Breaking Eggs And Making Omelettes

Topics On Multimedia Technology and Reverse Engineering


Archives:

Giving Thanks For VP8

November 25th, 2010 by Multimedia Mike

It’s the Thanksgiving holiday here in the United States. I guess that’s as good a reason as any to release a first cut of my VP8 encoder. In order to remind people that they shouldn’t expect phenomenal quality from it — and to discourage inexperienced people from trying to create useful videos with it — I have hardcoded the quantizers to their maximum settings. For those not skilled in the art, this is the setting that yields maximum compression and worst quality. When compressing the Big Buck Bunny logo image, the resulting file is only 2839 bytes but observe the reconstructed quality:



It really just looks like a particularly stormy day in the forest.

First VP8 File From An Independent Encoder
I found a happy medium on the quantizer scale and encoded the first 30 seconds of Big Buck Bunny for your inspection. I guess this makes it the first VP8/WebM file from an independent encoder (using FFmpeg’s Matroska muxer as well).

Download: bbb-360p-30sec-q40.webm (~13 MBytes)

I think the quality makes it look like it was digitized from an old VHS tape.

For fun, here’s the version with the quantizer cranked to the max: bbb-360p-30sec-q127.webm (~1.3 MBytes)

Aside: I was going to encapsulate the video in this post using a bare HTML5 <video> tag for the benefit of the small browsing population who could view that (indeed, it works fine in Chrome). But that would be insane due to the fact that supporting browsers preload the video with no easy (read: without the help of JavaScript) method for overriding this unacceptable default.

The Code
I’m still trying to get over my fear of git. To that end, I have posted the code on Github:

https://github.com/multimediamike/ffvp8enc

I still don’t like you, git. But I’m sure we’ll find some way to make this work.

Other required code changes in the basic FFmpeg tree:

  • Of course, copy vp8enc.c into libavcodec/
  • In libavcodec/allcodecs.c, ‘REGISTER_DECODER (VP8, vp8);‘ turns into ‘REGISTER_ENCDEC (VP8, vp8);
  • Add ‘OBJS-$(CONFIG_VP8_ENCODER) += vp8enc.o‘ to libavcodec/Makefile

Further Work
About the limitations and work yet to do:

  • it’s still intra-only, no interframes (which is where a lot of compression occurs)
  • no rate control or distortion optimization, obviously
  • no intra 4×4 coding (that’s close to working but didn’t my little T-day deadline)
  • no quantization control; this should really be hooked up to the FFmpeg command line but I’m not sure how
  • encoder writes into a static-sized, 1/2 MB memory buffer; this can overflow
  • code is a mess (what did you expect at this stage of the game?)
  • lots and lots of other things, surely

Posted in VP8 | 9 Comments »

9 Responses

  1. Marcoen Says:

    Great work mike!

    I also want to thank you for the dinner we had after the GSoC mentor summit more than a year ago :)

  2. Kostya Says:

    VP8 is done, time to finish that Xan WC4 decoder!
    Or there’s still one TrueMotion 2 flavour left to RE.

  3. Bec Says:

    > But that would be insane due to the fact that supporting browsers preload the video with no easy (read: without the help of JavaScript) method for overriding this unacceptable default.

    Well… The intent is there: shouldn’t hit the server at all, and “meta” should only fetch the first frame or so to get the length and dimensions (you can set them manually to avoid resize-on-play).

    Then again, Chrome didn’t get the memo yet (http://code.google.com/p/chromium/issues/detail?id=16482). So yeah, better wait for a little while. Firefox 4 should work fine though.

  4. Bec Says:

    I knew I was going to get owned. Let’s try putting some zero-width spaces to fool the filter. Don’t copy&paste this.

    

  5. Bec Says:

    I give up. Read https://developer.mozilla.org/En/HTML/Element/Video (in particular the “preload” attribute.)

  6. willus Says:

    Thanks, Mike. Nice work, and very useful to examine the source.

  7. Michael Sabin Says:

    Thanks for publishing your efforts to write a video encoder! I’ve been trying to do the same thing for the PlayStation 1 videos. A brute force method is working (keep increasing the qscale until the bitstream fits in the space allowed for the frame), but I really want to do more, such as:

    * Temporal spreading (diffusion?) of quantization error
    * Shorter VLC substitution searching
    * Trellis quantization (h.264 only?)
    * Context-adaptive variable-length coding (h.264 only?)

    Unfortunately I’ve found next to nothing on such advanced topics anywhere, and I have no idea who to ask.

  8. Multimedia Mike Says:

    @Michael: Good luck to you with your encoding efforts as well. Unfortunately (or, perhaps, fortunately, depending on how you learn), the best knowledge in this domain is likely wrapped up in the source code for FFmpeg, x264, and other open source multimedia programs. I have a feeling I’m going to have to raid those codebases eventually to figure out how to take this VP8 encoder farther.

  9. follower Says:

    FWIW I got Chrome to play the file off disk okay but for me VLC 1.1.5 wouldn’t play it–no error messages just something in the log about “nothing to play”.

    Also, if your issue is specifically with git rather than DVCS in general I’ve used the hggit Mercurial plugin with GitHub successfully.