FFmpeg 0.4.9pre1 patch
Introduction
This patch enables Motion to be built with FFmpeg 0.4.9pre1 and also newer 0.4.8 builds (such as the ones available for Gentoo).
The patch is not a complete transition from 0.4.8 - it enables support for both 0.4.8, newer 0.4.8 builds and 0.4.9pre1.
Description of Patch
Main Purpose(s)
FFmpeg version 0.4.8 (build 4680) contains a hack for supporting MPEG1 video with non-standard framerates. The framerates available for MPEG1 are quite few, basically starting at 23.976 (there are some unofficial exceptions). The hack inserts B frames (i.e., empty frames) to pad the video stream to a proper framerate. Since Motion videos often have pretty low framerates, this hack is necessary when using MPEG1. Unfortunately, the hack has been removed in later FFmpeg builds (after 4680).
This patch consequently removes MPEG1 support when a non-supportive version of FFmpeg is detected. Note that timelapse still works, even though it uses MPEG1. That's because timelapse uses a standard framerate.
In addition, FFmpeg 0.4.9pre1, which is the latest non-CVS version of FFmpeg, has a different API for
av_write_frame
than previous versions.
This patch uses the correct API depending on the version of FFmpeg used.
MPEG1 vs. MPEG4
Up until now, Motion has used different techniques for encoding MPEG1 and MPEG4 videos. For MPEG1, the old libavcodec method has been used, and for MPEG4, the new libavformat method has been used. The patch moves MPEG1 to using the new method as well. This means that
ffmpeg.c is slightly cleaner and should hopefully be more flexible than before.
Testing
I have tested the patch by compiling against three different versions of FFmpeg: 0.4.8 (build 4680), 0.4.8.20040322-r1 (build 4707) and 0.4.9pre1 (build 4718). For each version, I tested timelapse, MPEG1, MPEG4 and MS-MPEG4. I used framerate 5 in all cases (except timelapse, of course). The results are:
|
0.4.8 |
0.4.8.20040322-r1 |
0.4.9pre1 |
timelapse |
ok |
ok |
ok |
MPEG1 |
ok (1) |
n/a |
n/a |
MPEG4 |
ok |
ok |
ok |
MS-MPEG4 |
ok |
ok (2) |
ok (2) |
(1) The video is naturally not very smooth, since 5 frames are padded to 24 or so every second.
(2) I get the following warning a lot:
[msmpeg4v2 @ 0xb7d0c0c8]warning, cliping 1 dct coefficents to -127..127
. This is not because of the patch, AFAIK.
Multiple FFmpeg Versions
If you have multiple FFmpeg versions installed, e.g. for testing purposes, you may run into trouble. For example, I have three versions installed:
- 0.4.8 in /usr/local/ffmpeg-048-pure
- 0.4.8.20040322-r1 in /usr
- 0.4.9pre1 in /usr/local/ffmpeg-049
If I run
./configure [...] --with-ffmpeg=/usr/local/ffmpeg-048-pure
, I cannot build Motion. Why? Because the linker tries to grab the FFmpeg libraries from /usr/lib despite my use of the
--with-ffmpeg
flag. The reason is that the link flags look like:
LIBS = -lm -lpthread -ljpeg -L/usr/lib -lcurl -lssl -lcrypto -ldl -lssl -lcrypto -ldl -lz -lcurl
-L/usr/local/ffmpeg-048-pure/lib -lavformat -lavcodec -lm -L/usr/lib -lxmlrpc -lxmlrpc_xmlparse
-lxmlrpc_xmltok
The interesting thing is that
-L/usr/lib
occurs
before -L/usr/local/ffmpeg-048-pure/lib
. Since
ld
reads
-L
flags from left to right, /usr/lib is searched before /usr/local/ffmpeg-048-pure/lib. The solution is to move
-L/usr/local/ffmpeg-048-pure/lib
first on the line.
Open Issues
There are some things that should be considered before the patch can be regarded as complete.
- For non-MPEG1, the behaviour for an existing video file is to overwrite. For MPEG1, it is to append - in order to support timelapse. Should the append behaviour be specific for timelapse only (applies only to FFmpeg 0.4.8)?
- Currently,
gop_size
is set to 10 for MPEG1 and 12 for MPEG4. I don't know if these are the best values.
- For MPEG1,
max_b_frames
is set to 1, and for MPEG4 it is not set at all. I don't know if this is the best way to go.
- The FFmpeg version is not detected by configure, but rather by examining preprocessor macros during the build procedure. In order to notify the user that MPEG1 support has been disabled, the following set of warnings is printed. Is this enough?
ffmpeg.c:32:9: warning: #warning **************************************************
ffmpeg.c:33:9: warning: #warning Your version of FFmpeg does not support MPEG1 with
ffmpeg.c:34:9: warning: #warning non-standard framerate. MPEG1 will be disabled for
ffmpeg.c:35:9: warning: #warning normal video output. Please read the Motion Guide
ffmpeg.c:36:9: warning: #warning for more information.
ffmpeg.c:37:9: warning: #warning **************************************************
- If the user tries to set
ffmpeg_video_codec
to mpeg1 with a newer version of FFmpeg, the following error will appear in syslog. Is this enough?
Nov 25 23:17:21 void motion: *** mpeg1 support for normal videos has been disabled ***
- We don't handle delayed frames. I will try to see if this is relevant.
Installation of Patch
Enter the Motion source directory, and type:
zcat <path to patch> | patch -p1
All done! Run
./configure
and then
make
.
Now added to my current 3.1.18 sources and being tested.
Great job.
--
KennethLavrsen - 29 Nov 2004
Thanks!
I'll update the Motion Guide once 3.1.18 is out as well.
--
PerJonsson - 30 Nov 2004
NOTE NOTE NOTE NOTE
The patch contains a bug, that results in jumpy mpeg1 videos with ffmpeg 0.4.8. Remove line 272 in
ffmpeg.c (after the patch has been applied). It is the line that reads
c->max_b_frames = 1;
.
This bug will be removed in the next snap of Motion.
--
PerJonsson - 17 Dec 2004
Changed the status to
ReleasedSnapshot. It is included in
MotionRelease3x1x18snap8
--
KennethLavrsen - 03 Jan 2005