Archive for the ‘Various Video Codecs’ Category

REing another simple codec

Saturday, June 29th, 2024

Since I was bored I tried to (ab)use to search for interesting (i.e. unsupported) samples once again. The main problem is that if it does not decode contents it does not recognize the format. So e.g. AVI files without video track (yes, those files exist) and those using some unrecognized codec will be both marked as aviAudio format, and if audio stream is absent or unknown as well the file gets demoted to unknown.

So I tried to search AVI and MOV files both by extension and by this audio-only type and here are the categories of the results:

  • actual audio-only files (that’s expected);
  • completely different format (there’s an alternative AVI format and MOV is very popular extension as well);
  • improperly extracted files (rather common with MOV on hybrid Macintosh/PC CDs where resource fork often gets ignored);
  • damaged files (happens with some CDs and very common with AOL file library collection—often AVI data starts somewhere in the middle of the file);
  • too old or poorly mastered files (for example, one AVI file lacks padding to 16 bits between chunks; some MOV files can’t be decoded while they look correct);
  • one Escape 130 that could’ve been supported if libavcodec AVI demuxer would not feed garbage to the decoder (it’s not just my demuxer that can handle it, old MPlayer 2 plays it fine with its own demuxer);
  • some TrueMotion 1 files that were not recognised because of tmot FOURCC;
  • files with some special features of the known codecs (I’ve seen some MOV files containing QDraw codec with JPEG frames);
  • files with the codecs I can decode (like IPMA) but the popular software can’t;
  • files with the known codecs (some documented by me) that nobody bothered to implement (especially Motion Pixels 1 and 2);
  • and finally some AVIs with savi FOURCC and a single file with DKRT FOURCC.

Those “SuperAVI” files turned out to be a rebranded Cinepak which I managed to recognise right away, the remaining file turned out to be a bit baffling. After extracting the frames I figured out that it is raw YV12 video, but for some reason it had 64 bytes of soemthing before the image data and 440 bytes after. It can be located on TNG Klingon Language Disc but it does not look like the software there can decode it anyway.

Overall, nothing hard or interesting (if you don’t count the questions about the origins of that file, that is).

A look at an obscure animation system

Tuesday, June 25th, 2024

Since I have nothing better to do, I looked at a thing I’ve encountered. There’s a system developed by some Japanese going by nickname “Y.SAK” that consists of compressed bitmaps (in whatever files) and scripting system using them for displaying animations (that’s .bca files) or even complex scripts (that’s .bac files, don’t confuse them) that may react on mouse, set or test variables and even invoke programs.

Of course the only part I was really interested in were those compressed bitmaps. They have 48-byte header starting with ‘CS‘ and containing author’s copyright, then the header part of DIB file follows (including palette) and finally the compressed data. Apparently there are two supported compression methods—RLE and LZSS. The latter is the familiar code used in many compressors for various things, but RLE is surprisingly interesting. Its opcode contains copy/run flag in the top bit and either 7-bit copy value or 3-bit run length plus 4-bit run value index. Maximum run length/index values mean you need to read the following byte for the real value for each. But that’s not all, note that I wrote “run value index“. There’s a table of possible run values sent before the actual compressed data and that index tells which 4-byte entry from it should be repeated for the run. Nothing revolutionary of course but still a rather curious scheme I don’t remember mentioned anywhere.

And that’s why I keep digging for this old stuff.

Some words on IBM PhotoMotion

Thursday, June 6th, 2024

After a recent rant about search systems I decided to try to find any information about the format (I just happened to recollect that it’s supposed to exist). I don’t know if anybody was lucky but for me the search results were mentions in the list of FOURCCs, some passing references in two papers and that’s all. Now it will probably start returning more results from domain though 😉

So what should we do when a generic search engines fail? Resort to the specialised ones of course. Thanks to the content search feature of I was finally able to locate a CD which uses PhotoMotion technology with both video files and the official player (aptly named P7.EXE, I couldn’t have given it a better name myself). Even better, video files were encoded as both AVI and MM so I could check what output to expect.

Of course Peter’s decoder can’t handle them properly because of the larger header (26 bytes instead of usual 22 or 24 bytes) and uncompressed intra frames. But it was simple to write a simple stand-alone decoder for it to validate that both PhotoMotion and game samples are decoded fine.

This is no major achievement of course but at least it answers a question what that format is all about. So even if there’s still no information about an alleged VfW decoder, now we know what to expect from it.

Looking at random PAF

Thursday, May 16th, 2024

So apparently there’s RIFF-inspired PAF format used in Bi-Fi racing game for DOS (essentially a promotional game for a local brand for sausage-in-a-roll snack).

It’s nothing to write a Multimedia Wiki article about but it’s somewhat interesting. Apparently it has one single CODE chunk that contains commands for updating frame—for all frames. It is pairs of (skip,copy) bytes that tell how many quads of bytes should be skipped on output or updated from the delta frames.

Delta frames are RLE-packed data in DLTA chunks, first 32 bits tell the unpacked data size, then it’s traditional RLE (top bit clear—copy data, top bit set—repeat next byte low seven bits times).

Apparently those files were intended to be used as an animated TV screen overlay on the jukebox background (maybe also for an intro but the CD-rip of the game didn’t have it). So on one hand it’s a mediocre format, on the other it’s somewhat interesting anyway.

Next I should explore the usage of a Duck codec on “iamaduck” console…

Oh No! More Amiga Formats

Sunday, May 12th, 2024

I keep looking at those, no significant progress yet but here’s what I have got so far:

  • ClariSSA—I’ve managed to locate two routines in ssa.library that look like video decompression routines (one is more advanced version of the other SSA with over a hundred of opcodes, another one is a simple RLE) but I still don’t know how they relate to e.g. BEST or COST chunks inside IFF. Update: apparently it separates data like opcodes or plane values into those chunks, I’ll write in more details about it later;
  • DeluxeVideo—haven’t looked at it that closely but it resembles more of an animation system (e.g. Macromedia Flash) than compressed video frames. Update: that’s because it is, the file essentially contains references to the actual sprites and backgrounds plus the commands and effects to apply on them;
  • TheDirector Film—the player for the only known sample uses some LZ-based cruncher but I’m too lazy to spend time on reconstructing the unpacked executable (or mess with UAE let alone unpacking and powering on my expensive door-stopper with AmigaOS 4.1);
  • Magic Lantern Diff—nothing much to say, looks doable. Update: it turned out to be RLE-based and I’m not sure but it might be coding data vertically like Zoetrope did;
  • NTitler—this is essentially a binary script for the program, referring to external resources for everything and such. Not something particularly interesting or fun to look at.

And there you are. After I do what I can with these formats (though as you can see for two of them it’s “not worth looking further” resolution already) I’ll move to something non-Amiga entirely.

Looking at Adorage SSA

Wednesday, May 8th, 2024

So I’m still looking at the list of unsupported video formats from dexvert in hope something curious comes by.

First, out of curiosity, I looked at the unsupported Delphine Software CIN files. Apparently they merely don’t have audio streams and contain garbage in an audio part of the header (plus they have 1-2 video frames). Ignoring the audio header makes them decode. Next.

Second, EA MAD file—apparently it comes from a game rip with audio and video files being dummied out so it’s easier to share. Nothing to look here in any sense. Next.

So, one of SSA formats (no, not that one SSA animation format for Amiga, another one). It turned out to be rather complicated RLE for bit-plane coding. I.e. frames are coded as several bit-planes with the codec commands essentially being something like “skip to this offset in the current bit-plane, then update following 16-bit values with these new values, then skip a bit more and update some more values then skip…”. There are different opcodes for run/copy of certain sizes (or ranges) plus some additional operations for repeating a pair of values (and I thought LinePack was rather unique at that).

I actually ended up hacking a some decoder. It does not seem to handle 8-bit palettes well and there are still some glitches here (just look at the letter ‘D’ in the following image) but in works in principle.

From technical point of view it was not that hard. Even if Ghidra failed to decompile decoder function properly (mostly because of the opcode jumptable) it was nothing hard, even if I don’t know M68k assembly, expressions like move.l (A0)+,(A1)+ are rather intuitive so I could figure out which piece of code, say, copied 18 bytes and which one replicated the same 16-bit value to those 18 bytes.

I’ll try to find something else to look next, there’s still half a dozen of potentially interesting formats in the list.

ARMovie: trying codec wrappers

Tuesday, May 7th, 2024

I’ve managed to locate two ARMovie samples with video format 600 and 602 (which is M$ Video 1 and Cinepak correspondingly), so I got curious if I can decode them. The problem is that ARMovie stores video data clumped together in a large(r) chunks so you need to parse frame somehow in order to determine its length.

Luckily in this case the wrapped codec data has 16-byte header (first 32-bit word is either frame size or a special code for e.g. palette or a skipped frame, followed by some unknown value and real codec width and height) so packetising data was not that hard. The only problem was that Video 1 stream was 156×128 while the container declared it as 160×128 but after editing the header it worked fine.

Supporting such wrappers actually poses more of a question of design for NihAV—how to link those rather container-specific packetisers to a demuxer. Making demuxer parse all possible formats is rather stupid, my current solution of simply registering global packetiser and hoping there’s no need for another is a bit hacky. I should probably make it namespaced so that the code first probes e.g. “armovie/cinepak” packetiser before “cinepak” one but it’s an additional effort for no apparent gain. Speaking of which, I should probably change code to feed the stream provided by the packetiser to a decoder (instead of always using the one from demuxer) but since I’m lazy I’m not going to do that either.

Anyway, I’m not going to spend more time on ARMovie unless new samples for the formats I don’t support show up (beside newer Eidos Escape codecs which are supported elsewhere already). There are other formats left to look at. For example, I’ve made a good progress with Adorage animation format.

Looking at Ace Film

Friday, May 3rd, 2024

This is an old animation format on Acorn computers made by Ace Computing. It exists in several flavours.

There is bare Ace film that has barely any header (mostly just data size, title, some offsets) and chunks which start and end with the chunk size (so that you can seek backwards in the file). Then there’s chunked Ace film where all that data is wrapped into ACEF chunk with some other chunks following it (like RATE, FULL or PALE—the last one is for palette).

Presumably at offset 32 of raw data there is a compression method: 0, 1 or 2 (last one added in EuclidX). 0 means uncompressed data, 1 means LZW and 2 means unpacked data XORed with the previous frame.

Let’s take a closer look at method 1. It looks like a more or less conventional LZW. If the second byte of the stream is zero, the stream contains 16-bit little-endian LZW indices, otherwise it is variable-length LZW with initial index length being 9 bits (and value equal to 256) and growing up (the decoders don’t check upper limit but I suspect it should be around 16 bits). It also uses value 256 to signal the stream end and there are no other reserved values.

Apparently for convenience it decodes indices, stores them in the dictionary (it’s the property of LZW that each new index involves adding a new dictionary entry) and then decodes them backwards. After all, LZW dictionary entries are essentially stored in reverse so either you have to decode an entry, reverse and output it—or you can decode reverse string and output it at the end. This decoder chose the latter implementation (not that you can do it in any other way).

Unfortunately I’ve not managed to reconstruct data properly because of the implementation subtle details but I’m pretty sure anybody knowing how LZW works and willing to spend a bit of time fiddling with the format can come with a working decoder. As for me, it’s not interesting enough to spend more time on it. There are still several more ARMovie codecs to support and other formats to look at.

ARMovie: Moving Blocks done

Tuesday, April 30th, 2024

I’ve finally finished Moving Blocks HQ and REing Super Moving Blocks. The main changes from vanilla Moving Blocks is a larger MV table (vectors can now target as far as 8 pixels instead of previous 4 and the fact that now raw luma samples use delta coding and static Huffman codebook. The only difference between two newer variations is that Super Moving Blocks uses 6-bit luma samples (and larger codebook for handling twice as many possible delta values).

With this part done, all is left is adding support for various Escape codecs as well as raw audio and video formats. And ACEFilm of course, but that’s a separate format.

A quick look at Eidos Escape codecs

Sunday, April 28th, 2024

As people remember, Eidos started as a company offering video editing software for Acorn RISC machines (do not confuse with Acorn RISC Machines company), but later it merged with a game publisher (more than once) and now it’s a Japanese game company. Yet the codecs they developed survived for some time in the games.

Since I was looking at ARMovie and found decompressors for Escape 100 and 102 codecs (essentially the earliest in the series) I looked at those as well and here’s a brief overview.

Both codecs are almost identical in design (only the luma code seems to differ), they operate on 160×128 frames in 5-bit YUV420 format, operating on 2×2 blocks. Chroma values are picked from the table of 256 combined U/V values. The codecs code data as a variable-length code for the number of blocks to skip (the same code seems to have survived until Escape 124) and the following block update mode (luma and/or chroma). As I said before, chroma values are taken from the table or left intact from the previous frame; luma values are coded two 5-bit values and 3-bit mask telling which value to use for the block elements (first element in the block is always the first value of course).

And that’s it. No other modes, the only frame header is 32-bit word with codec ID (later revisions decided to add frame size and even flags that affect decoding process). Nevertheless it’s rather interesting to encounter codecs that use simple two-colour vector quantisation (and fixed codebook for chroma pairs) without any additional image transformation tricks (e.g. motion compensation beside skipping, or even allowing raw blocks).