MPEG-1: An old, but underrated video format for games?

Old formats can sometimes be a plus, so I decided to test.

2025-01-14
Last Update: 2025-01-16
By Ceos_Stock on Pixabay

It’s almost a common knowledge that if a piece of proprietary software exists, there might be an open-source implementation of it. Sometimes what exists instead is an alternative, and maybe an alternative to a file format is some old proprietary format with expired patents.

A well known video format used in games for pre-rendered cutscenes, full motion video, and others is Bink Video by RAD Game Tools . Of course, it’s proprietary, and you have to pay to gain access to its source code and implement it in a game or something.

One day, out of curiosity, I decided to do a search on the internet which was a simple “Bink Video alternative”. One of the first results was Bandicam Video Library , which claimed to be “a faster and cheaper alternative” to Bink. But looking inside, it turned out to be just a library to decode either MPEG-1 or VP8 videos.

This made me remind of pl_mpeg which, guess what, is a single-file C library for decoding MPEG-1 videos. I knew it existed for a long time, but I took the fact that it was meant for a very outdated format too seriously and wasn’t interested in working with it until recently, when I decided to read the creator’s article where we can see a positive opinion.

Testing

Curiosity struck, and then I decided to do some encoding tests like I did a few years ago with Theora, the only video format supported by the Godot Engine at the time of this writing. Those tests led me to find encoding parameters to ensure the best possible quality/size ratio. The verdict was quite simple: use the latest reference encoder (not easy to find and use) at the lowest speed setting, and a balanced quality value.

But for MPEG-1 it was slightly more complicated. There’s no free encoders out there other than the one in FFmpeg itself. And compared to Theora, there were much more settings.

Let’s take this video from Pixabay which covers a few considerable video characteristics. This article’s cover image is literally a frame taken from it. I went a bit further and downgraded the video to 24 FPS:

As I wouldn’t self host a high quality video here, all examples in this article will have a bit of AV1 artifacts, but the difference between them will be mostly MPEG-1’s fault.

Now, let’s see the result of a plain ffmpeg -i input_video output_video.mpg, which is what most people will judge MPEG-1 is (2.9MB):

Assuming you’re watching these examples at full screen, and have a good quality audio device, one might notice that the result is quite awful when we expect it to be transparent.

Solving the audio issue is easy: just specify the libtwolame audio encoder. By default, FFmpeg will use the experimental mp2 encoder, which degrades the audio quality even at very high bit rates. With libtwolame, however, you may even decrease the default bit rate from 384k to 224k and not notice anything wrong with the audio.

Explaining the solution I found for the video quality would be quite complicated, so I’ll just leave the final pseudo-command below:

ffmpeg -i input_video -c:v mpeg1video -b:v 1500k -g:v <twice the video frame rate> -b_strategy 2 -b_sensitivity 1 -brd_scale 3, -mpv_flags +qp_rd+naq+mv0 -mbd 2 -quantizer_noise_shaping 1000 -qsquish 99 -motion_est 2 -pass 1 -fps_mode cfr -f null /dev/null

ffmpeg -i input_video -c:v mpeg1video -b:v 1500k -g:v <twice the video frame rate> -b_strategy 2 -b_sensitivity 1 -brd_scale 3, -mpv_flags +qp_rd+naq+mv0 -mbd 2 -quantizer_noise_shaping 1000 -qsquish 99 -motion_est 2 -pass 2 -c:a libtwolame -b:a 224k output_video.mpg

Among the changes, we are specifying both bit rates, using two passes and overriding a lot of options. This will inevitably slow down the encoding, but the result will be considerably better than a plain FFmpeg command. I might have missed some options, but the ones above made the biggest difference. Some were even avoided because they were worsening the result.

I manipulated the bit rate a bit so the resulting video would be slightly smaller than the one above (2.7MB), but hey, the result is much better:

While the static effect at the very beginning looks quite worse, I think it’s a good tradeoff. Moreover, you can just increase the bit rate a bit to improve the result.

If we encode into Theora using a balanced quality value, we will get a result around 4.8MB. I encoded one last example with the bit rate increased to 2800k, which resulted into the following 4.7MB video:

Concerns and conclusion

I found a few issues and limitations while running the encoding tests. If you use a too low bit rate value, the encoder will simply throw a “bit rate is too low” error and encode nothing. And if it’s too high, you’ll likely get broken artifacts. I couldn’t find a way to use constant quality (-q:v) and have a consistent result between different video files, but two-pass variable bit rate already works pretty well.

Is MPEG-1 a good video format for games and a good alternative to Bink? Maybe. I’m not some big name of the game industry (heck, I don’t even have games I’ve made money off), but my personal answer for that question would be totally yes, as long as you use it correctly and given how cheap it is to decode. With my mid-range CPU, the speed it took to decode a 34-second 1080p 24 FPS video would be enough to decode two hours of video in less than a second. Twice as fast as Theora.

This opinion is valid at least for Bink 1, as it can’t compete with Bink 2, which has features that are unavailable in MPEG-1. However, if all you want is some cheap FMV with no alpha channel, MPEG-1 should be more than enough.