Category Archives: General

Creating A Lossless SMC Encoder

Look, I can’t explain how or why I come up with this stuff. For some reason, I thought it would be interesting to write a new encoder for the Apple SMC video codec. I can’t even remember why. I just sat down the other day, started writing, and now I have a lossless SMC encoder that I’m not sure what to do with. Maybe this is to be my new thing— writing encoders for marginal multimedia formats.

Introduction
SMC is a vector quantizer (a lossy method) but I decided to attack it from the angle of lossless encoding. A.k.a. Apple Graphics Codec, SMC operates on 4×4 blocks in an 8-bit paletted colorspace. Each 4×4 block can be encoded with 1, 2, 4, 8, or 16 colors. Blocks can also be skipped (copied from previous frame) or copied from blocks rendered immediately prior within the same frame.

Step 1: Validating Infrastructure
The goal of this step is to encode the most braindead SMC frame possible and see if FFmpeg/libav’s QuickTime muxer can create a valid file. I think the simplest frame would be one in which each vector is encoded with the single-color mode, starting with color 0 and incrementing through the palette.

Status: Successful. The only ‘trick’ was to set avctx->bits_per_coded_sample to 8. (For fun, this can also be set to 40 (8 | 0x20) to specify a grayscale palette.)



Step 2: Preprocessing
The video frames will arrive at the encoder as 32-bit RGB. These will need to be converted to a paletted colorspace before encoding. I don’t want to use FFmpeg’s default dithering approach as this will result in a substantial loss of quality as described in this post. I would rather maintain a palette built from observed colors throughout successive frames. If the total number of unique observed colors ever exceeds 256, error out.

That’s what I would like to do. However, I noticed that FFmpeg/libav’s QuickTime muxer has never taken into account the possibility of encoding palettes. The path of least resistance in this case is to dither the input to match QuickTime’s default 8-bit palette (if a paletted QuickTime file does not specify a palette, a default 1-, 2-, 4-, or 8-bit palette is selected).

Status: Successful, if slow. I definitely need to optimize this step later.

Step 3: Most Naive Encoding
The most basic encoding is to “encode” each block as a 16-color block. This will actually result in a slightly larger frame size than a raw encoding since each 4×4 block will be prepended by a byte opcode (0xE0 in this case) to indicate encoding mode. This should demonstrate that the encoder is functioning at the most basic level.

Status: Successful. Try not to laugh too hard at the Big Buck Bunny dithered to an 8-bit palette:



Step 4: Better Representation Continue reading

Removing GRUB

I have a Windows/Linux dual-booting computer that I don’t want to be dual boot anymore– the Linux part needs to go. Thus, the GRUB bootloader needs to be removed so that Windows boots normally. I found lots of tips around the internet about how to do this. Of course, none of them worked. So I must add to the general body of knowledge.

I found tips that described how to manually remove GRUB via Linux– by using 'dd' to overwrite no more than 446 sectors of the boot disk with zeros. This strikes me as a dangerous and unstable proposition. It also wasn’t an option since I had already opted to reformat the formerly Linux partition via the Windows CD-ROM before I endeavored to remove the bootloader.

Other forums and sites mentioned a combination of utilities found on the Windows CD-ROM including FIXBOOT, FIXMBR, and BOOTCFG. While these programs performed some functions, they didn’t achieve the desired effect– to make Windows boot automatically.

New idea: Repartition the disk such that there is a (relatively) tiny extra partition. Then, well… reinstall Linux. I used a 4 GB partition and Ubuntu 10.10 and let it run its course which ended with installing GRUB… again.

Seems roundabout– installing Linux specifically to boot into Windows. But it works.

Google’s YouTube Uses FFmpeg

Controversy arose last week when Google accused Microsoft of stealing search engine results for their Bing search engine. It was a pretty novel sting operation and Google did a good job of visually illustrating their side of the story on their official blog.

This reminds me of the fact that Google’s YouTube video hosting site uses FFmpeg for converting videos. Not that this is in the same league as the search engine shenanigans (it’s perfectly legit to use FFmpeg in this capacity, but to my knowledge, Google/YouTube has never confirmed FFmpeg usage), but I thought I would revisit this item and illustrate it with screenshots. This is not new information– I first empirically tested this fact 4 years ago. However, a lot of people wonder how exactly I can identify FFmpeg on the backend when I claim that I’ve written code that helps power YouTube.

Short Answer
How do I know YouTube uses FFmpeg to convert multimedia? Because:

  1. FFmpeg can decode a number of impossibly obscure multimedia formats using code I wrote
  2. YouTube can transcode many of the same formats
  3. I screwed up when I wrote the code to support some of these weird formats
  4. My mistakes are still present when YouTube transcodes certain fringe formats

Longer Answer (With Pictures!)
Let’s take a video format named RoQ, developed by noted game designer Graeme Devine. Originated for use in the FMV-heavy game The 11th Hour, the format eventually found its way into the Quake 3 engine as well as many games derived from the same technology.

Dr. Tim Ferguson reverse engineered the format (though it would later be open sourced along with the rest of the Q3 engine). I wrote a RoQ playback system for FFmpeg, and I messed up in doing so. I believe my coding error helps demonstrate the case I’m trying to make here.

Observe what happened when I pushed the jk02.roq sample through YouTube in my original experiment 4 years ago:



Do you see how the canyon walls bleed into the sky? That’s not supposed to happen. FFmpeg doesn’t do that anymore but I was able to go back into the source code history to find when it did do that:



Academic Answer
FFmpeg fixed this bug in June of 2007 (thanks to Eric Lasota). The problem had to do with premature colorspace conversion in my original decoder.

Leftovers
I tried uploading the video again to see if the problem persists in YouTube’s transcoder. First bit of trivia: YouTube detects when you have uploaded the same video twice and rejects the subsequent attempts. So I created a double concatenation of the video and uploaded it. The problem is gone, illustrating that the backend is actually using a newer version of FFmpeg. This surprises me for somewhat esoteric reasons.

Here’s another interesting bit of trivia for those who don’t do a lot of YouTube uploading– YouTube reports format details when you upload a video:



So, yep, RoQ format. And you can wager that this will prompt me to go back through the litany of unusual formats that FFmpeg supports to see how YouTube responds.