Video Encoding

What you find here:

I have always been interested in video encoding techniques, and as a proud owner of an analog TV card with on-board MPEG2 encoding (ivtv-compatible), I now have lots of streams to play around with.. ;-)

(Of course, this whole page is solely concerned with open source software, since Linux is the only operating system I use.)

DVD Preparation

I found this quite difficult, mainly because the necessary information is scattered around the WWW and you need many small tools which come with separate packages. Let me give you a quick overview of the useful software:

tcextract (from the transcode package)
allows you to extract elementary streams from program streams. These are terms from the MPEG world, meaning that you can e.g. separate audio and subtitle streams from the video stream.
projectx
is a Java-based tool I was recently pointed to - its main feature AFAICS is that projectx -demux foo.mpg will not only demux a stream (like tcextract or mplayer -dump{audio,video} do), but will also synchronize the separate audio streams with the video according to the PTS (which is separated from the elementary streams and thus lost during normal demuxing). This saves you from manually finding the A/V offset, and also works if the A/V offset changes between different parts of the movie (which it commonly does).
mplex (from the mjpegtools)
allows you to (re-)multiplex elementary streams into program streams and allows you to specify profiles for e.g. DVD compatibility (i.e. -f 8).
dvdauthor
prepares the AUDIO_TS/VIDEO_TS structure of a video DVD according to an XML description, which can even contain descriptions of menus and everything. Its main use without a GUI is to prepare the directories to be burned for simply playing .vob files.
growisofs (dvd+rw-tools)
is used for burning to DVD. The name stems from the fact that this program was written for DVD+RWs (as a frontend to mkisofs), which allow to incrementally burn files as long as you're able to grow ISO filesystems, but nowadays, it's also happily burning all DVD media.
File: vobto47g(6122 bytes; Sun, Oct/05/2008) download 'vobto47g' to disk

A step-by-step explanation how to create a movie DVD using this software has been posted to the Gentoo forums. Unfortunately, it does not go into detail why some steps are necessary, and the author does not seem to be interested in the highest possible quality (i.e. he neglects the bad effects of multiple re-encodings for example). You might also want to have a look at my python script, which I successfully used to shrink DVDs under Linux in order to burn them to 4.7 GiB media.

Cutting Video

I am often encoding / recoding movies, mostly to MPEG4 (using the ffmpeg codec), which gives the best quality / disk space ratio. (However, the resulting files are not compatible with standalone DVD players in general.) I am editing videos for just one reason: in order to remove ads from TV recordings, and I found avidemux the most comfortable tool for doing so.

File: avidemux.py(7760 bytes; Mon, Feb/26/2007) download 'avidemux.py' to disk

Actually, avidemux is also capable of encoding the result in a variety of formats, but since I am very familiar with MEncoder already, which is the fastest encoding solution I know (giving best quality), I am using avidemux just for saving EDL files. Thus, I wrote a small python module (see download) which parses avidemux EDL and MPEG index files, and which I can use in my encoding frontend (see below) or standalone. (Note that this is not compatible with the upcoming Avidemux versions, but only with the stable 1.x series, since the format has changed really drastically. Alas, not even the new Avidemux itself can load its old formats.)

Mencoder GUI Frontend

Of course, it is possible to manually use mencoder after studying its manpage, but after a while, that was really a hassle for me and I started using a script. However, there are several parameters which you have to hand-tune for every movie, so you still end up running several test commands etc. Some day, I started writing a mencoder frontend, dreaming of a more or less complete thing at the beginning, but implementing only what I needed ATM.

File: mencode-gui-0.0.5.tar.gz(24.85 kb; Sun, Nov/05/2006) download 'mencode-gui-0.0.5.tar.gz' to disk

Right now, I want to offer what I have: A frontend which is usable for some things (mainly encoding anything to MPEG-4/DivX using the ffmpeg codec), but cannot do very much else. It is so incredibly useful to me (I use it constantly to encode videos from various sources), that it must be of at least some use for many people.

The GUI is far from fool-proof (of course, I am open for constructive suggestions or even patches), so let me sketch how to use it (BTW: it is Qt-based, so you need PyQt):

Loading files / determining the source

You can start mencode-gui without parameter to go into DVD mode. If you want to encode files from hard disk, you have to give the file names as parameters, e.g.:

# encode a single video file readable by MPlayer:
mencode-gui somefile.mov

# encode multiple video files, which are simply concatenated(!):
mencode-gui chapter1.vob chapter2.vob ... chapter13.vob

# encode an edited video from an Avidemux EDL file:
mencode-gui myrecording.edl

# encode multiple image files into one movie (cf. MPlayer manpage):
mencode-gui "mf://myanim00*png" # experimental!
Encoding

I tried to set all parameters to reasonable defaults. Usually, I just press "Encode" on the audio page to encode the audio (1st pass). Note that all encoding is done in the background and there is no command queueing (yet)! mencode-gui supports one to three passes (update: it now allows even more passes, if you want):

  • If you manually press "Encode" on the audio page, you will have an audio pre-pass (resulting in two-/three-pass encoding in total).

    The advantage is that mencode-gui can calculate the exact bitrate left for the video. As a rule of thumb, a movie of less than 1:30h will fit on a 700Mb CD in reasonably good quality. (Beyond that, YMMV.)

  • If you select "2-pass encoding" on the video page, two video passes will be used. The resulting movie of the first pass is sent to /dev/null, but a file with useful statistics for the second pass is created, leading to a much higher quality of the final movie. Both passes will use the same parameters for encoding the video (those that were active when you pressed "Encode"). The audio is not copied from the 1st pass output anymore (in 3-pass mode); that mode of operation has been deprecated by the MEncoder developers due to problems with A/V sync. (The time spent on audio encoding is negligible anyways, compared to video encoding, I/O, and [de]muxing.)

So, the usual process is:

  1. Start audio encoding (possibly checking the bitrate / selecting a channel first).
  2. Go to "Video Processing" page and
    • select de-interlacer (Linear Blend recommended) if the source is interlaced (e.g. from analog TV)
    • press "Preview Frame" whenever appropriate to check the output (encodes and displays a single frame at the configurable position)
    • change cropping/scaling parameters (and repeatedly preview the result)

Note

It is possible to have non-square pixels in the output, and the resulting files will have the aspect stored in a special tag as defined by the MPEG standard. Unfortunately, most players (all except MPlayer AFAIK :-() only look at the AVI header and do not respect the aspect. Thus, I usually scale the movie to a nearly-square aspect ratio as a tribute to these players (effectively making my movies more enjoyable for Windows people).

  1. As soon as the audio encoding is finished, calculate the bitrate:

    • Select a target size from the combo box or manually enter any desired filesize (in Mb) and press "Calc" (or enter) to calculate and fill in the exact bitrate.

    • Go back and change scaling/cropping parameters or change the bitrate according to the displayed bits per pixel rate.

      As a rule of thumb, I need at least 0.15 BPP to be happy with the resulting quality (but YMMV). When encoding from high quality sources (e.g. DVD), this may already look quite well. With noisy source material, you may need more (0.2 BPP should be safe in any case).

      These values are probably only valid for MPEG4 with B frames etc.; the more codec features you switch off, the higher the bitrate has to be for sufficient quality.

    • Try the SCE/masking parameters on low bitrates only. They lead to blocking artifacts, but many people report that they successfully encode at quite low bitrates with these (I don't like that though ;-p). IIRC, it was especially recommended for Anime movies.

    • OTOH, QPEL motion estimation is for high bitrates only. It significantly increases encoding time, and often you won't see a difference (note that this is an advanced feature and not supported by cheap encoders as those in some mobile devices or standalone players). Thus, I really seldomly use it at all.

  2. Press "Encode Video" and wait... ;-)

  3. Enjoy the final result! :-) (Or change parameters and encode again. mencode-gui will try not to overwrite files without asking - it will even allow you to re-start only the second video encoding pass - but there is no "stop encoding" button yet, you'll have to resort to kill..)

There are many hidden features of course, and some things I did not mention yet, but I am looking forward to your feedback! :-)

BTW: Recent versions of the ffmpeg codec (which is now hard-coded since I did not test/support other codecs anyways) movie set the FOURCC of the resulting file to "FMP4". Although it is possible to change fourcc codes (e.g. to "DX50" to indicate DivX 5.0 which is also an MPEG-4 codec), a better way is to play the files with either MPlayer or install ffdshow (which is a great thing to have anyways) under Windoze. ffmpeg delivers best quality at a low CPU cost.

Changes in 0.0.4:
  • introduce multi-pass mode (more than two passes) incl. "turbo"
  • fix long-standing bug with "slow" display (not updating often enough when encoding with more than 100 fps)
File: chfourcc(468 bytes; Sat, Apr/29/2006) download 'chfourcc' to disk

FourCC Changer

When trying to play ffmpeg-encoded videos on a friends' Windoze system, I found a little tool called "fourcc changer", which can be used to change the files to look as if they had been encoded with DivX(tm) 5.0, simply by changing the FourCC "FMP4" into "DX50". Other important FourCCs are "DIVX" or "XVID" (fourcc.org has a long list of them).

I think installing ffdshow is the better option, but in some cases you might be looking for a similar tool for other platforms, so I wrote a small python script which can basically do the same. I just hardcoded the FourCC offsets without looking at any documents, so please make backups of your files and/or check the output of running

chfourcc <filename>

(which should display sensible old fourccs) before trying to change them (by passing the new FourCC as an additional parameter).

Creating MPEG files

Often, I want to convert a series of image files (e.g. PNGs) to an MPEG file for giving it to someone else or for integrating it in a presentation. So far, I realized that MPEG2 is not at all as compatible as I would have imagined. I could play literally all files I created with MPlayer, most also with Xine, but had very few luck with them on plain Windoze/Mac systems.

One hint by RC could be useful:

[And] those players that will handle MPEG-2 AVIs (MPlayer, ffplay, VLC, Xine, avidemux2... Perhaps MPC?) have ODML support, anyhow.

Maybe that could be done with a command like the following (as used by Travis Vaught on enthough-devel in the "Help for animation in MayaVi2" thread):

mencoder "mf://heartslice%03d.png" -mf fps=10 -o heart.avi
-ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=500

This is a choice of commands I tried (with input being sth. like -mf fps=25 -vf scale 'mf://*.png'):

# create MPEG2 ES (elementary stream) with mpeg2enc:
mplayer -noframedrop -vo yuv4mpeg -v -osdlevel 0 <input>
mpeg2enc -f 3 -v 1 -H -b 5000 -V 1024 -F 3 -a 1 --no-constraints \
  stream.yuv -o output.m2v

# convert/mux ES -> PS:
tcmplex -i output.m2v -o output.mpeg -m 2

# create MPEG2 with mencoder/lavcodec, native MPEG container:
mencoder -v \
  -ovc lavc -lavcopts vcodec=mpeg2video:vbitrate=3000:vhq \
  -of mpeg -o output.mpeg <input>

# create MPEG2 with mencoder/lavcodec, lavformat MPEG container:
mencoder -v \
  -ovc lavc -lavcopts vcodec=mpeg2video:keyint=1:mbd=1:vqmin=2:vqmax=10:autoaspect \
  -of lavf -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames \
  -o output.mpeg <input>

# create MPEG1 ("absolute lowest common denominator")
mencoder -v \
  -ovc lavc -lavcopts vcodec=mpeg1video:vhq:vbitrate=1800000:autoaspect \
  -of mpeg -o output.mpeg <input>

# create MPEG4, supposedly readable by QuickTime (untested):
mencoder -v -oac faac -faacopts mpeg=4:raw -ofps 15 -srate 44100 \
  -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=250:autoaspect:mbd=2:mv0:trell:v4mv:cbp:last_pred=3:predia=2:dia=2:precmp=2:cmp=2:subcmp=2:preme=2:vglobal=1:aglobal=1 \
  -of lavf -lavfopts format=mp4:i_certify_that_my_video_stream_does_not_use_b_frames \
  -o output.mpeg <input>

# other untested cmdlines from the web that should work with QT:
mencoder -vf scale=320:240 -oac faac -faacopts mpeg=4:raw:br=128 \
  -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=1200:mbd=2:cmp=2:subcmp=2:trell:v4mv:aic=2:vglobal=1:aglobal=1 \
  -of lavf -lavfopts format=mp4:i_certify_that_my_video_stream_does_not_use_b_frames
  -ffourcc mp4v -o output.mpeg <input>

mencoder -vf scale=320:240 -oac lavc \
  -ovc lavc -lavcopts acodec=aac:abitrate=128:vcodec=mpeg4:vbitrate=1200:mbd=2:cmp=2:subcmp=2:trell:v4mv:aic=2:vglobal=1:aglobal=1
  -of lavf -lavfopts format=mp4:i_certify_that_my_video_stream_does_not_use_b_frames
  -ffourcc mp4v -o output.mpeg <input>

Now that we are talking about MPEG4, it seems to be easy to create AVIs which are very hard to play back on Windows systems, even if you are willing to install codecs/players. I always proposed ffdshow, but only recently noticed that it is very important to use the newer "tryout" variant on sourceforge.net, the original "ffdshow" project is unmaintained. I have been told that using the XviD codec may help (e.g. when playing back with VLC). Also, I tried -ffoucc DX50, see also my FourCC Changer above.

My digital camera (Casio Exilim S-500) creates files with MP3 sound and an "M4S2" video FourCC, which stands for Microsofts' newer MPEG-4 codec, compliant to MPEG-4 version 2 simple profile. Maybe that is a good, portable combination, I will have to check that (fourcc.org mentions an "automatic WMP download").

When creating large AVIs, note that MEncoder automatically uses ODML for files larger than 1GB. To be more widely compatible, you can use "-noodml" for files up to 2GB.

I would be very happy about feedback / additions / links / hints / thanks about this section, which is also some kind of sketchpad for me to write down possible methods.

MPlayerHQ's ffmpeg FAQ could be helpful, too.


Valid XHTML 1.0! Valid CSS!
This page was last modified: Thursday, January 29, 2009 hacker emblem