lardbucket: vp8, webm, and ffmpeg

5/19/2010

VP8, WebM, and FFmpeg

Filed under: Programming, Technology — Andy @ 8:06 pm

So, today at Google I/O 2010, Google announced that, along with a number of other groups, they were releasing WebM, a video container and codec. (WebM itself specifies the container, which is a variation of Matroska, as well as the video format, the newly-released VP8, and the audio format, Ogg Vorbis.) I won’t get into the technical details of the codec, as I’m not really qualified to do so, but a developer for x264 has a reasonably thorough review of a prerelease version of the code here.

The interesting part of VP8 / WebM is that it is a reasonably good video standard that may be theoretically free to use. (The currently popular “best” video format, H.264, is riddled with patents and requires licensing for most uses, although encoding video that’s available for free doesn’t require payments until at least 20151.) It doesn’t appear as though anybody is claiming that WebM is the best video format available, but it’s reasonably good, and potentially free to use. (It’s impossible to know whether someone else has patented parts of the standard, because that would require examining every software patent ever granted, which is not going to happen.) For some background, the video codec, VP8, was produced by a company named On2 before Google bought them last year. Its predecessors, VP6 and VP7 were used for video in Flash2 and the video in Skype3, respectively.

Most of this will be fairly boring to anyone who normally reads this blog, but if you’re interested in a way to encode WebM videos yourself in Ubuntu, read on.

So, a HOWTO on setting up FFmpeg with WebM. There are two parts that you’ll need: libvpx and ffmpeg, probably in that order. But first, we’ll go through the first part of the semi-standard guide on installing ffmpeg and x264 on Ubuntu (which is a great resource, I’ve copied the relevant parts here). I’ll assume you’re moderately comfortable with the command line and ffmpeg.

Wait!

The guide on this page is old and outdated now. It used to be the “right” way of doing things, but thanks to work by the ffmpeg and libvpx developers, things are now much easier. Please have a look at FakeOutdoorsman’s updated, working guide right here. I’ll keep this one around for posterity.

Dependencies

This guide is outdated. Please see the “wait!” section above.

You’ll want to remove any existing ffmpeg. (If you’ll be installing x264 at the same time, remove that too.)

sudo apt-get remove ffmpeg x264 libx264-dev

Then you’ll need some dependencies: (and possibly the universe and multiverse repositories)

sudo apt-get update
sudo apt-get install build-essential subversion git-core checkinstall yasm texi2html libfaac-dev libfaad-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libsdl1.2-dev libtheora-dev libx11-dev libxfixes-dev libxvidcore-dev zlib1g-dev

If you want, you can install x264. One of the points of VP8 is that we can now avoid using H.264, so that’s potentially counterintuitive, but the ability to decode H.264 video is useful, so you may want to do this for the moment anyway.

cd
git clone git://git.videolan.org/x264.git
cd x264
./configure
make
sudo checkinstall --pkgname=x264 --pkgversion "2:0.`grep X264_BUILD x264.h -m1 | cut -d' ' -f3`.`git rev-list HEAD | wc -l`+git`git rev-list HEAD -n 1 | head -c 7`" --backup=no --default

libvpx

This guide is outdated. Please see the “wait!” section above.

The WebM site’s code page lets you decide whether to pull from git or to grab a release. I did the former, although either one will work:

cd
git clone git://review.webmproject.org/libvpx.git

Note: in the comments, Robert adds: “If you download libvpx-0.9.0.tar.bz2, then make sure to change VPX_IMG_FMT_I420 back to IMG_FMT_I420 in libvpxenc.c and libvpxdec.c.”

Then you’ll need to configure and compile libvpx. That’s fairly easy: (Change the target if you’re not compiling using GCC on an x86 Linux computer, but you probably are.)

cd libvpx
./configure --target=x86-linux-gcc
make

Then you’ll need to install the headers and library from libvpx, because the makefile’s install command doesn’t seem to work at this point:

sudo cp vp8/*.h /usr/include/
sudo cp vpx_codec/*.h /usr/include/
sudo cp vpx_ports/*.h /usr/include/
sudo cp libvpx.a /usr/lib/

And you’re done with libvpx!

ffmpeg

This guide is outdated. Please see the “wait!” section above.

Getting ffmpeg to compile properly with libvpx is a bit of a pain at the moment. Hopefully the source tree will catch up soon and the patches from WebM won’t be necessary. For the moment, do the following: (Yes, I know the svn version of ffmpeg is not what’s listed from WebM, but this one actually works. Not all the patches are applied, as the others don’t apply cleanly or are already in ffmpeg. You can use a different configure command, but this one is based on the tutorial I linked to above, the –enable-libvpx-vp8 is really the only necessary part.)

cd
wget http://webm.googlecode.com/files/mplayer-vp8-encdec-support-r2.tar.bz2
tar xvjf mplayer-vp8-encdec-support-r2.tar.bz2
svn checkout -r 23197 svn://svn.ffmpeg.org/ffmpeg/trunk/ ffmpeg
cd ffmpeg
patch -p0 < ../mplayer-vp8-encdec-support/allcodecs-register_VP8.diff
patch -p0 < ../mplayer-vp8-encdec-support/allformats-add_webm.diff
patch -p0 < ../mplayer-vp8-encdec-support/avcodec-AVCodecContext_add_VP8_specifics.diff
patch -p0 < ../mplayer-vp8-encdec-support/avformat-minor_version_bump.diff
patch -p0 < ../mplayer-vp8-encdec-support/libavcodec-build_VP8.diff
patch -p0 < ../mplayer-vp8-encdec-support/libavcodec-new_options.diff
patch -p0 < ../mplayer-vp8-encdec-support/libavformat-build_webm.diff
patch -p0 < ../mplayer-vp8-encdec-support/libvpxdec.diff
patch -p0 < ../mplayer-vp8-encdec-support/libvpxenc.diff
patch -p0 < ../mplayer-vp8-encdec-support/matroskadec-add_webm.diff
patch -p0 < ../mplayer-vp8-encdec-support/matroskaenc-add_webm.diff
patch -p0 < ../mplayer-vp8-encdec-support/ffmpeg-only/configure-libvpx_test.diff
patch -p0 < ../mplayer-vp8-encdec-support/ffmpeg-only/documentation-add_VP8__WEBM.diff
patch -p0 < ../mplayer-vp8-encdec-support/ffmpeg-only/ffpresets-libvpx.diff
./configure --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-pthreads --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libx264 --enable-libxvid --enable-x11grab --enable-libvpx-vp8
make
sudo checkinstall --pkgname=ffmpeg --pkgversion "4:SVN-r`svn info | grep Revision | awk '{ print $NF }'`" --backup=no --default

And then you’re set! You can try out your new ffmpeg: (Here, video.y4m is your input video, and video.webm is your output file. You have to use the .webm extension for ffmpeg to create a WebM file, and use whatever input video you want. Adjust the threads number to your liking, usually the number of processor cores you have in your computer is a good place to start.)

ffmpeg -i video.y4m -threads 4 video.webm

If you want to play with more options, check out libavcodec-new_options.diff in mplayer-vp8-encdec-support. (You can pass those options to ffmpeg as you would any other option.) I’m not quite clear at the moment on how to get it to run with multiple threads or on multiple cores – it currently just uses one core on my server, so if anyone has any ideas, that would be nice. Your new WebM videos should play in any of the preview builds of browsers that support WebM, and you can play them back through ffplay as well.

Andy Schmitz

(Thanks to Micheal J., Fritz, and Robert from the comments for useful suggestions.)

mplayer-vp8-encdec-support-r2.tar.bz2
  1. The press release PDF from MPEG LA, the group licensing the patents for H.264
  2. An Adobe article on encoding video for Flash using VP6. An earlier version of this post claimed VP6 was the original codec for Flash, which is false.
  3. A press release

43 Comments »

  1. This is awesome! Thanks so much! Any idea on the encoding speed between h264 and vp8?

    Comment by Nico — 5/19/2010 @ 10:36 pm

  2. Well, x264 likes to use four cores on my server, while the VP8 encoder that this creates seems to just use one, even with –enable-pthreads, which gives it a distinct disadvantage.

    Given that disadvantage, it performs about as you’d expect: rather slowly. I was able to convert a 30 second 1280×720 video (with no audio) to WebM in 297 seconds (4 minutes and 57 seconds), but to MP4 using x264 in just over 8 seconds. Of course, there’s certainly more than just the multicore activity of x264 going on there, and we can probably expect the WebM encoder to improve over time.

    (It’s also possible there are optimizations that I somehow did not enable in libvpx, etc., so certainly don’t take that as “the way things are,” but it’s how they just ran for me a few minutes ago.)

    Comment by Andy — 5/19/2010 @ 11:00 pm

  3. Hi,

    FWIW with Flash, the first “video” was that you were able to run JPGs in sequence (to a max of 30000 frames IIRC). In Flash 6, they added video properly using Sorenson Spark as the video codec. Flash 8 introduced On2VP6 support, Flash 9 Update 3 introduced H.264 support and a next version of Flash will have WebM support.

    http://en.wikipedia.org/wiki/Flash_video#File_formats

    Comment by Micheal J. — 5/19/2010 @ 11:40 pm

  4. thanks!
    just wanted to note that you use revision 23197, whereas the webmproject site tells me to use 23165 (but here some patches fail).
    thanks again.

    Comment by ebb — 5/20/2010 @ 4:42 am

  5. Micheal J.: You’re quite right, sorry about that. I’ve updated the post to reflect the actual reality.

    ebb: Yes, that’s true. I noted that above, too. The WebM site does say to us the older revision, but fewer of their [r2 set of] patches apply to it than to the new version. The one patch that doesn’t apply cleanly to r23197 is a minor version bump that’s already done in ffmpeg (but slightly differently), and the other patches that I don’t apply above already made it into ffmpeg r23197.

    Comment by Andy — 5/20/2010 @ 7:19 am

  6. Hi Andy,

    where you (or someone else) able do get ffmpeg compiled with “-enable-shared” set in “./configure” ?
    During “make” it exits with:

    /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/libvpx.a(vpx_codec.c.o): relocation R_X86_64_32 against `a local symbol’ can not be used when making a shared object; recompile with -fPIC

    I tried it with “–extra-cflags=-fPIC” but this doesn’t help.

    Best,

    Felix

    Comment by Felix — 5/20/2010 @ 7:59 am

  7. For anyone who wants to compile for Windows I’ve posted instructions here: http://www.ioncannon.net/meta/1128/compiling-webm-ffmpeg-windows/

    Comment by Carson McDonald — 5/20/2010 @ 9:29 am

  8. If you did the configure step as issued above “./configure” you will be building the generic c encoder/decoder (without optimizations). This could be a reason you are seeing slow times. Issuing “./configure –help” will show the targets that you can build for. I don’t know your platform, but you probably want to do “./configure –target=x96-linux-gcc” to enable SSE optimizations.

    Comment by Fritz — 5/20/2010 @ 9:57 am

  9. @Felix:

    In your libvpx configure you’re going to what:

    –target=x86_64-linux-gcc –enable-pic

    The former is targeting your platform (doesn’t auto detect at present), and the latter you’ll need to link the lib w/FFmpeg.

    Comment by Tom Finegan — 5/20/2010 @ 10:11 am

  10. @Tom:

    That is what I am actually doing in “./configure”. Does it work for you?

    Comment by Felix — 5/20/2010 @ 10:48 am

  11. Thanks for the tutorial. I’d like to try it out, but I’m not familiar with Linux command-line. Could you compile an ffmpeg executable for Windows (or Linux) and share it? Much appreciated!

    Comment by Gabriel — 5/20/2010 @ 10:56 am

  12. @Felix

    > Does it work for you?

    Yes, but I’m working with the code from the chromium nightly.

    I will have to try this later on and see what’s going on– I commented initially because “relocation R_X86_64_32″ typically means that libvpx was build w/out –enable-pic in the configure.

    Comment by Tom Finegan — 5/20/2010 @ 11:39 am

  13. Fritz: Thanks for the information! It now runs about 3-4x faster (doing the same encode from above in 88 seconds on a quad-core Xeon, but still only using one core). Do you have any further information about optimizations, or any way to get it going using multicore processing?

    Gabriel: I’m not confident enough about my build to distribute a Linux binary, but I know that micksam7 on Twitter compiled this version for Windows, and codingrobots posted a [64-bit?] Mac version. Note that I haven’t tested and can’t vouch for either of those.

    Comment by Andy — 5/20/2010 @ 1:27 pm

  14. My experience is with ivfenc/ivfdec. There are example parameters for ivfenc up on the webm site. ivfenc –threads= specifies how to thread it, but I don’t know how to pass that through ffmpeg. man ffmpeg or –help may show.

    Comment by Fritz — 5/20/2010 @ 5:02 pm

  15. Thanks, Fritz! Indeed, it looks like specifying the number of threads does let it work better. With “-threads 4″ (just a single dash for ffmpeg’s arguments), I can run the 30-second 1280×720 encode in 57 seconds on a quad-core Xeon, although it still only seems to use around two cores. (That is, “top” reports it being around 180-230% usage.) Boosting the number of threads doesn’t help, so I’m a bit curious, but the extra speed increase here is still useful.

    Comment by Andy — 5/20/2010 @ 5:52 pm

  16. Well, x264 likes to use four cores on my server, while the VP8 encoder that this creates seems to just use one, even with –enable-pthreads, which gives it a distinct disadvantage.

    @Andy: you need to run ffmoeg with “-threads 2″ and it will use both cores (tested on my dual core)

    Comment by startx — 5/21/2010 @ 6:49 am

  17. i got this error while compiling ffmpeg

    libavcodec/libvpxenc.c:266: error: ‘IMG_FMT_I420’ undeclared (first use in this function)

    i am using 64-bit ubuntu

    Comment by kamran — 5/21/2010 @ 9:55 am

  18. Same problem as kamran… Seems it’ll be tricky to get it working on 64-bit system.

    Comment by Niektory — 5/21/2010 @ 4:58 pm

  19. …or maybe not. I changed IMG_FMT_I420 to VPX_IMG_FMT_I420 in libvpxenc.c and it compiles now.

    Comment by Niektory — 5/21/2010 @ 5:21 pm

  20. If you are using LiVES, please make sure you add “–enable-jpeg –enable-png” to the ffmpeg options, otherwise you might break video importing in the LiVES application.

    Comment by salsaman — 5/21/2010 @ 8:29 pm

  21. Sorry, forget that…you only need the above when compiling mplayer.

    Comment by salsaman — 5/22/2010 @ 7:35 am

  22. **** Installation failed. Aborting package creation

    Didn’t work for me

    Comment by cipher — 5/23/2010 @ 12:10 am

  23. FYI, you don’t need x264 for H.264 decoder, the decoder is native and built-in.
    Speed tests with threads would be great indeed.

    Comment by prosper — 5/23/2010 @ 5:06 pm

  24. cipher: I’m sorry it didn’t work for you. Can you provide more information about what didn’t work? If it was just the package creation that didn’t work, you may be able to simply do “sudo make install”, although then you don’t get the benefit of having ffmpeg as a package you can later remove.

    propser: Huh, thanks for letting me know about H.264 decoding. I may get a chance to do speed tests in a while, but things are pretty hectic for the moment. I’d be happy to link to others if someone does one, though. (I haven’t yet seen any done formally.)

    Comment by Andy — 5/23/2010 @ 8:07 pm

  25. If you download libvpx-0.9.0.tar.bz2, then make sure to change VPX_IMG_FMT_I420 back to IMG_FMT_I420 in libvpxenc.c and libvpxdec.c.

    Comment by robert — 5/24/2010 @ 6:12 pm

  26. If you are compiling on a x86 Mac use “./configure –target=x86-darwin9-gcc” for 32 bit and “./configure –target=x86_64-darwin9-gcc” for 64 bit. This will enable x86 optimizations. See “./configure –help” for other targets.

    Comment by robert — 5/24/2010 @ 6:36 pm

  27. I have made fedora packages of ffmpeg with webm support. Check my blog for links.

    Comment by Praveen Arimbrathodiyil — 5/27/2010 @ 2:58 am

  28. ffmpeg with webm compiled in DEB package
    http://www.megaupload.com/?d=YTSYPOE2

    Comment by agusbohemio — 5/27/2010 @ 7:57 am

  29. libVorbis seems to be missing in the build. The audio generated won’t be of acceptable quality.
    Please read: http://xiphmont.livejournal.com/51160.html

    Comment by Leon — 5/27/2010 @ 11:07 am

  30. considering above Monty warning, is it ok to simply add :
    –disable-encoder=vorbis –enable-libvorbis
    after ;
    ./configure –enable-gpl –enable-version3 –enable-nonfree –enable-postproc –enable-pthreads –enable-libfaac –enable-libfaad –enable-libmp3lame –enable-libopencore-amrnb –enable-libopencore-amrwb –enable-libtheora –enable-libx264 –enable-libxvid –enable-x11grab –enable-libvpx-vp8

    Comment by antistress — 5/30/2010 @ 4:55 pm

  31. The line
    sudo checkinstall –pkgname=ffmpeg –pkgversion “4:SVN-r`svn info | grep Revision | awk ‘{ print $NF }’`” –backup=no –default
    brings errors for me (seems to come from the –pkgversion “4:SVN-r`svn info | grep Revision | awk ‘{ print $NF }’`” part)

    Comment by antistress — 5/30/2010 @ 5:12 pm

  32. I can compile and install the ffmpeg without problem reading this post but I have a problem if Ï try encode via ffserver with this configuration

    Feed feed1.ffm
    Format webm
    VideoCodec libvpx_vp8
    VideoFrameRate 25
    VideoBufferSize 80
    VideoBitRate 150K
    VideoIntraOnly
    AVOptionVideo minrate 150K
    AVOptionVideo maxrate 150K
    AVOptionVideo itsoffset -4
    AVOptionVideo timestamp 30
    AVOptionVideo threads 4
    AVOptionVideo qmin 30
    AVOptionVideo qmax 31
    #AVOptionVideo vpre 720p
    #AVOptionVideo copyts
    AVOptionVideo flags +global_header
    VideoSize 512×288
    Preroll 0
    AudioCodec libvorbis
    AudioBitRate 64K
    AudioChannels 2
    AudioSampleRate 48000
    AVOptionAudio async 1
    AVOptionAudio itsoffset -4
    AVOptionAudio timestamp 30
    AVOptionAudio flags +global_header

    and I shot from ffmpeg with this line

    ffmpeg -i /media/DATOS02/VIDEOS/”Avatar CD1″.avi http://192.168.1.51:8092/feed1.ffm

    the machine dont create the webm correct but if I only send video and noaudio the webm is correct and I can see in Opera Nightly

    Best Regards

    Comment by ricardo jimenez — 5/31/2010 @ 1:38 pm

  33. I’ve made an how to in french, inspired by your post and its comments
    http://libre-ouvert.toile-libre.org/?article30/transformer-un-ogg-vorbis-en-webm-sans-reencoder

    Comment by antistress — 5/31/2010 @ 5:04 pm

  34. But I am trying live stream with ffmpeg and vp8 and when I put video + audio the system dont start the encoder but if only put video the video encoder good and I can see in Opera or chromiun without problem

    Can Somebody help me for encoder live stream with ffmpeg and vp8?

    Comment by ricardo jimenez — 6/1/2010 @ 2:22 am

  35. Anyone know of a ppa for Ubuntu with webm patches included?

    Comment by Martin Wetterstedt — 6/3/2010 @ 2:45 am

  36. Heads up — You do not need the patch files anymore to compile WEBM support with FFmpeg. These patches have been comitted to the latest FFmpeg SVN. Also some more work has been done on the libvpx source files so you’re best bet is to use git and pull down a copy of the latest version. This new version can now detect your processr and actually install the library files into the correct location (ex: /usr/local/lib).

    Comment by Robert — 6/4/2010 @ 1:49 pm

  37. I just added libvpx installation instructions to HOWTO: Install and use the latest FFmpeg and x264 on Ubuntu on ubuntuforums.org. Uses libvpx from git and installs with checkinstall.

    Comment by FakeOutdoorsman — 6/10/2010 @ 4:34 pm

  38. …and thanks for mentioning the guide.

    Comment by FakeOutdoorsman — 6/10/2010 @ 4:37 pm

  39. I ran into two problems
    A).libvpx: the third part

    Line 1. sudo cp vp8/*.h /usr/include/ (cp: cannot stat `vp8/*.h’: No such file or directory)
    Line 2. sudo cp vpx_codec/*.h /usr/include/ (cp: cannot stat `vpx_codec/*.h’: No such file or directory)

    B). ffmpeg: line 21 the make will not work:
    This is the error I get,
    Makefile:342: /tests/fate.mak: No such file or directory

    make: *** No rule to make target `/tests/fate.mak’. Stop.

    Comment by irv — 6/22/2010 @ 9:14 pm

  40. yes
    I also got same problem
    After building libvpx I got following header files

    args.h md5_utils.h vpx_config.h vpx_version.h y4minput.h

    now , One can see here that there is no vp8/*.h,vpx_codec/*.h or vpx_ports/*.h file.
    Is there any error related to configuration.

    Comment by amar — 6/30/2010 @ 3:53 am

  41. FakeOutdoorsman: Thank you for the updated version of the guide! (And thank you for the guide in the first place, it is often one of my first stops when setting up or upgrading an Ubuntu machine.)

    irv, amar, and others: Please see FakeOutdoorsman’s guide regarding setting up ffmpeg. It is now more up-to-date than my guide above.

    Everyone: Debugging ffmpeg and libvpx issues is unfortunately not something that I’m able to do at this point, due to other things I need to spend time on. The guide from FakeOutdoorsman is excellent and something I would suggest that you look at if you are still having compilation issues. Thanks!

    Comment by Andy — 6/30/2010 @ 4:32 pm

  42. Hi, I followed the tutorial for Ubuntu 10.04 (Lucid Lynx). Then when I try to convert a .mp4 file to a .webm file I get into this error: “[libvpx @ 0xa01b2c0] Failed to initialize encoder: ABI version mismatch”, which lead the encoding process to failure. Googled a very long time for it, but nothing found.

    Comment by cyberziz — 11/8/2011 @ 9:50 am

  43. I’m getting the same “ABI version mismatch” error when trying to encode. Can anyone help?

    Comment by slevytam — 12/4/2011 @ 1:57 pm

RSS feed for comments on this post.

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

My Stuff
Blog Stuff
Categories
Archives