Skip to main content

DVD authoring for domestic use on a Linux box

Posted in

Do you know what's funny about the movie "Plan 9 from outer space"? It's so bad that you wouldn't want to pay money for it and therefore nobody would try to sell it to you anymore. Yet, you just have to see it. Good news is, the movie is, like many others of that era, in the public domain now. Bad news are that you need to download it and are likely to end up with something that will play fine on your PC, but not necessarily on a DVD player.

So, whats the problem with just putting an AVI file on a DVD? Well, actually none, except, of course, that a standard DVD player would not necessarily know how to handle it and even if it did, you would not get things like chapters this way.
A standards conform DVD medium must meet a number of requirements in order to be playable:

  • The movie has to be encoded as a raw MPEG-1 or MPEG-2 stream.
  • The resolution and the frame rate of the movie must be compatible with what a TV set can understand. TV's will either understand the PAL or the NTSC format.
  • The DVD must provide a special filesystemstructure so the players knows where find chapters, etc.

To author DVDs, some tools are needed. The GUI tools, I tried so far, did not really do a convincing job, so commandline it is (the name in parenthesis is the name of the Debian package, the tool belongs to):

  • mplayer and mencoder (mplayer): Transcode movie
  • dvdauthor (dvdauthor): Create DVD filesystem structure
  • growisofs (dvd+rw-tools): Burn DVD

Transcoding the movie

First thing when authoring a DVD is to find out what your TV set supports and how to transcode a movie for it (if needed). PAL TV sets, for example, support resolutions of 720x576, 704x576, 352x576, or 352x288 pixels at a framerate of 25 frames per second. Bear in mind that PAL and NTSC are age old and quirky standards which had to be made downwards compatible with their black and white predecessors. For that reason, TVs are not even nearly as flexible as computers are and videos that do meet their demands have to be transcoded first.

Transcoding a movie already allows for making several choices. Do you want an aspect ratio of 16:9 (cinema scope)? Then choose 720x576 (PAL) as the resolution. For an aspect ratio of 4:3 (regular TV), pick either 704x576 or 352x288. The later one giving poor video quality, but allowing for putting more video material on a single disc. Naturally, when transcoding, you should try to pick a resolution that comes close to the resolution and aspect ratio of the original movie stream (use mplayer or the file command to get this information).
In case you need to bring the resolution up, you have the options to either scale or expand the stream while transcoding. Scaling allows for making the movie fit the screen size at the cost of reduced image quality and increased storage size. Expanding just puts a black border of sufficient size around the movie. Image quality stays as is and disc space consumption is only slightly increases as areas of solid color compress well.
Usually it is preferable to scale instead of expand in order to be able to watch the movie without a magnifying glass.

Here is an example to recode an NTSC compatible AVI to a PAL compatible MPEG:

mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf \
-vf scale=720:576,harddup -srate 48000 -af lavcresample=48000 \
-lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:\
keyint=15:vstrict=0:acodec=ac3:abitrate=192:aspect=16/9 -ofps 25 \
-o movie.mpg movie.avi

Notice the -ofps 25 parameter which tells mencoder to make sure to maintain a framerate of 25 frames per second. NTSC has a framerate of ~30fps, so some frames will simply be thrown away as the TV could not display them anyway. This is not a big loss. The other way round, from PAL to NTSC, is more difficult as frames need either to be repeated or interpolated, resulting in visual lag.

Doing the math: size matters

Not all AVI files come in TV friendly resolutions. This is especially bad when their aspect ratio neither matches 4:3 nor 16:9 (width divided by height is neither 1.333 nor 1.777). Scaling such videos to screensize inevitably results in a distorted image, while resizing would add ugly black borders on all four sides.
The best solution in these cases is a compromise between scaling and resizing. That is, first scale the video until it matches the screensize horizontally and afterwards resize it vertically. This will add a black border to the top and the bottom but otherwise leaves the aspect ratio as is.

For example, assuming your video has a size of 544x400 and you want to view it on a PAL TV set. In that case, pick the next larger resolution, which would be 704x576. Divide the screenwidth by the video's width to get the scaling factor: 704/544 = 1.294. Now multiply the video's height by the scaling factor and round up: 400 * 1.294 = 518.
You now know that you have to first scale to 704x518 and afterwards resize to 704x576, adding a slim black border of 29 pixels to the top and the bottom.

If you find that confusing, here's a short bc function definition that will do the calculation. Simply start bc with the -l option, then copy and paste the script and call the resize function with x1=original_width, y1=original_height, x2=target_width, and y2=target_height, e.g.:

  $ bc -l
  bc 1.06.94
  Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
  This is free software with ABSOLUTELY NO WARRANTY.
  For details type `warranty'. 


  define resize(x1,y1,x2,y2) {print "scale=",x2,":", (x2/x1)*y1,",expand=",x2,":",y2,"\n"}
  resize(544,400,704,576)
  scale=704:517.64705882352941176400,expand=704:576
  0

Ignore the trailing 0 and round the second scaling factor appropriately (518 in this case).

Taking the mencoder command from above, modify it like this (note the change in the second row):

mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf \
-vf scale=704:518,expand=704:576,harddup -srate 48000 -af lavcresample=48000 \
-lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:\
keyint=15:vstrict=0:acodec=ac3:abitrate=192:aspect=16/9 -ofps 25 \
-o movie.mpg movie.avi

Preparing the filesystem

After the video has been transcoded to a raw MPEG-2 stream of the desired resolution, the real work starts. DVD uses either UDF or ISO9660 as a filesystem, but you cannot just dump an arbitrarily named file on it and hope for the player to find it. DVD players expect a very specific filesystem structure on their media. Preparing this structure is not too difficult. The dvdauthor program does most of the work for you. You have to tell it your ideas on menus and chapters, though.

Chapters are pretty much arbitrary bookmarks in the movie, basically, time indexes, that can be navigated, using the next/previous button on your remote. To find out, where you want to place such a bookmark, view your movie using mplayer. Hit the "o" key to bring up the OSD and write down the points in time you want your chapters to begin on.

Once you have done this, create a directory in which to build the DVD image:

mkdir dvd-image
dvdauthor -t -o dvd-image -c 00:02:50,00:12:00,00:24:00,00:43:00 movie.mpg
dvdauthor -T -o dvd-image/

Note, that you have to invoke dvdauthor twice here. The first time just puts the VOBs (Video OBject) into the dvd-image directory, the second will build a table of contents. Without this table of contents, the DVD player would not be able to make sense of the DVD.
The result of the example commands above will create a very basic DVD image in the dvd-image directory that will not have a menu and starts to play right away. It has four chapters, beginning at 2:50, 12:00, 24:00, and 43:00.

Burning the DVD

Finally burning the image on an actual disc is fortunately trivial:

growisofs -Z /dev/dvdrw -dvd-video -speed=8 dvd-image -overburn

Here you probably only have to adjust your drive parameters. Note, that growisofs will refuse to burn the image in case you forgot to put a table of contents on it.

Advanced usage: Adding more than one stream to a title

Eventually, you might want to put more than a single stream on one disc. To add more than one MPEG to a single title, use dvdauthor like this:

dvdauthor -t -o dvd-image -c 00:20:00,00:40,00 1.mpg -c 00:10:00 2.mpg 
dvdauthor -T -o dvd-image/

This will put two streams into the same title and add chapters at minute 20, 40 and 50. Note, that the second title is placed directly after the first, so it's chapter points are treated as being relative to the previous stream. Also note, that this kind of usage requires both streams to have the same resolution.

Advanced usage: Adding more than one stream to a disc

Adding several streams to the same title has the disadvantage of them all having to have the same resolution. This can be worked around by putting different streams in different tracks:

 dvdauthor -t -o dvd-image -c 00:20:00,00:40,00 1.mpg
 dvdauthor -t -o dvd-image -c 00:20:00,00:40,00 2.mpg
 dvdauthor -T -o dvd-image/

Dvdauthor will automatically create a new track, when invoked a second time for the same output directory. The drawback of this is that a DVD player will now autostart playing the first stream and quit after finishing it. The second stream is not played at all. You have to use the "PBC" (play by chapter) button to manually navigate to it. You will not automatically get a title menu this way.