Archive for the ‘Useless Rants’ Category

On Monster Codec

Sunday, July 15th, 2012

There is one codec unrivaled in its monstrosity. I’m talking about GoToMeetingAndNeverReturn.

First of all, look at its size. The oldest version I could find (it decodes only G2M2 and G2M3) occupies 6196600 bytes. Newer one with G2M4 support (and that’s an additional compressor too) is 8247160 bytes, Current version (with seemingly the same functionality) is 15665528 bytes.

What does it contain? Everything. I kid you not, All (maybe except one) GoToUnpleasantPlace utilities refer this small file and actually export their real main() function out from it. And their size is about forty kilobytes each.

What does it contain from code point of view? Some libraries for networking, cryptography, speech codecs library, libjpeg, zlib, some internal code and tons of C++-induced crap. When you see wrapper calling wrapper calling wrapper calling something trivial (and the wrappers just pass arguments as is and do nothing else), or when you see that 90% of any function is used for exception handling, then we’re talking about enterprise-grade C++ indeed. And of course absolute bloatedness (including making indirect calls where unneccessary) and inability to run on Linux (not with Wine or MPlayer2 loader) greatly help debugging.

Now to the codec details: every frame consists of chunks which hold different kind of data — frame information, mouse cursor shape, mouse cursor position, image data, etc. Frame is divided into tiles (usually 8×8 tiles in frame) and each tile is coded separately.

There are two compression methods, known by their numbers stored in frame header. For G2M2 and G2M3 it’s compression method 2, for G2M4 it’s compression method 3. Both are horrible.

Method 2 seems to have some completely unrelated submethods.

Here’s the call graph from method 2 decompression function.

Looks like there are several possibilities when coding with this method.

There is a possibility to use JPEG compression but I don’t know under what circumstances it’s used.
Also I’ve discovered that MSA1(MSS3) and MTS2(MSS4) actually use standard recommended quantisation tables from ITU T.81 Appendix K.1 (they are not used by libavcodec JPEG decoder though) and quality to quantisation mapping from libjpeg6.

Another coding method employs ELS codes I’ve described in the previous post and uses it to code some bit plane and RGB triplet in dependent form (i.e. with prediction from two previous pixels and using R-G, G, B-G components).

For method 3 so far I know only a few facts. First byte contains image type and depending on it decoding may vary a bit. For example, for image type 0 and 3 three following bytes contain some RGB value, other image types don’t have it. And internally it’s called MPCCoder or SMPCCoder.

In conclusion I want to say that this codec is too large and horrible to use only static reverse-engineering (because it’s very hard even to determine what is the next function called indirectly) and debugging it requires Windows, so don’t expect me to RE it. But if you do you’ll get many thanks and some money from these guys. Good luck!

Some Notes on Un-RE’d Codecs

Saturday, June 23rd, 2012

If I haven’t REd a codec that doesn’t mean I haven’t looked at them at all.
So today I want to talk a bit about some un-REd codecs and what peculiarities they have.

Looks like that all interesting codecs can be divided into three groups: screen codecs, intermediate codecs and speech codecs.
Since I don’t understand the latter group I shan’t give details on it.

Screen codecs

We have lots of them and they can be divided into two categories: simple and monsters.
Simple codecs usually employ some standard data compression library (zlib, FastLZ, LZO or LZF) or Huffman coding with standard median prediction and interframe difference.
I.e. boring, let’s talk about monsters.

  • Windows Media Video 9 Screen (aka MSS2) — combines palettised regions coded like in its predecessor with WMV9-coded regions.
  • M$ Expressions Encoder Screen (aka Titanium Screen codec) — it uses variable-length codes and codes frames with one of two methods. One of them is DCT exactly the same as in M$ ATC Screen codec.
  • MSU Screen Lossless Codec — this one seems simply code R,G,B values with some arithmetic coder and lots of context modeling and prediction.
  • Go2Meeting codecs — a good demonstration of the fact that the best strategy against REing is employing shitty coding monkey.
    Version 4 of decoder was monolithic 8 MB .dll file, version 4 is 15 MB already, all in “fine” C++.
    There are two compression methods known.
    Version 2 employs some weird arithmetic coder substitution (suspiciously like ELS-coder by Wm.D. Withers).
    Version 3 employs libjpeg and zlib for coding image blocks somehow, frame data doesn’t look like it at all.

Intermediate codecs

Cineform — looks like they use Huffman coding and wavelets and it codes 10-bit video.

Fruit Intermediate Codec — looks a lot like its successor (ProRes) but with different bitstream format and fixed coding scheme instead of adaptive ones.

BitJazz SheerVideo — the main problem with it is that most of the codec code performs conversion between any of couple dozens of formats (8- and 10-bit YUV and RGB packed in any possible way). Actual decompression code gets lost somewhere.

On reverse-engineering codecs

Saturday, June 9th, 2012

Sometimes I’m asked what codec I’ll do next. So here’s the answer: I don’t really know.

Since I’m no longer student I don’t have much time to dedicate to reverse-engineering.
Thus I work on different codecs time from time and select such codecs more or less in random.
When I see that it’s nearly completed I spend more time on it till I write a decoder.
That’s how I got RALF decoder, for example.
Or that’s how I have not got Discworld III BMV decoder: long time ago I’ve figured out container format and audio compression, a month ago I’ve advanced in video decoder; but it’s far from completion and I don’t know when I’ll work on it again.

Of course some factors affect my selection of codecs: if I have some interest in it, if it serves some theoretical purpose (e.g. I did Indeo Audio and RALF not because I needed them but to have respective families of codecs fully supported) or if somebody convinces me to do it (two words – GSoC 2007).

So if you ask for some decoder you might get it after a while (but no obligations unless you send me a box of Trocadero).
Don’t forget that samples should be present too (and decoder for the more complex formats).

A Dream Come True

Saturday, May 12th, 2012

For one of my friends – Lost Eden finally running on Amiga.
(screen grabber output only HAM8 CDXL thus screenshot quality is not the best, click it for fullsize version).

Though someone should write HNM4 decoder one day…

High Priority Libav Projects

Sunday, April 22nd, 2012

Once I’ve stumbled upon High Priority Free Software Projects at FSF. The idea appealed to me so here I present similar thing for Libav. It also has one or two sane proposals (hopefully) and offers the same level of support (i.e. none). But maybe in some cases we or I can help with it.

User tools

  • Working avserver;
  • Proper filter system. When I say “proper” I mean the one that allows dynamic reconfiguring, handles errors and works for arbitrary inputs and outputs;
  • libswscale replacement. The one that doesn’t sap sanity when you look at its code. Maybe with a nicer API too. And better pixel format support.

RealMedia support

  • Improve RM demuxer or maybe rewrite it from scratch;
  • Add proper support for multirate RM streams;
  • Add IVR format demuxer;
  • Add ClearVideo decoder (that’s the last codec in RM that we don’t support, hopefully not for long).

Other Intel codecs support

  • Improve Indeo4 decoder (it still has some features lacking);
  • AddImprove Intel Audio Coder decoder.

On2 codecs support

  • On2 VP7 decoder (we still can implement it faster than certain Baidu rival releases its source code);
  • On2 VP4 decoder;
  • On2 AVC decoder (that stands for “Audio for Video Codec”).

Too bad I cannot even find a decoder for On2 AVC nowadays. We have some samples though.

Micro$oft (screen) codecs support

This company has at least four screen codecs that we don’t support (MSA1, MSS2, MTS2 and CGDI).

  • Add M$ Screen Codec 1 decoder;
  • Add M$ Screen Codec 2 decoder;
  • Add M$ Expression Encoder Screen Codec decoder;
  • Add beta Windows Media Video 9 interlaced decoding.
  • Fix beta Windows Media Video 9 P-frames decoding.

QuickTime codecs support

  • Add Rottenfruit Intermediate Codec decoder;
  • Add any other codec decoder.

Other codecs

  • Add GoToMeeting 2-4 decoder;
  • Add more screen codec decoders;
  • Add more game format decoders (especially Discworld Noir BMV);
  • Add more audio (especially speech) codec decoders.

Codebook Hell

Tuesday, March 27th, 2012

There’s one codec I’d like to have reverse-engineered and implemented as an opensource decoder (well, lots of other codecs as well but this one particularly). Its name is VoxWare MetaSound, that’s an old codec which was used as an alternative to MP3 in old days of DiVX 3 😉 and its clones.

It’s definitely based on TwinVQ and is probably closer to the variant that got into MPEG-4 Audio standard (I suspect that mostly to make that standard even more bloated than before). That figures from having such modes like 8kHz/6kbps which is not present in VQF but present in ISO 14496-3 draft.

This codec probably has more data tables than TwinVQ (in binary decoder the section with codebooks is more than 256kB large, in TwinVQ it’s about 200kB) and should set a new record if we ever get a decoder for it.

Decoding looks very simple in theory: decoder initialises codebooks for given samplerate and bitrate (it’s actually signaled in extradata: VOXq for 44.1kHz/32kbps, VOXk for 16kHz/16kbps, VOXz for 44.1kHz/48kbps), for every frame it reads window type and an array of some values and performs reconstruction.

So far I was able to identify only some codebook information. Bark tables seems to be identical, but shape and whatever codebooks seem to be different.

I’ve spent a couple of evenings finding out that information and I dare someone (especially you, Vitor!) to write a decoder for it. I don’t know a thing about TwinVQ except one fact and it’s stated in the title.

Call for Intel Codecs

Monday, March 19th, 2012

I’ve spent two weekends and finally REd and wrote decoder for Re* Audio Lossless Format. With news like these I can deliberately call it Intel Audio Lossless Format.

So, what codecs we’re lacking so far?

  • Intel Audio Coder — it’s quite similar to IMC (Music Coder) but not identical.
  • Intel Layered Video Codec — probably it’s just h.263 variant, the only thing I know is that RealVideo 2 decoder was based on it (it’s mentioned in doxygen for Helix SDK I saw once in Internet somewhere and this supports that theory indirectly).
  • ClearVideo — a licensed fractal-based codec. It’d be rather simple DCT-based codec if not for one catch: it uses domain search to generate codes that then are used for block unpacking (and in decoder too, it seems). Maybe these patents will help?
  • Intel NGV — we’ll deal with it when it’s ready 🙂

Feel free to send any useful information about them, preferably working decoders of course.

After that we can claim full support of Real and Intel codec family.

A bit more about cooking

Saturday, November 12th, 2011

Sometimes when I have an acute nostalgy I try to cook something from my homeland.

First time I made
Köttbullar (med potatis och lingonsylt självfallet). Too bad I could not do it SWEDISH STYLE! :-(. This time I tried to make Janssons frestelse. Jag hade inget burk ansjovis men bohusmatjessill i stället blev lagom bra.

A Codec Cookbook

Saturday, November 12th, 2011

With the addition of VBLE decoder I thought once again about codecs and how they are written.

Lossless Video Codecs

There are two approaches:

  • Take a frame, apply one or two general compression schemes to it. Can be zlib, RLE+zlib or motion compensation from previous frame + zlib.
  • Discover spatial prediction (usually from left neighbour or median) and add some coding for residues. HuffYUV, Lagarith, UtVideo, VBLE, LOCO, FFV1, whatever.

Lots of people try it, find that their codec is faster/compresses better than HuffYUV and release results. Usually those codecs don’t live long and the only bad thing about it is they being released to public in the first place.

Lossy Video Codecs

The codecs are usually more complex, so there are less of them. But there are more ways to create one.

  • lossily quantise raw data or DCT output Every self-respecting company producing frame grabbing cards has written such codec.
  • take a draft of some standard codec and base your work on it That’s how we got Window$ Media, R3al and Off2 video codecs.
  • WAVELETS!!!!111oneone
  • another approach to compression like vector quantisation, binary or quad tree decomposition, object-oriented representation (though this one is mostly used in screen capturing codecs), etc.

The main problem with these codecs is achieving good compression parameters without much hassle. For example, libavcodec MPEG-4 encoder may be the best around here but (like Soviet machinery) one has to work real hard to find out which parameters he/she needs to set to which values to get good compression. That’s the reason why people often choose Xvid instead.

Lossless Audio Codecs

There is one approach to those: add lots of crazy filtering (usually several chained filters) and equally crazy coding of residues. There you got it. Simple filters = faster compression, complex filters = slightly better compression with significantly longer compression times.

Last abstract from lossless video codecs applies to audio as well.

Lossy Audio Codecs

Those appear not too often because it’s very hard to satisfy everybody’s ears. Thus (IMO) it’s mostly limited to speech codec development. And there’s Xiph of course.

Why FFmpeg is “better” than Libav by Numbers but not in Reality

Saturday, October 15th, 2011

Time from time there are mails from FFmpeg developers to different distributions saying “Oh, we are better, have more features and more secure, pick us and not libav”. In case somebody wonders here are two examples: Ubuntu and Debian.

So let’s walk through and see the claims. Comparison was made from git snapshots made 2011-10-15 11:00 CEST.

More codecs

FFmpeg claims to have more codecs. In numbers that’s true. Let’s see what are those codecs though:

  • VDPAU accels for MPEG-1 and MPEG-2.
  • AMV encoder. Really just a quick hack to flip picture before using standard JPEG encoding.
  • 8SVX raw audio. Really just a hack to support one particular case of raw planar audio.
  • Flash Screen Video 2 encoder. If you look at the discussion here and the committed file you’ll see that encoder was committed by the same person who had some objections but they never were addressed. Also committing encoder for the codec without any working opensource decoder (well, no decoder beside Adobe Flash client could decode the output properly) is not the brightest idea IMO.
  • CrystalHD MPEG-2, MPEG-4, H.264 and VC-1 support.
  • JPEG-2000 codec. Known to be very buggy and yet included.
  • M$ Video 1 encoder. That was the last review for it – link on gmane and then it was just committed verbatim. Such hypocrisy is one of the reasons I don’t contribute to FFmpeg directly (they pull all patches from libav anyway).
  • DTS encoder. It was considered not to be good enough by the person who was responsible for its development (Benjamin Larsson) but not bad enough to not be included to FFmpeg.
  • G.723.1 codec. The same story.
  • G.729 decoder. It was abandoned halfway by original developer so it’s not complete and buggy.
  • Sonic codec. An experimental codec that was not touched since 2004. It’s not supported by anything and my tests show that it often cannot even compress audio losslessly (output size is bigger than original). That’s why we finally threw it out at libav.
  • Subtitle and text codecs.
  • Stagefright H.264 decoder. It’s too ugly to be included to libav (C++ ABI issues, internal bitstream filter usage).
  • Speex encoder wrapper and Celt encoder wrapper.
  • libaacplus encoder wrapper. It’s based on 3GPP source code and hence not redistributable.

In conclusion, those additional codecs supported by FFmpeg are either hardware acceleration (VDPAU, CrystalHD, stagefright), trivial or some old patches previously rejected but now picked up to maintain impression of superiority.

More muxers and demuxers

Now to muxers and demuxers.

  • ACT and BIT demuxers. Containers for G.729 data.
  • ADF/IDF/bintext/xbin demuxers Containers for text formats.
  • CAF muxer.
  • G.723 demuxer. Container for G.723 data
  • LOAS demuxer. It’s just a hack for probing raw AAC stream.
  • MicroDVD subtitles muxer and demuxer.
  • PMP demuxer.
  • WTV muxer.
  • libmodplug Module tracker file support (libmodplug decodes the files, demuxer outputs decoded raw sound and optional text information).

Most of (de)muxers are either for formats we don’t support or trivial. But I admit there are maybe two demuxers and one muxer that can be included into libav after some cleanup.

Filters

I’m not fully familiar with filter subsystem but it still has too many problems and having an ugly wrapper for MPlayer filters (which are also not of the highest code quality) was one of the points that drove FFmpeg-libav split.

Features, security and overall

When FFmpeg claims to have more features than libav it’s true — they merge everything from libav nowadays. And FFmpeg gets more side features for two reasons: the name is more known and it’s easy to get a feature in because nobody seems to bother with proper reviews nowadays. As for security, it’s the same. For example, when there was a report for some minor security flaw in Chinese AVS decoder, original patch from security investigators (applied in FFmpeg) just made decoder more secure but it still crashed on that file, in libav we created our own patch that dealt with both of these problems. FFmpeg often reminds me of a saying “Socialistic system successfully overcomes the problems it creates itself”.

In conclusion, my opinion is that FFmpeg is trying to compete with libav by lowering standards on accepted stuff. Hence the name of this post.

And I’m glad we can’t have commits like this. For those who have not so good C understanding: it compares addresses of two different strings and it’s an undefined operation that works mostly by luck. So my advise is simple: if you want quality then choose libav, if you want some special features — look for suitable fork at github.