Indeo 3 overview

January 27th, 2023

The overall idea behind this codec is simple: a frame is split into cells of variable size (the patent says “a roughly regular grid of cells”) using a binary tree, each cell can then either be coded in intra mode (differences to the previous line) or inter mode (differences to some region in the previous frame). Coding is done by splitting cell into 4×4, 4×8, 8×8 or 8×4 blocks and using one or two of 21 codebook to code pairs of differences (with some tricks to compress small differences and zero runs even further).

The patent describes thirteen different modes, the decoders I know about support only some of those:

  • mode 0—code 4×4 blocks using a single codebook;
  • mode 1—code 4×4 blocks using two different codebooks for even and odd lines;
  • mode 2—code 4×4 blocks using two different codebooks but the second one is used only for the second line (no known decoder supports that mode);
  • mode 3—code 4×8 block using a single codebook by coding differences to the even lines and interpolating the odd ones;
  • mode 4—the same as mode 3 but with two codebooks;
  • mode 5—very similar to mode 3 but with a possibility to add a correction to the interpolated lines (since it involves writing single bits that no other part of the codec does, no known implementation supports it);
  • mode 6—like mode 5 but with two codebooks (and equally unsupported by anything known);
  • mode 7—code 4×4 blocks with bit flags for telling which dyad to code (no known decoder supports this);
  • mode 8—the same as mode 7 but with two codebooks (of course it’s unsupported);
  • mode 9—the same as mode 7 but with the second codebook specially for the second line (equally unsupported);
  • mode 10—code 8×8 block using a single codebook by either duplicating pixels on even lines and interpolating odd lines (for intra) or scaling each delta for 2×2 block (in inter mode);
  • mode 11—code 4×8 (inter only) block using corrector repeated for each odd line;
  • mode 12—mode 11 with two codebooks (only VfW version supports it).

Considering the internal implementation details (e.g. using arrays for opcode handling or not), I’d say that QuickTime and XAnim versions of the decoder are based on the same porting kit code supplied by Intel while Video for Windows version uses the different codebase (it’s not just an encoder being present and mode 12 support, it’s also the way how many tables are generated in runtime while they are static in other decoders, not using the opcode tables and other minor things).

But before we start to code cells we need to perform the initial frame splitting and the next post should be about that.

Starting yet another useless encoder

January 26th, 2023

Even before I started to write my series of posts on FFhistory, I had another work in progress already which I’m now making public in order not to chicken out (as I did several times already). I’m talking about Indeo 3 encoder.

Why Indeo 3 of all possible things? It’s both not your conventional DCT-based codec and it’s widespread enough to be of some limited use for me (being present in AVI, MOV and VMD containers, only Cinepak is more ubiquitous). I’m not as good as Mike Melanson but I’m willing to try my hoof at it.

The funny thing is, there’s an opensource decoder for it and even a decent description in US patent 5,386,232 from 1995 (so it’s expired already and anybody can write an encoder for it). The problem is that those two sources don’t match between each other and somewhat disagree with the official binary specification (I’m pretty sure that both Indeo3 decoders were REd from XAnim module). And Ghidra does not like VfW binary (maybe it’ll like the version inside QT6 better) so I can’t easily refer to it either.

Anyway, I attempted and gave up writing an encoder for Indeo 3 several times because of its perceived combinatoric complexity. First you need to split frame recursively into blocks—how to select them? Then you need to select one of the coding modes (again, how?) and codebooks (same question). Trying to think of a reasonable way to implement it all made me shudder and give up until I finally read the format description and persisted enough to write at least something working (side note: I also have the same problem with TrueMotion 1 encoder which I also want to write one day, hopefully it’ll be easier now).

Also I tried to look into the encoder implementation and found it as a bunch of magic numbers at work. I’m not joking, during initialisation it seems to set several dozens of various integers and floats and use them for various coding decisions (at least what I could understand from it is that codebook selection is kinda tied to the internal quantiser parameter which is calculated depending on bitrate/quality—and various magic numbers).

So I want to document how this codec works, what differs in the different descriptions of it and how my encoder decides what to use in different situations. This should amount to another dozen of posts that nobody will read.

A quick glance at WA

January 21st, 2023

A certain Paul B. asked me to look at WA (aka WavArc) and it turned out to be rather interesting. For starters, it’s the only lossless audio archiver and not compressor I’m aware of (the difference is an ability to store multiple files in single archive). Of course there are things like Rar or WinZip with special multimedia compression modes but they’re general-purpose archives with content-specific compression methods and not audio-only archivers.

There are two versions of the executable: 32-bit DOS one and 16-bit DOS one (where all 32-bit integer and FPU operations are emulated). The latter turned out in showcase what Ghidra lacks in supporting old DOS executables, so eventually I tried 32-bit version. Even if I had to load it manually, luckily it turned out to have PE-like header for the loader so it was no problem figuring out segment mapping. After that it was a piece of cake.

Essentially there are three compression modes: store (mode 0), Shorten-like fixed prediction and fixed Rice codes (modes 1-4) and mode 5 with LPC prediction and residue coding using either fixed Rice codes or arithmetic coder (with fixed model transmitted before residues).

Overall, it’s a curious piece of software that was interesting to look at.

FFhistory: conclusion

January 20th, 2023

Now that I’ve finished remembering various developers it’s time to evaluate their impact and how it would be without certain them.
Read the rest of this entry »

FFhistory: Paul B Mahol

January 19th, 2023

This guy appeared in 2011 from nowhere and in a sense he looks like an embodiment of the project. You can find in him the same productivity and unwillingness to meet other people as in Michael Niedermayer, the same talents to reverse engineer codecs as in many people mentioned in the post about them, the same diva behaviour as in Baptiste Coudurier, the same versatility as elenril, the same unwillingness to finish Bink2 decoder as Luca’s unwillingness to finish Opus decoder (I’m still waiting for both BTW) and the same abrasive personality as in many developers from MPlayer. In other words, a guy with strong positive and negative sides.
Read the rest of this entry »

FFhistory: helpers

January 18th, 2023

I’ve tried to mention various developers who made the project better but there are still some people worth mentioning. Some of them have contributed next to none or no code at all but they helped in other ways. Now is a good occasion to mention them.
Read the rest of this entry »

FFhistory: the Khirnovs

January 17th, 2023

Here I’d like to remember two siblings who developed for FFmpeg and libav.
Read the rest of this entry »

FFhistory: Summer of Code students

January 16th, 2023

Since 2006 FFmpeg (and libav when it existed and was active) has been participating in the Summer of Code program. Essentially it’s students working on tasks for different project with one corporation paying for the successful completion of the task during summer (back in the day it was $4.5k, no idea what happens now). While the sum is not remarkable by American standards, it was high by Central European and Asian standards. And of course there were students who were after money and disappeared after they got them (in one case with unbelievable claims about why the health problems prevented him from the completion). In one case there was a student who essentially plagiarised another project, in another case a student dumped a lot of code with unknown functionality so it was hard to understand or review. But here I want to talk about the students who actually stuck around after the program was over and even did something else.
Read the rest of this entry »

FFhistory: the new generation

January 15th, 2023

The original FFmpeg developers were mostly the people developing the project for fun and for personal reasons (i.e. being able to watch anime encoded in some weird format), the newer generation might’ve come for that reason but as often as not they were employed by some large company (or got employed by it soon after they started contributing) so their subsequent work was done mostly on behalf of their employer.
Read the rest of this entry »

FFhistory: Luca Barbato

January 14th, 2023

He claims to have started his career by writing Altivec optimisations, being spotted by Gentoo developers and asked by them to apply his skills at certain opensource projects… Originally he worked on MPlayer but eventually, in 2005, he turned his attention to FFmpeg as well.
Read the rest of this entry »