|
2 | 2 | title: Jo_MPEG converted to C |
3 | 3 | permalink: "/{{ page.fileSlug }}/" |
4 | 4 | date: 2022-02-18 |
5 | | -last_modified: |
| 5 | +last_modified: 2024-08-15 |
6 | 6 | description: Single-header MPEG-1 Video library ported to C |
7 | 7 | publicTags: |
8 | 8 | - C++ |
9 | 9 | - C |
10 | 10 | - video |
11 | 11 | image: jo_mpeg.png |
12 | 12 | --- |
13 | | -jo_mpeg is a C++ [single header library](https://github.com/nothings/single_file_libs) written by [Jon Olick](https://www.jonolick.com/home/mpeg-video-writer), which creates MPEG-1 videos (without audio). It is [listed as a C++ only library](https://github.com/nothings/single_file_libs#video) in stb's single header library collection. However, only the & reference format is what makes this library C++ only. Replacing those with simple pointers makes this compile with both C and C++: [jo_mpeg.h](jo_mpeg.h) |
14 | | - |
15 | | -( I also found this: https://github.com/yui0/slibs/blob/master/jo_mpeg.h, but it is one version behind. ) |
| 13 | +jo_mpeg is a C++ [single header library](https://github.com/nothings/single_file_libs) written by [Jon Olick](https://www.jonolick.com/home/mpeg-video-writer), which creates MPEG-1 videos (without audio). It is [listed as a C++ only library](https://github.com/nothings/single_file_libs#video) in stb's single header library collection. However, only the & reference format is what makes this library C++ only. Replacing those with simple pointers makes this compile with both C and C++. |
16 | 14 |
|
17 | 15 | <details> |
18 | 16 | <summary>Full source of the C compatible <a href="jo_mpeg.h">jo_mpeg.h</a></summary> |
19 | 17 |
|
20 | 18 | ```c |
21 | 19 | {% rawFile "posts/jo-mpeg-in-c/jo_mpeg.h" %} |
22 | 20 | ``` |
23 | | -</details> |
| 21 | +</details> |
| 22 | +
|
| 23 | +## Results |
| 24 | +I encoded a couple of seconds from [Big Buck Bunny](https://peach.blender.org/) as a sample: [sample.mpg](sample.mpg). |
| 25 | +
|
| 26 | +<blockquote class="reaction"><div class="reaction_text">Can't show it directly in browser, as MPEG1 is not supported anymore. Also there is <a href="https://jsmpeg.com/">jsmpeg</a>, but it also doesn't support this output.</div><img class="kiwi" src="/assets/kiwis/facepalm.svg"></blockquote> |
| 27 | +
|
| 28 | +<figure> |
| 29 | + <img src="comparison.png" alt="Input frame vs Output frame. Side effect of conversion: Increased saturation and contrast." /> |
| 30 | + <figcaption>Input frame vs Output frame. Side effect of conversion: Increased saturation and contrast.</figcaption> |
| 31 | +</figure> |
| 32 | +
|
| 33 | +Unfortunately, the output has increased saturation and contrast. This is due to RGB -> [YCbCr](https://en.wikipedia.org/wiki/YCbCr#RGB_conversion) conversion in line `230` - `232` scaling the final color vectors scaled too much. I fixed this by reverting the color space math changes that happened with the update to `v1.02`. |
| 34 | +
|
| 35 | +<figure> |
| 36 | + <img src="comparisonNew.png" alt="Input frame vs Output frame. Reverted to old color math." /> |
| 37 | + <figcaption>Input frame vs Output frame. Reverted to old color math.</figcaption> |
| 38 | +</figure> |
| 39 | +
|
| 40 | +I'm not sure why the code change credited to `r- lyeh` happened, but I guess the used video player handled color space incorrectly. Both [VLC](https://www.videolan.org/) and [MPV](https://mpv.io/) playback the colors correctly with `v1.03`. |
| 41 | +
|
| 42 | +Quality is hardcoded and results in roughly `8mbps` at a resolution of `684x385`. Quality measurements are at roughly `27db` [PSNR](https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio#Quality_estimation_with_PSNR) and `0.9` [SSIM](https://medium.com/srm-mic/all-about-structural-similarity-index-ssim-theory-code-in-pytorch-6551b455541e)... |
| 43 | +
|
| 44 | +<figure> |
| 45 | + <video width="684" height="342" controls><source src="not-terrible.mp4" type="video/mp4"></video> |
| 46 | + <figcaption>...Or in other words</figcaption> |
| 47 | +</figure> |
0 commit comments