Fixing A/V sync and unifying frame rates on FlyCamOne movies

I've got myself a flycamone2, a small video cam that records MJPEG AVIs to SD. Sadly enough, the firmware is quite buggy, which often leads to desynchronized audio (or rather, video, as you will see); also, the frame rate is variable.

So I investigated the AVI files that are generated by the flycam. Basically, they consist of audio and video frames, interleaved (that's why it's called "AVI", after all :-) -- a bunch of video frames are followed by an audio frame, video frames again, audio, and so on.

The audio frames are fixed-size (4088 bytes, which translates to 0.511 seconds at a sample rate of 8000), and those audio frames serve as a kind of implicit timestamp with their fixed sample rate.

The video frames come in between the audio frames (actually, the very first frame in a file always seems to be a video frame), and change in number (variable frame rate, it seems they're just dumped to the file when the JPEG encoder on the chip is done compressing a frame) -- I've seen between 5 and 15 video frames per audio frame interval in the files I've analyzed.

At the end of a movie, the cam seems to calculate the average frame rate and write this into the file header. Since the real frame rate is varying, I think this accounts for some of the A/V sync problems people are seeing.

The other reason for sync problems seems to be that sometimes, the cam stops to record video frames, but continues to record audio frames. The average frame rate will drop, accordingly, causing a big A/V desync.

The solution

I've written a perl script that fixes the sync problems and converts the files to a fixed frame rate (25 fps, changeable at the top of the script) so they can be played back smoothly on a TV.

It does that by using the audio frames as timestamps, and duplicating or dropping some of the video frames in between two audio frames to adapt the frame rate.

When a file has the problem where the recording of video frames stops, the file is terminated there (so the end of the audio stream is lost).

The script needs:

usage infile.avi outfile.avi


First, the tool causes a loss of quality by dropping or duplicating frames. It does not decrease the picture quality as such, since the video data is not re-compressed.

Second, it reads the whole AVI file into memory, so take care (I know this is stupid, but that's the way File::Format::RIFF works).

It depends on mencoder to re-encapsulate the resulting AVI at the end, because I couldn't be bothered to fix all AVI header information or re-generate the AVI index myself.



avifixer is copyright by christian mock and licensed under the GPL.