Musepack SV8 is almost ready

September 26th, 2007

Judging from this post there is an eight steam version of Musepack in beta testing (but the spec is not frozen yet).

What distinguishes it from previous versions? Now it is container-aware. Previous versions store just audio frame in the continuous bitstream with no defined behavior on seeking nor demuxing. It was almost as fun as Monkey’s Audio container.

Now Musepack has a chance to spread in the wild (i.e. in other containers than .MPC). That mostly depends if there will be standard way to store them in the other containers (that’s where Ogg Vorbis failed). Well, good luck.

Some details on RV30/40

September 12th, 2007

RV8 or RV30 is close to earlier H.264 drafts and Sorenson Video 3, because they both use one variable-length code (Golomb codes in case of SVQ3, something special in RV30/RV40) to represent macroblock information (type, intra prediction modes). RV40 uses this code only to represent motion vectors and number of macroblocks to skip, macroblock type and intra prediction modes are coded with variable-length codes chosen from the set of them depending on context.

Here are the main differences from H.264:

  1. Different bitstream. Special codes for elements and own substitution of Golomb code.
  2. Intra prediction types are specified only for luma subblocks, chroma subblocks use some of them for prediction too.
  3. Intra prediction modes are slightly different and some of them require additional context (down left neighbour).
  4. Bidirectionally predicted blocks in B-frames do not use motion vectors from the previous/next frame in motion vector prediction while using them in motion compensation.
  5. Intra prediction for intra blocks in interframes is performed even when neighbouring blocks are not intra blocks.

Main differences between RV30 and RV40:

  1. Bitstream syntax and different codes (RV30 is easier in this matter).
  2. RV30 does not have 8×16 and 16×8 motion compensation modes (while 8×8 mode exists).
  3. Different motion vector prediction algorithm.
  4. B-frames in RV30 do not contain some variant of bidirectionally predicted blocks which RV40 has.

And now here is the list of things I didn’t like in RV30/40:

  1. Slice header does not contain number of macroblocks coded in this title. While it saves whopping 6-13 bits per slice (and frames usually have less than a dozen of slices, usually two or three), it gives unnecessary pain to implementor.
  2. Vertical left intra prediction method uses down left neighbour pixels in calculation for one insignificant pixel (it’s insignificant because it does not affect further intra prediction).
  3. Motion vector prediction is a bit complicated too.
  4. And, of course, the lack of good documentation

What I did during my summer

September 12th, 2007

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.

Samples, and lots of them

August 20th, 2007

Extremely big thanks to Mike, who sent me a dozen of DVDs with samples and they eventually got delivered (Roberto Togni also had sent me some disks with samples but they disappeared somewhere). It took about a week to deliver them to Ukraine. And a whole month to pass customs control.

But nevertheless it’s here and now I have enough samples to test my future and current decoders.

My thoughts on decompiling

July 18th, 2007

Here I want to present my thoughts on decompiler techniques I’d like to see. Maybe a lot of this is implemented somewhere but I haven’t seen working decompiler.

  • Possibility to load disassembly instead of disassembling by itself.
  • Good flow analyzer. REC, for example, produces a lot of silly gotos. Is it so hard to build directed graph for blocks, separate out conditional code and loops? IDA does so. And it’s pretty easy to recognize typical schemes like do{}while;
    if(){}else{} and detect break; in loop.
  • Watching ‘live’ registers. Each instruction may affect some registers and flags but some of them won’t be needed later (for example, sometimes substraction is used to modify some value and sometimes also result flags are checked too). And block of instructions may depend on some register values set before (if they are not modified before using). Boomerang had something like this but resulting code was too LISPy.
  • Reiterations – if decompiler finds out that function uses registers for passing parameters then code must be changed to reflect this.
  • Pattern recognition – it would be very nice if decompiler could recognize the same patterns over the code (in form: A = B+ constant; B = A | constant; ). And if it also could automatically label bitreading functions… But I fear that this is AI-complete problem.

Well, my rant ends here. Back to work.

Monkey Audio

June 10th, 2007

Thanks to Peter Lemenkov who pointed me to this Monkey’s Audio decoder implementation. It has four strong points: GPL, C, small and clean. Oh, it also takes less memory too.

The only drawback is that old APE files are not supported (but nothing can play them on PPC anyway without x86 emulator) so I’m eager see APE support in MPlayer, Xine, VLC (or maybe it’s there already?). Preferably via libavcodec 😉

Samples

April 29th, 2007

Looks like the best way to collect a lot of samples is to become a developer and maintain demuxer/decoder. You may receive a lot of samples that do not decode with it 😉

I’d like to thank three major contributors (from Dania, Netherlands and Japan) of VC-1 in HD-DVD/Blu-Ray samples. It is because of them VC-1 video playback is less buggy than it was before (I know it still is but at least it’s improving).

Why we should have another Monkey’s Audio decoder implementation

March 25th, 2007

Why should I bother about Monkey’s Audio? Because many pirates good people offer classical music in this format (FLAC is quite rare and I’ve seen WavPack only once).

What I consider wrong in Monkey’s Audio design:

  • No verson compatibility – each version alters decoding process
  • Huge blocks – some megabytes is huge indeed (WavPack – 64k, FLAC – even less), hence inaccurate seeking and big memory requirements
  • “Insane” profile – if it does not decode in realtime on my CPU that is unusable

What I consider wrong in MA implementation:

  1. There is only one implementation (with two known ports)
  2. It is not endian-safe (both generated WAV headers and < 3.92 decoding)
  3. OO in that case means “Object-Obfuscated” (i.e. too many files where you can’t easily find required code)
  4. Custom license

Maybe during GSoC somebody will write easily understandable portable decoder in Lavc that will allow playback of .APE in FFplay,MPlayer,VLC,Xine,etc. Otherwise I’ll have to do it myself.

VC-1: Some Bugs Squashed

March 25th, 2007

This and last weekend I fixed some bugs in my decoder so now watching HD-DVD/BluRay movies will be a bit more pleasant ;-). But for the whole watching and listening experience you should wait for E-AC3 decoder (maybe it will be implemented during Google Summer of Code).

As for me, my systems neither are fast enough to decode it in realtime (1.42Ghz PPC G4 and PII 266Mhz) nor can even display full picture (max. resolution is 1280×1024 but I’m fine with it). So you may conclude I’m not interested in watching HD and you will be right. But I care for decoder and will fix bugs in it as I do already.

VC-1: Complex Profile is supported a bit

February 28th, 2007

I’ve just added some support for WMV3 Complex Profile (aka old Advanced Profile).
I don’t know why most samples (users complaining about) I’ve met are anime. It’s a good chance they will work now.

And here is updated list of CP features explained:

  • RES_X8 – additional bit at the end of I-frame header pointing if this is normal I-frame or this is special coded frame (I’m sure that’s exactly WMV2/8 J-frame with different header)
  • RES_FASTTX – somehow interferes with P-frames but bitstream is not changed
  • RES_RTM – old P-frame format (header should be the same but some additions on macroblock level). This is also quite common in old WMV3 files. Not RE’d yet