Diary Of An x264 Developer

05/09/2008 (2:51 pm)

Variable length coding and you

Let’s say you want to write a number to a bitstream. The decoder is expecting a number, so it knows exactly what to look for. But how do you format this number?

You could write 16 bits no matter what, putting a max of 65535 on this number. This would also waste tons of bits though; what if the number you’re writing here with your encoder is almost always 0, 1, or 2? Writing 16 bits would seem ridiculous, so it only makes sense to use a variable-length code (VLC). But how would the decoder know how *long* the code is? Here’s a simple example:

5 -> 101
2 -> 10

Both will look the same to the decoder, since it doesn’t know whether the code ends after the first bit, the second, the third, etc. But there’s a solution to this problem; a common one lies in the form of exponential Golomb codes. Here’s an example:

0 -> 1
2 -> 011
5 -> 00110
8 -> 0001001

The number of zeroes is the number of bits in the code, and a 1 is used to terminate the list of zeroes. This may seem inefficient, but in a sense one has no other choice but to have some sort of coding scheme like this. Of course, exponential golomb codes are only optimal in the case of a specific probability distribution; an optimal variable-length coding system has code lengths chosen based on the probability of each value. This is the primary reason why MPEG-4 Part 2 (Xvid/DivX) is superior to MPEG-2; the VLC tables were much better chosen.

Of course, the ideal system would be to allow custom VLC tables to be put in the header of the video file; its quite trivial to design a twopass encoder to create optimal VLC tables for a given video, or even a given frame. H.264 partially does away with this problem with CABAC; while there would be benefit to including a custom initial CABAC state, the cost of various CABAC modes adapts quickly to the video. Of course, this is not always the case; CABAC still relies on variable-length codes, because it converts numbers to series of binary digits, which are then written into the context-based arithmetic coder (the “binary” part of CABAC). One result of this is that even if one has a B-frame made up entirely of intra blocks, the arithmetic coder won’t be able to completely adapt, and each block will still cost more bits; the variable-length coding for the macroblock type is not chosen in such a way that would allow such “complete” adaptation.

7 Responses to “Variable length coding and you”

  1. imcold Says:

    Hi Dark Shikari, you miss one zero at the front of exp-golomb code for 8 (should be 0001001). Nice blog on one of my favorite subjects, I’ll be watching it for sure ^_^

  2. Dark Shikari Says:

    Thanks for reporting the error; typo fixed!

  3. Uhmmmm Says:

    I think it’s worth noting that by simple extension, exp-golomb coding can be made more efficient for most numbers. Instead of representing the number of bits with the number of zeros before a one, you can represent the number of bits itself by the code you presented:

    0 -> 1
    1 -> 010 0
    2 -> 010 1
    3 -> 011 00

    This uses one more bit for storing 1, 2, and 7-14, but is at least as efficient for all other numbers.

  4. Uhmmmm Says:

    Forgot to add, that extended exp-golomb code was used in an earlier version of the Dirac spec, but seems to have been removed now. I think it was probably only used for certain header values which tended to be small numbers anyways, resulting in a possible loss and no real gain. Plus the added complexity. That’s my guess anyway.

  5. Kedar Says:

    Hi,
    I am currently working on CAVLC and CABAC. I just saw your blog and I thought I should ask if you would be willing to look into any queries that I may have in future….

    thanks,
    Kedar.

  6. borgy Says:

    Hello,

    Sorry for writing here on your blog but I can’t seem to find other contact data and you’re quite a name in this field.
    I’ve started to work on a h264 coder/decoder for my university together with 3 coleages. Can You please recommend some good documentation, other then the norm itself?
    We’ll be limiting ourselves to baseline right now, and are currently working on CAVLC.

    Looking forward to any help :)

  7. Dark Shikari Says:

    @borgy

    Read existing implementations, like x264 and libavcodec.

Leave a Reply