In my research, I often generate a sequenceof images from either my experiment or from a simulation that I wantto put together into a movie. Since I use linux, I wanted to do thisusing free software in linux, and I wanted to be able to play themovie in linux. This webpage outlines what I've learned about how todo this in linux using mencoder or ffmpeg to create high quality filesthat are well compressed and the play well under all operatingsystems.
The movies are going to be non-standard size (usually square,around 200x200 pixels for me), and have a non-standard frame rate:typcially, my movies may only be 10 frames, so I don't want to run itat 30 fps.
We want to encode to some kind of relatively portable movieformat. ffmpegand mencoder both dothis using the libavcodec library developed as part of ffmpeg. Thecodec options from the mencoder man page include:
vcodec= Employ the specified codec (default: mpeg4). mjpeg Motion JPEG ljpeg Lossless JPEG h263 H.263 h263p H.263+ mpeg4 MPEG-4 (DivX 4/5) msmpeg4 DivX 3 msmpeg4v2 MS MPEG4v2 wmv1 Windows Media Video, version 1 (AKA WMV7) wmv2 Windows Media Video, version 2 (AKA WMV8) rv10 an old RealVideo codec mpeg1video MPEG-1 video mpeg2video MPEG-2 video huffyuv HuffYUV asv1 ASUS Video v1 asv2 ASUS Video v2 ffv1 FFmpeg's lossless video codec
ffmpeg supports an even largerlist of output codecs and container formats.
MPEG-1 and MPEG-2 streams are no good, since the frame rate islocked to 29.97 or 25 FPS. For an excellent overview of some of thecommon open-standard compression methods, see thispage.
(Note: "open" standard only means that the specifications aren'tsome undocumented industry secret. It does not mean, however, that theformats are not entrenched with patent issues, which mpeg4, and evenmpeg1 and mpeg2, most certainly are...You take what you can get,though.)
MJPEG would seem to be a good option, except that the files thatwe get seem to be incompatible with windows media player for somereason (at least with files encoded with mencoder). MJPEG supportsarbitrary frame rates, but the movies files could get large if youhave a lot of frames since it doesn't use temporal coding.
MPEG-4 is the best option. The mpeg4 stream can be stored ineither in the .avi or .mp4 (quicktime) container file: it can supporthigh levels of lossy compression to keep file sizes small and alsosupports arbitrary frame rates. It is also translates much more easilyto other platforms than wmv1 or wmv2.
mencoder only supports avi file containers, which is a pity sincethe quicktime widgets looks nicer, and the .mp4 container format hasfewer issues with compatibility (there are some fourcc issues with.avi: this container file format issue is the only reason why thempeg4 streams inside avi files from DiVX, xvid, ..., codecs areincompatible! How stupid is that?)
Note also that mencoder (at least version 1.0pre6-3.3.3 does) willbarf if we use anything other than jpeg files as our input, so weshould convert all our images to jpeg's with 100% quality to avoidany quantization loss at this stage:
$ for f in *ppm ; do convert -quality 100 $f `basename $f ppm`jpg; done
With mencoder, we can use the vbitrate option to set the degree oflossy compression. Note that the default mpeg4 option will add a"DivX" logo to the movie when playin in windows media player, so weprefer to use one of the other mpeg4 encoders, such as msmpeg4 ormsmpeg4v2. The commmand line I've used is:
mencoder "mf://*.jpg" -mf fps=10 -o test.avi -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=800
We can also use ffmpeg directly to encode the images files into amovie. If we start with files name 001.jpg, 002.jpg, ..., we can use:
ffmpeg -r 10 -b 1800 -i %03d.jpg test1800.mp4
This works very well, and is nice because ffmpeg is included indebian! My only complaint is that with ffmpeg is that you have to becareful that all the files are named sequentially. For example, for along time, I was missing 015.jpg, which caused it to encode only 15frames. To get it to work, I had to rename the files so that therewere no gaps in the file numbers. The .mp4 files encoded this way willplay fine with quicktime under windows, which I peronally prefer overmedia player, and which will never show the stupid DiVX logo, sinceit's doesn't use the braindead avi container. (see rant above...)
How do the file sizes compare?
Image files:
Initial ppms: 6.9 MB Initial jpgs: 8.0 MB (100% quality)
Movies (10 frames per second): avi files are encoded using mspeg4v2,mp4 files are done using the ffmpeg default (mpeg4).
1500 test1800.avi 900 test800.avi 528 test400.avi 1748 test1800.mp4 860 test800.mp4 504 test400.mp4 324 test200.mp4 264 test100.mp4
At 1800 kbits/sec, the quality is excellent, with no noticeable motionartifacts. 800 is very good, but at 400, the motion artifacts becomequite noticeable.
Other useful stuff:
ffmpeg -i test.mp4 -f singlejpeg -t 0.001 test.jpg
Check out this file for an example (latexsource file is available here). More info abouthow to do this is avilable from thiswebsite.
The movies will play fine under windows using acroread 7.0. Underlinux, if you install acrobat reader 7.0 for linux, you can save theembedded movies to disk and play them form there.