Archive for March, 2022

Looking at Voyeur II videos

Saturday, March 26th, 2022

Here’s a result of another attempt to distract myself from the thoughts whether Ukraine will kick out the invaders in a steady manner or if the führer will resort to chemical or nuclear weapons.

So I decided to take a look at random FMV game and Voyeur II came to my attention. From what I know the first instalment uses RL2 videos and is supported by ScummVM. The second game, however, uses a completely different format and packs most of the data into few volumes (80% of the data on CD is in single diskN.vol and the rest of the data is mostly in endings.vol and slides.vol).

Those volume files turned out to be archives as expected, and the content of those archives turned out to be kinda archives too.

The data stored in volume files is bits of video usually one or two seconds long but the way they’re stored is somewhat peculiar. The header defines (always?) four streams, two of which are dummy ones and the other two are audio and video correspondingly (and they can turn up in any order). The rest of the file is a collection of blocks with 8-byte header defining block size and to which stream it belongs to—and yes, blocks for different streams may be interleaved. Audio stream seems to be plain PCM and video stream is a sequence of frames (thankfully, 14-byte frame header contains packed frame size).

So, what about video compression? It’s RLE with a small twist: there are intra- and inter-frame RLE variants and they can use double-pixel mode (i.e. where you skip or fill the doubled amount of pixels and for raw pixel data each pixel is repeated twice on output). Inter-frame RLE compression has skip codes (i.e. at first you read how many pixels you need to skip, then you read either raw pixels to update the frame with or RLE data depending on opcode, and then you read next skip code and repeat it until the end of frame). Additionally it seems the video is always 320×160 and only video height is stored in the files.

All in all, the most interesting part there turned out to be the logical organisation of data and not the RLE compression or actual videos (I checked random couple of dozens of samples from over two thousands total videos and nothing piqued my interest). Maybe I’ll find something more interesting next time.

Revisiting legendary video format

Tuesday, March 22nd, 2022

So Ukraine is still holding against self-proclaimed second army of the world (though by this time it has earned the title of the most atrocious and hateful military force in the world, the title that had to be taken from the SS troops). And while I can’t stop worrying about my relatives, home city and home country in general, I still need something to distract me at least for a while.

While watching some video about video games, I spotted something surprising in it: a cutscene in Callahan’s Crosstime Saloon. While I worked on supporting Q video format in Legend Entertainment games I remember seeing just one video from that game (the animated title). So I tracked a full CD version of the game and discovered some surprising things about it.

First of all, it turned out to be version 7 of the format (and I’ve seen only versions 3-5 before). Second, it turned out to be mostly the same as version 5 but with F8 opcode in use. This opcode turned out to be used for compact representation of the colours where a code either introduces a cache of up to 15 colours or reuses some previous table and then tile colours are stored in a nibble. Third, beside cutscenes there are a couple of videos of some lady with a small child that look like a home video sneaked in by some developer.

There’s still a lot of work to be done to support it properly (because of the various quirks of the format) but I’ve managed to decode all of the videos from the game already, some of them even without artefacts. This is a pointless but fun distraction after all.

vp6enc: slightly faster encoding mode

Saturday, March 12th, 2022

As I mentioned before, I wanted to try to apply the macroblock selection approach from VP7 encoder in VP6 encoder. Well, it was easy to implement: instead of preparing all macroblock modes and then trying which is the best one now it tries macroblock modes (starting with inter mode now) and stops when the result is good enough. In this mode encoding seems to go couple percent faster and the resulting size at the same quantiser can differ somewhat in both directions. You can try it yourself by using fast encoder option.

The encoder is still a failure though.

VP7 encoder release

Thursday, March 3rd, 2022

While a certain country cosplays the Third Reich and conducts talvisota simultaneously—and tries to bomb my home city to debris, I still need some distraction…

borrowed from

Since I’m rather bored with VP7 encoder I’ve decided to release it and move to something else. It should work about the same as VP6 encoder (i.e. poorly and nobody should care about it) but if you want to know what knobs you can turn just invoke nihav-encoder --query-encoder-options vp7 (but I guess the only useful options are to set bitrate/quantiser and keyframe interval).

Have fun!

Update from March 4: encoding with low quantisers should now work as well.