It was very hot summer – both in terms of temperature and development process. I was writting decoder for the some codec (look at the category of this post if you don’t know what codec family was that, the fourth incarnation of it).
The main difficulty was
With the help of this tool written by Mike both he and I were able to capture some dynamic data during execution of the reference decoder and, basing on that information – to reconstruct execution flow, debug some variables and guess how some functions work. Still there were many functions that required assembly-human dictionary and took plenty of time.
What has surprised me during this work:
- That is the first time I work with PIC code. Now I understand why some people believe it’s evil thing. Constantly calculating real addresses from offsets from GOT (global offset table) is no fun and switch(){} construction becomes extremely complicated. But now I know GOT address of that decoder by heart.
- Passing parameters partly via stack and partly via registers (for example, source and stride are passed in register and destination as an argument) is also fun to watch
- It’s quite unexciting when one function does virtually nothing except calling other function (with the same arguments).
- There are several VLC reading techniques employed in reference decoder:
1. Peeking if the next bits match some codeword in the table (i.e. iterate over table of codewords, look at the next k bits of bitstream and compare them with codeword)
2. Using next 16 bits from the bitstream to find out code length (by finding prefix corresponding to the given length), then the difference between prefix and actual code (minus unused bits of course) is used to determine actual code value
3. Using 256-element lookup table on the next 8 bits in bitstream to determine code length and value - And that’s not all – codeset for the first case may be stored in two ways – in pairs
(code, length)
and in one value using formula(1 << length) | code
. And function using this has to determine most significant one position, remove it and then call show_bits().
I plan to give codec architecture review in my next post.