DVD compliant mpeg2 on Linux

Either mjpegtools or the ffmpeg encoder can be used for creating the mpeg2 program streams needed for authoring DVDs on Linux. Our focus is encoding widescreen NTSC interlaced video source from a miniDV camcorder. We attempt to preserve as much of the quality of the original source as possible.

Needed Software

You need at least one on the following open source software projects to encode mpeg2 video on Linux.

An Encoding Script

I have written a script called encode-dvd that will create suitable mpeg2 files. Since other people's scripts are often difficult to use here are some explicit examples of encoding the file s001.avi using ffmpeg, mencoder and mjpegtools.

Ffmpeg

The ffmpeg encoder is faster on my computer than the mjpegtools tools encoder. The patch ffmpeg-2.3.2-interlace.patch or ffmpeg-1.2.1-interlace.patch adds an option that allows forcing the interlacing mode of an input file and is relative to the 1.2.1 Magic version of ffmpeg released May 10, 2013. An older version of this patch patch-ffmpeg-1.0.1-interlace is relative to the 1.0.1 Angel version of ffmpeg released December 8, 2012. Specifically -interlace 1 forces ffmpeg to interpret the input as interlaced and -interlace 0 forces ffmpeg to interpret the input file as progressive regardless of how the original input file may have been encoded or flagged. This flag can be useful when using ffmpeg with interlaced video. On Xubuntu 12.04 I was able to compile ffmpeg with
$ ./configure --prefix=/usr/local/ffmpeg --enable-libxvid \
    --enable-libx264 --enable-libvpx --enable-libfaac \
    --enable-libmp3lame --enable-libtheora --enable-libtwolame \
    --enable-libvorbis --enable-gpl --enable-nonfree 
$ make
$ su
# make install
For the 0.5.4 version of ffmpeg here are some older versions of the same patch as well as a second patch that adapts the 4:1:1 to 4:2:0 color space conversion used by ffmpeg so it works with interlaced video. Apply these patches to ffmpeg-0.5. Then build it with
$ export LD_RUN_PATH=/usr/local/lib:/usr/lib:/lib
$ ./configure --prefix=/usr/local --enable-gpl --disable-debug \
    --enable-liba52 --enable-liba52bin --enable-libxvid \
    --enable-libx264 --enable-libfaac --enable-libfaad \
    --enable-libfaadbin --enable-libmp3lame --enable-libamr-nb \
    --enable-libamr-wb --enable-nonfree
$ make
$ su
% make install
% exit
It is important to specify LD_RUN_PATH so that the new version of ffmpeg links to the new versions of libavcodec, libavformat and libavutil.

A typical command using the patched version of ffmpeg-0.5 to encode a DVD compliant program stream from DV source is

$ ffmpeg -i s001.avi -interlace 1 -ildct -ilme -top 0 \
    -target dvd -aspect 16:9 \
    -qmin 5 -b 7000000 -ab 224000 -y s001.mpg

As of Aug 2009 the imgconvert.c.patch no longer applies to development versions of ffmpeg because the conv411() function has been removed. It appears that the development code still exhibits chroma subsampling errors with interlaced material. This is confirmed by Kevin Murraya in Believed Incorrect Chroma Subsampling on Interlaced 4:2:2 to 4:2:0. One can use y4mscaler to work around the chroma subsampling errors.

$ ffmpeg -i s001.avi -y s001.wav
$ ffmpeg -i s001.avi -f yuv4mpegpipe -pix_fmt yuv411p -y /dev/stdout |
  y4mscaler -I ilace=BOTTOM_FIRST -O chromass=420mpeg2 |
  ffmpeg -f yuv4mpegpipe -i /dev/stdin -i s001.wav \
    -interlace 1 -top 0 -flags +ildct+ilme \
    -target dvd -aspect 16:9 \
    -qmin 5 -b 7000000 -ab 224000 -y s001.mpg
There is also a change in syntax for specifying the ildct and ilme options in the development versions of ffmpeg.

Mencoder

I have not recently used mencoder to encode DVD compliant mpeg2 streams. Since mencoder uses the mpeg2 encoder from ffmpeg the results should be similar in quality to what is obtained from ffmpeg directly. Here is an untested command for mencoder that should do the same thing as the previous ffmpeg example.
$ mencoder s001.avi -aoc lavc -ovc lavc \
    -lavcopts acodec=ac3:abitrate=224:vcodec=mpeg2video:\
ildct:ilme:top=0:vbitrate=7000:vqmin=5:vrc_maxrate=7500:\
vrc_buf_size=1835:aspect=16/9 \
    -vf harddup,dsize=16/9 \
    -of mpeg -mpegopts format=dvd:tsaf:vaspect=16/9 \
    -o s001.mpg
I have not checked whether mencoder correctly subsamples the chroma when converting interlaced DV source to interlaced mpeg2 video.

Mjpegtools

The mjpegtools encoder runs more slowly than ffmpeg on my computer; however, no patches are needed to handle interlaced video. The encoding commands
$ lav2yuv s001.avi |
    yuvcorrect -T INTERLACED_BOTTOM_FIRST |
    mpeg2enc -M0 -nn -a3 -f8 -G18 -b7000 -V230 -q9 -o s001.m2v
$ lav2wav s001.avi > s001.wav
$ toolame -b224 -s48 s001.wav s001.m2a
$ mplex -f8 s001.m2v s001.m2a -o s001.mpg
work, but unfortunately reduce the effective color space to 4:1:0. Better results can be obtained by using y4mscaler and the commands
$ lav2yuv s001.avi -C 411 |
    y4mscaler -I ilace=BOTTOM_FIRST -O chromass=420mpeg2 |
    mpeg2enc -M0 -nn -a3 -f8 -G18 -b7000 -V230 -q9 -o s001.m2v
$ lav2wav s001.avi > s001.wav
$ toolame -b224 -s48 s001.wav s001.m2a
$ mplex -f8 s001.m2v s001.m2a -o s001.mpg
This interpolates the chroma in the horizontal direction before subsampling it vertically.

Real Time Encoding

Using an 2.8Ghz AMD 64 X2 I can capture DV source through firewire and simultaneously encode it to 4000kbps DVD compliant widescreen video. A slow mpeg2 encoder with temporal noise filter and a high quality 411 to 420 colorspace scalar leaves each CPU idle about 20% of the time. A fast single-pass encoder without filtering leaves one CPU 100% idle and the other 60% idle. My tests were performed on Linux using open source software. Windows should yield similar results with reasonable DVD compliant mpeg2 recording software.

Note that for long format events it is important to use a DV capture device that supports locked audio instead of the digital pass through feature of a consumer class miniDV camera. An example of such a device would be the Canopus ADVC110 Analog/Digital Video Converter.

Fixed-GOP multi-pass encoding:

  load average:   0.86   0.80   0.46
  cpu0:   76% usr   4% sys  20% idle
  cpu1:   75% usr   5% sys  20% idle
  ram:  1002M us  2294M fr   637M bf
  swap:    0M us  7632M fr       0/s
  page:        0/s in      683/s out
  eth0:        0/s in        0/s out
   5983 123M  99.3% mpeg2enc  
   5982  11M  31.2% yuvdenoise
   5981   4M  17.0% y4mscaler
   5980  15M   9.0% ffmpeg
   5986 153M   2.1% dvgrab
   5984  13M   1.6% ffmpeg
   2315  40M   0.3% Xorg
   5987   1M   0.3% tee      
Single-pass real-time encoding:
 
  load average:   0.45   0.69   0.45     
  cpu0:   31% usr   1% sys  68% idle     
  cpu1:    0% usr   1% sys  99% idle     
  ram:   898M us  2398M fr   633M bf     
  swap:    0M us  7632M fr       0/s     
  page:        0/s in      413/s out     
  eth0:        0/s in        0/s out     
   6077  19M  30.5% ffmpeg               
   6079 153M   2.1% dvgrab               
   2315  40M   0.3% Xorg   
   5467   1M   0.2% lcwatch

Conclusions

There are a number of ways to encode DVD complaint mpeg2 program streams on Linux. The commands are relatively straight forward. The script encode-dvd makes specifying quality, aspect ratio and interlacing easier than typing all the options in by hand.

Color space subsampling errors for interlaced video are present in unpatched versions of ffmpeg and possibly mencoder. Avisynth does color space conversion correctly as detailed in Sampling. Note that color space upsampling errors of a similar nature are present in some DVD players as described in The 4:2:0 Interlaced Chroma Problem. Unfortunately, the two chroma errors don't cancel each other out.

As a final note, if you will be authoring a DVD consisting of more than one file in dvdauthor, do not mix mpeg2 files produced with ffmpeg and mjpegtools in the same video title. Stick with one encoding method for the entire project. Otherwise, the end result will be a DVD with two separate audio tracks: an ac3 audio track and a mp2 audio track in which each track is partially blank. Anyone watching such a DVD would have to manually switch between audio tracks while they watched in order to hear the sound.


Last Updated: Tue Aug 12 16:56:08 PDT 2014