The aim of this tutorial is to teach you how to use myDVDEdit for modifying DVDs. You will learn about the general structure of a DVD, how to modify buttons, how to add commands, as well as how to add a new VTS to an already existing DVD.
Also in this tutorial, I'll show you how to add an access code to a DVD so as to stop other people from being able to watch it. Of course, it's pointless to suppose that a DVD can be completely protected, because there is plenty of software capable of reading VOB files, such as Quicktime and myDVDEdit of course, however, being able to limit access to ordinary DVD players isn't a bad start.
In order to show you how to do this, I've created a menu to represent the access keypad, as well as a title signalling whether or not access is authorised. So you will see below, two DVDs (one in PAL and the other in NTSC, depending on which one you want to use) containing this menu and title.
I won't show you here how I managed to create these DVDs, that is not the aim for this tutorial, although I can tell you that I used Photoshop to design the images and the superimposed menu (which will become buttons), and DVD Studio Pro to unite everything in the shape of a DVD. Then I suppressed all the commands and superfluous PGCs to obtain what you see.
Well, it may not look like much at first glance, but let's examine this DVD more closely.
Let's start at the beginning.
If you select First Play in the domain selector (which is what I call the table in the top left), you will see that it contains the command Jump VMG Menu title. This is an industry standard. First Play is the first PGC to be executed, when you start a DVD, and it usually contains the initialisation of the registers. When this PGC ends, there is usually one of two possibilities: either the DVD immediately displays a menu using the Jump Menu command, or it displays a title and so uses the Jump Title command
Note: If you don't already know about Jump commands, I would suggest that you read the Navigation Commands documentation.
VMG Menu title
In the VMG Menu domain, there is a PGC marked title. This must be present in order for a DVD to work properly. It is the PGC that is run when the user pushes the Title button on the remote control. This button can also be called Main Menu or Top Menu.
There is only one command here: Jump VTS Menu 1, Menu root. You simply jump to the root menu of the VTS Menu 1.
VTS Menu 1, Menu root
Let's continue the tour.
Have a look at the VTS Menu 1 domain. You should know by now (if you have read the myDVDEdit Overview tutorial) that a DVD is composed of VIDEO_TS files which make up the VMG, and also of many different kinds of files of the VTS_xx_n type, which make up the VTS, xx referring to their number. A VTS is composed of two domains: the menu domain (VTS Menu xx) and the title domain (VTS xx)
The VTS Menu must contain at least one PGC marked root. It is the PGC that runs when a DVD player executes a PGC in the VTS, and when the user pushes the Menu button on the remote control. root is termed an entry PGC.
In the VMG Menu there is only one possible entry PGC: title, whereas the VTS Menu has five possible entry PGCs. Each entry PGC corresponds to a button on the remote control:
root, Menu button.
subpicture, Subtitle Menu button.
audio, Audio Menu button.
angle, Angle Menu button.
chapter, Chapter Menu button.
Other than the Menu button, it is rare to find the other buttons on traditional DVD players (do not confuse the Subtitle Menu button with the Subtitles button which is always present. The same applies for Audio and Angle).
These entry PGCs allow there to be specific menus to change subtitles, audio track, or the choice of a particular chapter. Their presence is not essential
Let's return to our project.
Here, Pgc 1 is our root entry PGC and contains a Cell . Its duration is 00:00:00 12 / 30 if you've opened the NTSC project, and 00:00:00 10 / 25 if you've opened the PAL project. This means that the film is 12 images long at a frame rate of 30 images per second if you are in NTSC, or 10 images with 25 images per second in PAL. After playing this video, which is considered short, a DVD player normally executes the post commands, but in this example, the Cell is showing still infinite . The DVD player will therefore remain indefinitely on this image until the user pushes a button on the remote control. This is a typical fixed menu.
And talking of buttons, there are 12 of them . You can observe these better by clicking on the frames and numbers options . You will see that I have made the buttons 1 to 9 correspond with the 1 to 9 keys on my access keypad, like that the 1 key will be activated by clicking on button 1 of the remote control, key 2 on button 2, etc.
This menu was designed to work equally well in 16:9 as in 4:3. In 4:3 mode, display is pan&scan, which is usual for a menu. The group selector allows the buttons to display according to the display mode. You'll notice that the buttons don't have the same position, nor the same size, depending on the group selected. This is fairly logical since the displayed image is different depending on the mode.
What is true for the buttons also applies to the subpictures that are responsible for representing the selected or activated button. By clicking on the Information tab, in the Subpicture part, you will see two specified streams, one for 16:9, and the other for pan&scan. Although for subtitles, the streams can sometimes be the same, this is almost never the case for menus since subpictures have to be superimposed in the right place on the image.
And now we get to what interests us the most in this tutorial: the command for button .
For now this is configured to Nop, which is short for No Operations.
Note: I've noticed that certain DVD players don't like the Nop command in a button. I would therefore advise you to change it to a command like R0 = R0. This won't make too much of a difference, I'm sure you'll agree.
VTS 1 - Pgc 1
To finish our little tour around the structure of a DVD, you will see in Pgc 1 of VTS 1, a Cell of 1/2 seconds. This may seem a very short time to display an image, but don't forget that a DVD player can take from 0.5 to 1.5 seconds extra to display the next image (the time taken to restart its decoder). So the image will display on screen from between 1 to 2 seconds. If you still think this is too short, you can always add a 1 second pause in the Cell parameters.
Let's prepare the ground
In order to use my access keypad, I am going to have to use two registers: one to memorise the code input by the user, and the other to indicate whether the code is valid or not. For these, I'm going to use R14 and R15. As a general rule, I reserve the lower registers (R0. R1 etc.) for current and temporary operations, and the higher registers (R15, R14 etc.) for permanent information that has to be retained throughout the playing of the DVD. Here, one should also take into consideration the fact that this project will be integrated into an already existing project, and therefore one mustn't use registers already in use in that project. Be aware that for instance, DVD Studio Pro already uses R0 to R7 registers.
To make use of the functionality of myDVDEdit from version 1.0, I'm going to rename the R15 register as passCode. This will have two advantages, firstly, I won't need to remember what is the number of the register anymore, and secondly I will no longer run the risk of re-using one by mistake in the rest of the project.
Select the File / Project Properties menu, then click on the Registers icon. In the Name column, double click on R15 and enter the name passCode. So there you go, your register has now been renamed.
A second modification: we will temporarily change the display to hexadecimal. Now, I know that some of you are going to panic here, but don't be scared, you'll see it's very simple.
Select the myDVDEdit / Preferences menu, then click on the Commands icon. In the Numerical Values section select hexa.
But why go into hexadecimal? Simply because in decimal I can only access 10 digits per unit (from 1 to 9). But there are 12 keys. By going into hexadecimal, I'll be able to code up to 16 digits per unit (from 1 to 9, then A, B, C, D, E and F). In one case you are in base 10, in the other in base 16.
To make myself better understood, let's consider an example, I want the combination for my access keypad to be 1234. If I want this to be in a base 10 register, no problem, I write R0 = 1234. But if I now want my combination to be 53A8, in base 10 I'll find that rather difficult. However, if instead I use base 16, I'll have no problems since I have 16 digits per unit at my disposal. I merely need to write R0 = 0x53A8. The 0x is used to make it clear to the editor that this is a hexadecimal number. Or you could instead use the $ character. R0 = $53A8.
Now if your display is in decimal, you will see the command appear as R0 = 21416, since in decimal, this is the value of 0x53A8. Not very clear! Well, that's why we only go temporarily into hexadecimal display.
Note: By default, values greater than 255 are automatically displayed in hexadecimal, but in this tutorial I will also need to manipulate smaller numbers.
I'll now give you a very quick course on binary operations, hexadecimal and logic operations which will be useful later in this tutorial. If you already know all about them, go to the next chapter.
A DVD player, like a computer or anything else that works using a microprocessor, functions in binary. This means that it only recognises two possible values, 0 and 1. In order to represent this value we use the term bit.
Thus for every bit, only two values are possible, 0 or 1. If 2 bits are used there are 4 possible combinations of the bits. 00 01 10 11. Using 3 bits, 8 combinations are possible: 000, 001, 010, 011, 100, 101, 110, 111. Every time a bit is added, this multiplies by two the number of possible combinations. This simple observation permits us to define the combination number as being, two to the power of the number of bits, or 2n.
Note: This rule is true no matter which base is used. In base 10, or decimal, the base we use everyday, for n digits we therefore write 10n numbers (don't forget the 0). In base 16, or hexadecimal, for n digits we write 16n numbers.
Reading binary numbers containing lots of bits, isn't easy. To simplify this a little, we regroup the numbers into fours. With 4 bits, 16 combinations are possible. So there you go! Once again we have the hexadecimal values. This gives us the following conversion table:
If you look at the following 16 bits: 1001101001000111
By regrouping them into fours, you get: 1001 1010 0100 0111
Then by using the hexadecimal number corresponding to each group, you get: 9A47
Which is much easier to read than the 16 bits we started with.
In order to avoid confusing decimal and hexadecimal numbers, we will use the syntax from C programming language by adding 0x in front of all hexadecimal numbers.
This number is therefore written 0x9A47
Binary AND Operations
AND logic is a very simple operation between two bits. It consists of stating that the result equals 1 if both bits are 1s, but equals 0 in the opposite case.
We express this as x = a & b. (x equals 1 if both a AND b are 1s).
This can also be represented in the form of a table showing all the possible values:
When you carry out an AND between two 16 bit numbers, you are carrying out an AND between each bit in the same position in the two numbers.
Now watch what happens when we use the digits 0 and F in an AND operation between two hexadecimal numerals.
For example take the number 0x9A47, let's carry out an AND operation with 0x0FFF and see what happens.
0x9A47 is written 1001 1010 0100 0111 in binary.
0x0FFF is written 0000 1111 1111 1111 in binary.
An AND between the two gives 0000 1010 0100 0111
Thus in hexadecimal it is 0x0A47.
You can see that the AND operation allows us to delete the first numbers that do not concern us, while retaining all the rest. This is a very common operation in IT
Binary OR Operations
OR logic is just as simple. The result equals one if the first or the second bit are 1, and 0 if the opposite is true.
This is written as: x = a | b. (x is 1 if a OR b is 1).
This too can be represented in the form of a table with all the possible values:
When you carry out an OR between two 16 bit numbers, you are carrying out an OR between each bit in the same position in the two numbers.
For exemple 0x45A2 | 0x1938 = ?
0x45A2 is written 0100 0101 1010 0010
0x1938 is written 0001 1001 0011 1000
An OR gives 0101 1101 1011 1010
which in hexadecimal is written: 0x5DBA
Another classic IT operation is a Bit Shift, in other words, the displacement of bits in a number to either the left or the right. Unfortunately this operation doesn't exist in DVD commands. To get over this problem we'll use another operation: multiplication.
In the same way that when you multiply a decimal number by 10, you shift all the numbers and add a 0, when you multiply binary numbers by 2, you shift all the bits and add one that is a bit at 0. If you multiply this same number four times in a row by 2, thus multiplying it by 16, you add four 0 bits to this number. And four 0 bits, gives the hexadecimal number 0.
0x0A2B * 16 = 0xA2B0
OK, enough theory, now let's put it into practice.
Let's add some Pre-Commands to our menu.
We want to modify the R15 register, sorry I mean passCode, and the R14 register so as to give them an initial value.
The commands are:
passCode = 0x53A8
R14 = 0
If later on you want to modify the access code to your DVD, you will merely have to modify the initial value in passCode.
Select VTS Menu 1 - PGC 1 then select the Pre-Cmds tab.
Add a new command. There are three ways to do this, it's up to you which one you prefer:
- by clicking on the + button located under the command editor.
- by making a right click on your mouse (or ctrl click) on the command editor, then on the Add Command menu.
- by pressing the + key on your keyboard (Command Editor must be selected)
Now modify the new command by clicking on the triangle.
Type : Set Register
Register : passCode = Direct 0x53A8
Do the same operation with the command
R14 = 0.
Later on we'll see what R14 is used for.
Now let's modify the button commands. The aim is to make a button correspond to the numerical value of a key on the access keypad. There are different ways of doing this, my favourite is to modify the content of a register directly in the button.
Select VTS Menu 1 - Pgc 1 then select the Buttons tab. Now click on the Edit button.
Let's begin with button 1
Click on the little triangle to the left of the command.
Then enter the command:
type : Set register
Register : R0 = direct 1
Highlighted Button: None
Now go to button 2 and do the same thing by entering value 2.
For button 10, the value will be 0 (since it is key 0 on the access keypad).
For button 11 enter the value 0xA.
For button 12 enter the value 0xB.
This command modifies the content of the R0 register by giving it the value of the corresponding key on the access keypad. Then it executes a Link TailPgc, which makes the DVD player execute the Post-commands.
Click on the OK button to save all these changes.
This is where you program in the mechanism for verification of the code. To do this, only 5 commands are needed:
1 - R14 &= 0x0FFF
2 - R14 *= 0x0010
3 - R14 |= R0
4 - if(R14 != passCode) Link Cell 1
5 - Jump VTSTitle 1
R14 &= 0x0FFF
Type : Set Registrer, Register R14 &= Direct 0x0FFF
This command is equivalent to R14 = R14 & 0x0FFF
This one gave me a bit of a headache. Theoretically it's not necessary, but a bug in DVD Player means that the registers are not processed in 16 bits as would be the case in a real DVD player, but in 32 bits. If you multiply the value 0x1234 by 16, if the register has 16 bits, that should give 0x2340, but with DVD Player, it gives 0x12340.
To cure the problem, this command erases the digit on the left in the R14 register by performing a binary AND operation.
R14 *= 0x0010
Type : Set Register, Register R14 *= Direct 0x10
This command is equivalent to R14 = R14 * 0x0010
I made a left shift on my hexadecimal number by multiplying it by 16 (yes, 16, which is written 0x0010 in hexadecimal).
R14 |= R0
Type : Set Register, Register R14 |= R0
This command is equivalent to R14 = R14 | R0
After the shift, the last digit is replaced by the content of the R0 thanks to OR logic. I could just as easily have used addition since the last digit of R14 is always a 0 and R0 is a number with only one digit. Professional conditioning I suppose!
if(R14 != passCode) link Cell 1
Type : Link, if checked, R14 != passCode, LinkCell, Cell: 1
Here, I am testing whether the R14 register is different from the passCode register. If this is the case, the DVD player will connect to Cell 1, if not the player will execute the next instruction
Contrary to Link Pgc 1, the Link Cell 1 command avoids the execution of Pre-commands.
Jump VTSTitle 1
Type : Jump/Call, Jump VTSTitle, VTSTitle: 1
Title 1 is displayed.
Prohibited User Options
When the access keypad is displayed, so that the user cannot gain access to the DVD by an indirect method, it is important to prevent him from using the various buttons on his remote control. The Title button for instance, could allow him to go directly to a title without having to input the access code.
To stop this, we will modify the Prohibited User Options.
Select the VTS Menu 1 domain, then the PGC 1 / Prohibited User Options tab.
The checked boxes correspond with actions that are prohibited to the user. These options can be changed either at the PGC level (thus in the IFO file), or at the Cell level (therefore in the VOB files).
In order to forbid all actions to the user, select all the PGC options except for:
- Stop, (we are hardly going to forbid the user from stopping the DVD).
- Select/Activate, which allows one to select and activate buttons. Without this the buttons would no longer work.
How about a little test?
Slide the selector into Debug mode(or R). You need to be positioned on First Play/Pre-commands, the command being a Jump VMG Menu title. Click on the Continue button (G) to execute the commands continuously. The debugger will stop on the image of the access keypad.
Select the Registers tab, then, execute lots of buttons.
There are a number of possibilities to activate a button:
- Double click on the desired button.
- On the keyboard, select your button using the arrows keys then press the Return key.
- Using the mouse, select your button by clicking on the arrows on the remote control, then click Enter.
On each execution, you'll see that R0 will take on the value of the selected button, the value of R14 will be shifted to the left and the number of its units will take the value of the button.
If you execute consecutively the keys 5, 3, A and 8, R14 will take on the value 0x53A8 and will be identical to register 15: passCode. The player will then display the text 'Granted'. If you execute the Continue menu (G), the debugger will continue and loop back to the menu.
Our code is working correctly.
Integration into another DVD project
Now we will integrate our access keypad into an already existing DVD project.
You can close the current project.
I suggest you download the DVD project below, called Countdown. It's a small simple project containing just one menu and an animation that executes when the user clicks on the OK button.
In passing, you'll notice how a very common mechanism used in DVDs, the loop point, is managed.
In First Play, the R7 register is initialised to 0. then in VTS Menu 1, R7 is tested, if it equals 0, it goes on to 1 and Cell 1 is displayed, if not Cell 2 is displayed.
At the end of Cell 2, the Command Cell Link TopCell causes the return to the start of Cell 2, and this until the user presses the Enter button on his remote control.
Cell 1 which introduces the menu, contains no buttons and will be played only once. The first object of Cell 2 is our loop point.
Project Countdown is merely given here to serve as an example. You can of course use a different one project.
In order to import our access keypad into the project, execute the menu File/Import VTS. A dialog box will open inviting you to select a file to import. Look through the hard drive until you find the VIDEO_TS folder in the AccessKeypadPAL folder (or in the AccessKeypadNTSC folder if your project is in NTSC), select VTS_01_0.IFO then click on Choose.
The files are copied and the domains VTS Menu 2 and VTS 2 appear in the project.
Rename the register R15, as explained previously to accessCode. This isn't compulsory (but I like it!)
In First Play, replace the Jump VMG Menu Title command with Jump VTS Menu 2, Menu Root. If you are using a different starting project, replace '2' with the correct number of the imported VTS.