Add h264 support to ffmpeg on Ubuntu

So, I’ve got a handful of Ubuntu machines. I also have a bigger handful of DVDs. I’d like to conver the DVDs to easier-to-store videos which can be accessed by MythTV, XBMC, my mobile devices, and whatever else easily. The best broadly-supported format to do that in is h264-encoded mp4 files. And DVD::Rip does a nice job of letting me use all 20 or so CPUs I have laying around, rather than limiting me to just one workstation.

Unfortunately, DVD::Rip uses transcode, which uses ffmpeg to do the encoding. And Ubuntu’s ffmpeg, for whatever reason, lacks h264 support. There’s a guid to rebuilding it which has you pull down the latest source for all the utilities from CVS, and make new packages which don’t work right and are a pain to maintain. I, on the other hand, want to just take the Ubuntu package and add one compile-time option, so it’ll still work like the vendor-provided package. After all, all I ned to do is build the exact same thing with the “–enable-libx264” option. Here’s how.

Next, make a build directory and pull down the source for ffmpeg and its dependencies – note that it actually gets libav rather than ffmpeg on Oneiric(it’s still ffmpeg by itself on Lucid), and note that I didn’t use sudo for this one. That’s so the extracted files are owned by me, and so I can build without beign root (compiling as root is generally something to avoid).

You’ll also need to get the build package for x264, which is what we need to add (you need to have enabled the multiverse repository for that):

sauer@midnight:~/build$ sudo apt-get install libx264-dev

At this point, extract the package so you can build it. The directory would normally be named for your package, but ffmpeg is actually part of libav – so here, we’re extracting libav. I used a wildcard in the filename so you can copy and paste, but if you’ve extracted multiple versions in this directory, you’ll have problems. :) The last command is to change to the extracted-and-patched directory.

This, BTW, is the other reason to use the vendor source package. Any patches and stuff are all integrated in already. You could just rebuild now for your architecture using dpkg-buildpackage -rfakeroot -b. But we need to pass in an extra option. This is still super easy:

And now you wait while the magic compile gnomes take care of the hard parts. Don’t worry about all the warnings about undocumented parameters; those don’t hurt the actual binaries. :) You might notice that the ffmpeg script dumps out “enabled muxers” at one point, and that h264 is now included. Yay!

Actually, though, we could tweak ffmpeg a little more so that it’s tuned for our CPU. The most effective way to do that if you have a version of GCC which is newer than 4.2 (which is probably the case, but you should check first; Oneiric uses 4.6.1 and Lucid is 4.4.3) is to pass in the “-march=native” C flag. That’s still very easy. Just do this instead of the command above.

Be aware that this package is now tuned for your specific CPU; it’s not just a 32- or 64-bit package. So if you have multiple CPU types, you’ll have to redo that for each one of them. Not a huge deal, but still something to consider.

When it’s all done (it took a couple of hours on a single 2.4GHz Athlon), you’ll ideally get a bunch of output that looks like

Now I can go update a few other machines, and encode video using h264. The problem? Well, the version now matches what’s current in the repository, so you are apt (heh) to overwrite your package next time there’s an update. You’ll have to 1) notice that there’s an update available and 2) follow this procedure again to rebuild the new version. Yeah, that’s a pain. But, until the fine folks at Ubuntu are convinced to just bundle the encoder in the correct repo, them’s the breaks.

Also, this still doesn’t work with DVD::Rip, because there’s a command-line error in the way it calls ffmpeg with the h264 encoder. I haven’t tracked that down yet. But this does get you a working ffmpeg, which, I suppose, is the point.