[FFmpeg-devel] [PATCH] RoQ video encoder

Eric Lasota riot
Fri Jun 1 04:26:09 CEST 2007

Michael Niedermayer wrote:

> does anyone have a working email address from him?
I can probably answer any questions you have about it.  I wrote the 
library that this encoder patch is based on (three times...), and a 
decoder, I'm quite familiar with the format.

It looks like some incorrect changes were made to the decoder since I 
last looked at it:
roqvideodec.c line 94:
case RoQ_ID_MOT:
    ff_apply_motion_8x8(ri, xp, yp, 0, 0);

roqvideodec.c line 124:
case RoQ_ID_MOT:
    ff_apply_motion_4x4(ri, x, y, 0, 0);

... Both of these are wrong.  MOT (or 0x0000 in the Q3 decoder) uses the 
image section from two frames ago, not the previous frame.  More 
specifically, MOT performs no action, leaving the image data that was 
rendered in the buffer two frames ago.  This is the behavior described 
by Ferguson's document as well.

However, MOT will copy data from the previous frame on the SECOND frame 
only.  This is because the decoder copies the first frame's result to 
the second buffer (see cl_cin.c line 1206).  Note that the encoder being 
implemented does not support this functionality, as it is only useful on 
the second frame of the entire video (and is not useful on the frame 
immediately after any other keyframe either, because a proper decoder 
will still attempt to pull from the frame before the keyframe).

Since the FFMPEG decoder already does double-buffering, a correct 
implementation would be to only perform those motion applies on the 
first frame, or just do what the official encoder does and copy the 
first frame result to the backbuffer.

Also, a minor untested patch to the RoQ encoder: An updated 
SortPossibilityData that removes less-than-optimal reductions.  Might 
produce a small increase in quality, might just cause blocking 
artifacts, I haven't tested it extensively, it doesn't appear to cause 
any quality degradation on basic tests.  It's formatted for libsb3, not 
the FFMPEG port, so it needs to be cleaned up and ported to the new 
struct names, but here you go:

The qsorts are still non-optimal as well (since two of the sort 
operations will re-sort invalid possibilities that have already been 
moved to the end of the list, the count should be the number of 
currently-valid possibilities, not MAX_POSSIBILITIES), but the encode 
time has always been extremely biased towards codebook generation and 
indexing cels to the codebook, so micro-optimizing the plist sort is 
probably a drop in the bucket.

I haven't been tracking the progress too well (just realized that Mike 
Melanson decided to encourage reviving this effort after I benched it 2 
years ago), but an issue that was brought up last time was that the 
results are implementation-specific to qsort, to an extent that I can't 
imagine ever having an impact on visual quality, but will produce 
different binary output depending on how qsort is implemented if a equal 
bit-error trades are encountered and ordered differently.  It might be 
slightly faster to implement a qsort that uses a fixed size as well, 
since all qsorts are performed on pointer lists.

More information about the ffmpeg-devel mailing list