VCD and SVCD Creation

DV to SVCD

Producing the VCD image which can be burned on to CD-R is a multistep process. There are many ways to do each step. This is what I (successfully) did.

From the camera to disk

The data from the camera can be downloaded using the dvgrab utility. It can transfer all the data in one file or split the output at the endof scenes (I.e., when the camera was stopped). The files can later be concatenated again so this is not a big problem.

The dvgrab tool can output three formats:

The later is usually not necessary unless you want to write a tool which handles this format. Type 1 files are usually smaller but the format is not understood by all programs which can handle DV AVI files. Type 2 files seem to be safer.

The command line can look like this:

dvgrab --format dv2 aviout

If you have multiple firewire cards or want only a limited number of input additional parameters might be needed.

The video output format of an NTSC camera is 720x480 pixels in Sony Digital Video (DV) format at 29.97 frames per second. The audio output is in uncompressed PCM format with 48kHz, 2 channels, and 16 bit data. Be warned: the resulting files total at about 18GB per hour.

Transcoding

The NTSC SVCD format requires video at 480x480 pixels at 29.97 frames per second or 480x576 pixels at 25 frames per second. The former being NTSC, the latter PAL. My DVD can play both and it might be possible to mix the formats on the SVCD. I never tried it, though. The encoding is MPEG-2. The audio part has to be encoded using MPEG-1, layer 2. Unlike normal VCDs, SVCDs allow variable bitrate recording (VBR). Some very old DVD players don't understand the VBR encoding. To support them it might be necessary to encode using constant bitrate (but I haven't tried it so far).

The video and audio parts of the DV AVI files must be processed individually. It would be possible to explicitly split them and later merge them back together but there are nice tools available which do this for use. I'm using transcode. Using is really simple once it is decided what the input and output formats are. The documentation gives plenty of information. To transform the 720x480 NTSC DV AVI to 480x480 NTSC SVCD and producing MPEG-1 level 2 audio the following command can be used:

transcode -i aviout001.avi -V -y mpeg2enc,mp2enc -F4,"-M 2" -B 0,15,16 -E 44100 -b 128 -u 20,2 -o mpegout

The -i parameter specifies the input file (more on this in a second). The -V parameter selects that internally YV12/I420 is used as the internal intermediate format. -y selects the output formats (plural: for video and audio). mpeg2enc is the above mentioned MPEG-2 format and mp2enc is the MEPG-1 level 2 VBR encoding.

The following -F parameter provides options to the encoder module. In this case the 4 means SVCD format is wanted. The rest of the parameter, following the comma, is passed verbatim to the encoder module. For the mpeg2enc module this selects to use of two worker threads which will use both processors in my machine.

Since the input format is 33% larger than we need it we have to resize the image. This is done using the -B option. The value 0,15,16 means the height is reduced by 0 * 16 = 0 pixels and the width is reduced by 15 * 16 = 240 pixels. This is exactly the reduction needed. It would also be possible to specify the reduction using transcode's -r option but this is slower.

The -E and -b option specifies the audio output samplerate as 44.1kb per second and per channel at 128kb/s encoding rate..

The final -u parameter is used to direct internal memory allocate to be better suitable for a multi-threaded encoder. The defaults are useful as well.

This process can be applied to individual DV AVI files (possibly as cut by dvgrab). This is a bit problematic if they later should be viewed in one piece without interruption. If the files are not merged at some point the SVCD/DVD player will briefly stop to search for the new scene. This is most of the time undesirable.

Instead I usually merge the DV AVI files before transcoding them. As far as I know merging them later isn't possible anymore. To merge the files I create an empty directory and move all the files I want to have in one scene into it. Once this is done transcode does not get passed the names of individual files with the -i option but instead the directory name. It will then automatically use the tzcat tools to concatenate the DV AVI files.

The transcoding process will take a while. Even on fast machines. Many processors will help but transcode has so far no support for rendering farms but on SMP machines all processors can be used. Still, even on the fastest machines transcoding 60 minutes will take several hours (at the time you read this it might be outdated info...).

The output of the program run consists of two files. The video data is stored in mpegout.m2v and the audio in mpegout.mpa. The stem of the output file name was given as the parameter for the -o option.

Multiplexing

Before generating the SVCD image video and audio must be merged. This is best done using the mplex tool. The options I used are:

mplex -f 4 -S 680 -o result.mpg mpegout.m2v mpegout.mpa

The -f option select output format 4 which is SVCD. -S specifies the maximum output file size so that we do not exceed the limits of the SVCD storage capacity. Often more than one file is stored on the SVCD so this option is not useful in this form.

Generating the SVCD image

The SVCD does not contain the raw data of an MPEG file but it is instead structured and has a filesystem. This must be created just like a normal CDROM filesystem. The program to use for this is vcdimager.

There are two ways how vcdimager can be used: it can directly create the image file which can be burned to CDROM or first an XML description of the output file is created. This XML file can be edited, extended, changed, and then the final image can be created. Which way to use depends on the desired results. If you want title screens and complex navigation you will have to generate the XML file and change it accordingly. The VCDimager manual explains the DTD in detail.

After a number if trials I found out that my DVD requires a slightly non-standard SVCD format to be happy. Therefore I need some options beside those usually used. By default only the output format must be selected and the input files provided:

vcdimager -t svcd --broken-svcd-mode --add-dir=/SEGMENT result.mpg

I had to add the --broken-svcd-mode option to add some non-standard extensions to the filesystem and I had to add the directory /SEGMENT. Don't ask why, I wouldn't know.

With these options the program produces the files videocd.bin and videocd.cue. Alternate names can be selected with parameter to vcdimager. The file can be written to disk using programs like cdrdao. Note that cdrdao will use the .cue file to guide the process. In my case, I use

cdrdao write --device 1,2,0 --speed 6 --eject videocd.cue

For the two-step process first the vcdxgen tool is used. It takes the same options as vcdimager. This will create by default the file videocd.xml. This file can then be edited. It's possible to add titles (using MPEG still images, see below), menu selections, subtitles, and much more. It's possible to create interactive SVCDs. Once I've played a bit more with this I'll write something up. So far I've only added menus. This is an example for a SVCD XML description I actually used:

<?xml version="1.0"?>
<!DOCTYPE videocd PUBLIC "-//GNU//DTD VideoCD//EN" "http://www.gnu.org/software/vcdimager/videocd.dtd">
<!-- commandline used: vcdxgen -t svcd -=broken-svcd-mode -=add-dir=/SEGMENT -=update-scan-offsets -=volume-count=2 -=volume-number=0 -=iso-volume-label=GANG_GREEN_2002_11_10 1st.mpg 2nd.mpg -->
<videocd xmlns="http://www.gnu.org/software/vcdimager/1.0/" class="svcd" version="1.0">
  <option name="update scan offsets" value="true"/>
  <option name="svcd vcd30 mpegav" value="true"/>
  <option name="svcd vcd30 entrysvd" value="true"/>
  <info>
    <album-id></album-id>
    <volume-count>2</volume-count>
    <volume-number>0</volume-number>
    <restriction>0</restriction>
  </info>
  <pvd>
    <volume-id>GANG_GREEN_2002_11_10</volume-id>
    <system-id>CD-RTOS CD-BRIDGE</system-id>
    <application-id></application-id>
    <preparer-id/>
    <publisher-id/>
  </pvd>
  <segment-items>
   <segment-item src="title2.mpg" id="segment-menu"/>
  </segment-items>
  <sequence-items>
    <sequence-item src="1st.mpg" id="sequence-00"/>
    <sequence-item src="2nd.mpg" id="sequence-01"/>
  </sequence-items>
  <pbc>
    <selection id="menu">
      <bsn>1</bsn>
      <default ref="lid-000"/>
      <timeout ref="lid-000"/>
      <wait>60</wait>
      <loop jump-timing="immediate">1</loop>
      <play-item ref="segment-menu"/>
      <select ref="lid-000"/>
      <select ref="lid-001"/>
    </selection>
    <playlist id="lid-000">
      <prev ref="menu"/>
      <next ref="lid-001"/>
      <return ref="lid-end"/>
      <wait>5</wait>
      <autowait>0</autowait>
      <play-item ref="sequence-00"/>
    </playlist>
    <playlist id="lid-001">
      <prev ref="lid-000"/>
      <next ref="menu"/>
      <return ref="menu"/>
      <wait>5</wait>
      <autowait>0</autowait>
      <play-item ref="sequence-01"/>
    </playlist>
    <endlist id="lid-end" rejected="true">
      <next-volume>1</next-volume>
    </endlist>
  </pbc>
</videocd>

Certainly not perfect (e.g., I think the <endlist> definition can go) but it worked. The file also shows how the volume name is set. The generated menu will allow selecting 1 or 2, referring to one of the two MPEG files on the disk. Together with timeouts and default values this is quite nice and easy to use.

Once the XML description is finished one only has to run the vcdxbuild tool:

vcdxbuild videocd.xml

This will again create the files videocd.bin and videocd.cue. The names can be changed with some additional parameters.

Before burning the CD it might be useful to verify the disk. First, the vcddebug tool can be used. The output is verbose but I think errors will be easily visible. Second, programs like mplayer can directly read Video CDs.

SVCD Still Images

Still images can be used for menus. To get such an still image create a picture. The only requirement is to be able to convert it to PPM. The aspect ratio should match that of the screen (normally 4:3 for NTSC). Once the picture exists execute the following commands to get a still image for NTSC (here the input file is in PNG format). The programs used are all found in the NetPBM tools and MJPEG tools packages.

pngtopnm test.png |
pnmscale --width 480 --height 480 |
ppmntsc |
ppmtoy4m -v 0 -F 30000:1001 -S 420_mpeg2 |
mpeg2enc -v 0 -f 7 -a 2 -n n -T 110 -o test.m2v

For a higher resolution NTSC still image use this:

pngtopnm test.png |
pnmscale --width 704 --height 480 |
ppmntsc |
ppmtoy4m -v 0 -F 30000:1001 -S 420_mpeg2 |
mpeg2enc -v 0 -f 7 -a 2 -n n -T 120 -o test.m2v

For PAL output the commands should be like this (untested):

pngtopnm test.png |
pnmscale --width 480 --height 576 |
ppmntsc --pal |
ppmtoy4m -v 0 -F 25:1 -S 420_mpeg2 |
mpeg2enc -v 0 -f 7 -a 2 -n p -T 110 -o test.m2v

and

pngtopnm test.png |
pnmscale --width 704 --height 576 |
ppmntsc --pal |
ppmtoy4m -v 0 -F 25:1 -S 420_mpeg2 |
mpeg2enc -v 0 -f 7 -a 2 -n p -T 120 -o test.m2v

The value for the -a parameter of the mpeg2enc command has to be adjusted for the aspect ratio of the output. The following values are defined:

Value Ratio
1 1:1
2 4:3
3 16:9
4 2.21:1

These video frames can then be added to a final MPEG file:

mplex test.m2v -o test.m2p

Ulrich Drepper
Last modified: Tue Aug 12 22:50:20 PDT 2003