Looking at Voyeur II videos

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

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

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

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 vp7.de

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.

VP7 encoder: various bits

February 27th, 2022

As the world tries to avert attention from an insane dictator re-enacting 1939 (it gets funnier since I observe it from Germany), I should also do something to take my mind off constant worrying about my parents and other relatives in one of the Ukrainian cities under attack. Hence this significantly less unpleasant thing.

Now my encoder is conceptually done, all that is left to do is to fix a leftover bug or two, improve a thing of two, clean the code up and integrate it nicely with the rest of nihav-duck crate by splitting off common parts with VP6 encoder. Meanwhile I can talk about some things implemented since the last time and what wasn’t.
Read the rest of this entry »

The Prayer

February 24th, 2022

I do not like to state my political views publicly but sadly this is the right occasion.

I’m not a religious man so I know only just one prayer, the main Ukrainian prayer:

Дякую тобі, Боже, що я не москаль.

(translation: “thank you, God, that I’m not a Russian”). We live in a sad world where I’m really grateful for that.

The problem with opensource encoders

February 20th, 2022

Disclaimer: this post is about the general situation with existing (and even more, with non-existing) opensource encoders (for both audio and video) and not about the flaws in those encoders.

When I was developing my toy(ish) VP6 encoder, I got questions about it and general encoding technologies from many people (as in “one, two, many” but still it’s above the expected amount of zero). And then I remembered the reasons why there was no opensource VP6 encoder before I wrote one.

The main problem with opensource encoders is the shortage of talented people and the lack of environment to grow more of them. As the result, those who know how to write or tune encoders keep doing that or move to some other stuff (nowadays most of them who are remaining active seem to be sucked into rav1e and those who don’t know how to write encoders have very hard time learning how it should be done.
Read the rest of this entry »

Basic VP7 encoder: cutting corners

February 17th, 2022

I’ve more or less completed a basic failure of VP7 encoder. Now it can encode inter-frames using various size of motion compensation (and the resulting file can be decoded too!). There’s still a lot of work to be done (rate control, MB features and multiple frame analysis) but there are some things that I can talk about as well.

As I wrote in the previous post, there are too many coding parameters to try so if you want to have a reasonable encoding done in reasonable time you need to cut corners (or “employ heuristics” if you want to sound more scientific) in various ways. So here I want to present what has been done in my decoder to make it run fast.
Read the rest of this entry »

Looking at Zig programming language

February 5th, 2022

Back when I wrote my rant about C++ and its bad influence on C (yeah, about three quarters of year ago) I got recommendations to look at Zig and finally decided to download 0.9.0 release and play it. Long story short: it’s an interesting language with some good ideas but not the one I’d use.
Read the rest of this entry »

VP7 encoding: general principles

January 30th, 2022

It is not that hard to write a simple encoder (as I’m going to demonstrate), the problem is to make it good (and that’s where I’ll fail). Until that time I’m going to explain what I’m doing and how/why it should be done.
Read the rest of this entry »