Cursory Fraps FPS1 Research

A user on one of the FFmpeg mailing lists brought to our attention a codec called FPS1. The company behind this codec is named Fraps. The application domain for this codec is apparently real-time screen capture of computer game animation, such as in popular first-person shooter games, hence the clever FOURCC FPS1.

The company has several samples available on their website. According to the Transcode project, which was able to support earlier versions of the binary decoding module, the format layout was as follows:

* Fraps has codec FPS1 and the image data is actually a packed form of
YUV420
*
* Binary layout is as follows:
* Each frame has an 8 byte header:
* The first DWORD (little endian) contains the following:
Bit 31 - Skipped frame when set, no data.
Bit 30 - DWORD pad to align to 8 bytes (always set)
Bit 0-7 - Version number (currently 0. Unrecognised format if
higher)
* Then comes data which is organized into 24 bytes blocks:
*
* 8bytes luma | 8bytes = next line luma | 4 bytes Cr | 4 bytes Cb
*
* So one 24 bytes block makes defines 8x2 pixels

However, examining some sample content, the numbers do not reconcile according to this description, which states that there should be 24 bytes/16 pixels, or 3/2 bytes/pixel (same as YUV420). In a sample file that has a resolution of 1024×768:

(1024 * 768) pixels * 3/2 bytes/pixels = 0x120000 bytes

However, the first frame of this particular sample file is actually 0x8D0D0 bytes. Note that:

(1024 * 768) pixels * 2/3 bytes/pixels = 0x80000 bytes

so perhaps 2/3 is closer to the bytes/pixel ratio we are searching for.

The next non-skip frame in the sample file in question is 0x8D0DC bytes, which is not aligned on an 8-byte boundary, despite the 8-byte alignment flag being set. So much for that data point. Also, subsequent non-skip frames vary slightly in length. The above coding format description implies that all frames would be the same size.

The poster did mention that Transcode interoperated with an earlier version of the binary decoding module. Perhaps earlier versions of the format were a simpler, intra-only codec. This version must use some sort of interframe coding, maybe a skip code to indicate a 8×2 block is unchanged from the previous frame.

Further, I have trouble understanding why it would be a YUV codec. Ostensibly, this codec is geared toward losslessly capturing computer game animation pixels which are invariably rendered as RGB. Converting to YUV guarantees information loss straight out of the gate.

I started poking around one of the Fraps DLLs (frapsvid.dll) and found this curious string:

“The Fraps video decompressor requires a processor with SSE instructions.”

This is fascinating as SSE instructions generally deal with floating point operations– not the kind of thing I would expect from this type of algorithm. SSE is also known to have a multitude of special memory cache manipulation instructions so it is not unreasonable that this is why the decoder wants these instructions present.