Breaking Eggs And Making Omelettes

A blog dealing with technical multimedia matters, binary reverse engineering, and the occasional video game hacking.

http://multimedia.cx/eggs/

Les articles publiés sur le site

  • libvpx 0.9.1 and FFmpeg 0.6

    18 juin 2010, par Multimedia MikeVP8

    Great news: Hot on the heels of FFmpeg's 0.6 release, the WebM project released version 0.9.1 of their libvpx. I can finally obsolete my last set of instructions on getting FFmpeg-svn working with libvpx 0.9.

    Building libvpx 0.9.1
    Do this to build libvpx 0.9.1 on Unix-like systems:

    libvpx's build system has been firmed up a bit since version 0.9. It's now smart enough to install when said target is invoked and it also builds the assembly language optimizations. Be advised that on 32- and 64-bit x86 machines, Yasm must be present (install either from source or through your package manager).

    Building FFmpeg 0.6
    To build the newly-released FFmpeg 0.6:

    • Install Vorbis through your package manager if you care to encode WebM files with audio; e.g., 'libvorbis-dev' is the package you want on Ubuntu
    • Download FFmpeg 0.6 from the project's download page
    • Configure FFmpeg with at least these options: ./configure --enable-libvpx --enable-libvorbis --enable-pthreads; the final link step still seems to fail on Linux if the pthreads option is disabled
    • 'make'

    Verifying
    Check this out:

    $ ./ffmpeg -formats 2> /dev/null | grep WebM
      E webm            WebM file format
    
    $ ./ffmpeg -codecs 2> /dev/null | grep libvpx
     DEV    libvpx          libvpx VP8
    

    That means that this FFmpeg binary can mux a WebM file and can both decode and encode VP8 video via libvpx. If you're wondering why the WebM format does not list a 'D' indicating the ability to demux a WebM file, that's because demuxing WebM is handled by the general Matroska demuxer.

    Doing Work
    Encode a WebM file:

    ffmpeg -i <input_file> <output_file.webm>

    FFmpeg just does the right thing when it seems that .webm extension on the output file. It's almost magical.

    For instant gratification that the encoded file is valid, you can view it immediately using 'ffplay', if that binary was built (done by default if the right support libraries are present). If ffplay is not present, you can always execute this command line to see some decode operation:

    ffmpeg -i <output_file.webm> -f framecrc -

  • VP8 And FFmpeg

    18 juin 2010, par Multimedia MikeVP8

    UPDATE, 2010-06-17: You don't need to struggle through these instructions anymore. libvpx 0.9.1 and FFmpeg 0.6 work together much better. Please see this post for simple instructions on getting up and running quickly.

    Let's take the VP8 source code (in Google's new libvpx library) for a spin; get it to compile and hook it up to FFmpeg. I am hesitant to publish specific instructions for building in the somewhat hackish manner available on day 1 (download FFmpeg at a certain revision and apply a patch) since that kind of post has a tendency to rise in Google rankings. I will just need to remember to update this post after the library patches are applied to the official FFmpeg tree.

    Statement of libvpx's Relationship to FFmpeg
    I don't necessarily speak officially for FFmpeg. But I've been with the project long enough to explain how certain things work.

    Certainly, some may wonder if FFmpeg will incorporate Google's newly open sourced libvpx library into FFmpeg. In the near term, FFmpeg will support encoding and decoding VP8 via external library as it does with a number of other libraries (most popularly, libx264). FFmpeg will not adopt the code for its own codebase, even if the license may allow it. That just isn't how the FFmpeg crew rolls.

    In the longer term, expect the FFmpeg project to develop an independent, interoperable implementation of the VP8 decoder. Sometime after that, there may also be an independent VP8 encoder as well.

    Building libvpx
    Download and build libvpx. This is a basic 'configure && make' process. The build process creates a static library, a bunch of header files, and 14 utilities. A bunch of these utilities operate on a file format called IVF which is apparently a simple transport method for VP8. I have recorded the file format on the wiki.

    We could use a decoder for this in the FFmpeg code base for testing VP8 in the future. Who's game? Just as I was proofreading this post, I saw that David Conrad has sent an IVF demuxer to the ffmpeg-devel list.

    There doesn't seem to be a 'make install' step for the library. Instead, go into the overly long directory (on my system, this is generated as vpx-vp8-nopost-nodocs-generic-gnu-v0.9.0), copy the contents of include/ to /usr/local/include and the static library in lib/ to /usr/local/lib .

    Building FFmpeg with libvpx
    Download FFmpeg source code at the revision specified or take your chances with the latest version (as I did). Download and apply provided patches. This part hurts since there is one diff per file. Most of them applied for me.

    Configure FFmpeg with 'configure --enable-libvpx_vp8 --enable-pthreads'. Ideally, this should yield no complaints and 'libvpx_vp8' should show up in the enabled decoders and encoders sections. The library apparently relies on threading which is why '--enable-pthreads' is necessary. After I did this, I was able to create a new webm/VP8/Vorbis file simply with:

     ffmpeg -i input_file output_file.webm
    

    Unfortunately, I can't complete the round trip as decoding doesn't seem to work. Passing the generated .webm file back into FFmpeg results in a bunch of errors of this format:

    [libvpx_vp8 @ 0x8c4ab20]v0.9.0
    [libvpx_vp8 @ 0x8c4ab20]Failed to initialize decoder: Codec does not implement requested capability
    

    Maybe this is the FFmpeg revision mismatch biting me.

    FFmpeg Presets
    FFmpeg features support for preset files which contain collections of tuning options to be loaded into the program. Google provided some presets along with their FFmpeg patches:

    • 1080p50
    • 1080p
    • 360p
    • 720p50
    • 720p

    To invoke one of these (assuming the program has been installed via 'make install' so that the presets are in the right place):

     ffmpeg -i input_file -vcodec libvpx_vp8 -vpre 720p output_file.webm
    

    This will use a set of parameters that are known to do well when encoding a 720p video.

    Code Paths
    One of goals with this post was to visualize a call graph after I got the decoder hooked up to FFmpeg. Fortunately, this recon is greatly simplified by libvpx's simple_decoder utility. Steps:

    • Build libvpx with --enable-gprof
    • Run simple_decoder on an IVF file
    • Get the pl_from_gprof.pl and dot_from_pl.pl scripts frome Graphviz's gprof filters
    • gprof simple_decoder | ./pl_from_gprof.pl | ./dot_from_pl.pl > 001.dot
    • Remove the 2 [graph] and 1 [node] modifiers from the dot file (they only make the resulting graph very hard to read)
    • dot -Tpng 001.dot > 001.png

    Here are call graphs generated from decoding test vectors 001 and 017.


    Like this, only much larger and scarier (click for full graph)


    It's funny to see several functions calling an empty bubble. Probably nothing to worry about. More interesting is the fact that a lot of function_c() functions are called. The '_c' at the end is important-- that generally indicates that there are (or could be) SIMD-optimized versions. I know this codebase has plenty of assembly. All of the x86 ASM files appear to be written such that they could be compiled with NASM.

    Leftovers
    One interesting item in the code was vpx_scale/leapster. Is this in reference to the Leapster handheld educational gaming unit? Based on this item from 2005 (archive.org copy), some Leapster titles probably used VP6. This reminds me of finding references to the PlayStation in Duck/On2's original VpVision source release. I don't know of any PlayStation games that used Duck's original codecs but with thousands to choose from, it's possible that we may find a few some day.

  • FFmpeg 0.6 ; Something About HTML5

    17 juin 2010, par Multimedia MikeOpen Source Multimedia

    The FFmpeg project made a formal release yesterday. You can download version 0.6 from the project's download page.

    I've actually been seeing more news items about this today than I would have expected. This is most likely because the 0.6 release is named "Works with HTML5". Let it never be said that nerds don't know marketing. The team really latched on to the hottest buzzword going right now.

    The name of the release refers to FFmpeg's new native support for Google's WebM format. It can mux and demux the WebM container, and decode the Vorbis audio, all natively (FFmpeg's Vorbis encoder has been demoted to "experimental" for this release and it is recommended to enable libvorbis for encoding). But the big news is that this release can support Google's libvpx natively for VP8 encoding and decoding, without having to apply any other patches.

    Getting libvpx to compile still might be a bit tricky. Fortunately, the first pass of a native, independent VP8 decoder is currently in review on the ffmpeg-devel list.

  • Revised FATE Test Spec System

    9 juin 2010, par Multimedia MikeFATE Server

    FATE involves some database tables that define the test specifications. Like everything else in FATE, the concept could use some improvement. After I prototyped an improved, multithreaded testing client, the next logical revision seemed to be the test spec system.

    History
    The test spec system has been handled by a single table that includes an FFmpeg command line (with a few possible modifiers thrown in), an integer ID, a human-friendly ID, a description, the expected command line return code, the expected command output, a maximum runtime, and a Boolean to indicate whether the test is to be considered active.

    Adjunct to this test database is a large corpus of test media named the FATE suite.

    At first, the FATE testing script used a direct MySQL database protocol to query the test specs from the server before every build/test cycle. I soon realized this was ludicrously inefficient since the test specs don't change that often. So I cached the tests in a static file to be retrieved via HTTP, first in Python's "pickled" (serialized) format, then in an SQLite database.

    Planned Upgrades
    There are 2 major features I would like to build into the system going forward:

    1. The ability to version the entire suite so that it's possible to test old branches of FFmpeg
    2. Another database field to indicate which, if any, other test specs must be executed before this spec can be executed

    I think I will take this opportunity to switch the test cache serialization format to JSON. I switched from Python pickling to SQLite because the latter was more portable between languages. JSON has that same benefit. Further, working with JSON data doesn't require a round trip to disk (i.e., want to generate an SQLite database for sending via HTTP? It needs to go onto disk first. It's possible to create and manipulate a database entirely in memory but not fetch the bits).

    Things To Research

    • Pondering how version control systems operate and what they have to teach regarding how to version this data (including the question of whether I can just use an existing version control mechanism instead of creating my own system)
    • Efficient caching mechanism
    • Tagging test specs for alternate purposes such as longevity testing
    • Learn about web form programming in the 21st century so that it's not quite as painful to maintain the system.

    Preliminary Versioning Concept
    Here is one approach I am thinking of: Create test groups. Each test spec is assigned to at least one test group. I can think of at least 2 groups: functional (the base test set in existence that validates functionality) and profiling (the projected test set that will be used for ongoing performance and memory profiling). The web frontend will allow for the creation of labels that will apply to a single group. Doing so will apply that label to all active tests in the group.

  • FATE Ends the Mac

    8 juin 2010, par Multimedia MikeFATE Server

    Did you know Mac OS X can even blue-screen? To be fair, it doesn't actually present a blue screen. But when Mac OS X encounters a kernel panic, it looks like this:



    True to form, Mac just has to be prettier and glossier than other operating systems, even in the area of system crashes.

    The reason I bring this up is that the FATE system is bringing down my Mac. My Mac Mini is reliably dying every single time I try to execute my FATE client Python script. Maybe the weather is getting too warm.

    Update, 2010-6-8: Following advice in the comments, I tried to run Memtest86 on the Mac Mini in question. I couldn't get the machine to boot the CD I made. As an alternative, I turned the machine off and let it rest for a night. In the morning, I turned it on and ran the FATE client script. It's working for now.