Using ffmpeg with libx264 on Ubuntu Jaunty(9.04) 
May 05, 2009
以下、Ubuntu 9.04 Jauntyでffmpegからlibx264を使ってh264にエンコードする話が書かれていますが、
ffmpeg+libx264だとマルチコア環境でthreadsを増やしても速くならないようなので別の方法を模索中です。
- ffmpegからraw(yuv)形式で/dev/stdoutに出力し、パイプでコマンドラインのx264エンコーダに流し込む
CPUロードが全コア一杯まで上がるのでこの方法のが速いか?(パイプのオーバーヘッドがどれだけあるのか不明)
しかしこれだと後でmuxしないといけないし、パラメタ関係も面倒 - mencoderを使う
ちょっと試した感じ、フルロードにはならないが、ffmpegよりもこっちの方がCPU使用率高そう(?)
Ubuntu Jaunty上でffmpegを使ってx264にエンコしたいねっていう話。
まずaptでffmpeg入れても殆ど何も入ってないので、自分でコンパイルしなきゃならないよっていう大前提。
で、やりかたはHOWTO: Install and use the latest FFmpeg and x264に書いてある。
libx264は
./configure --enable-pthread --enable-shared --enable-asmffmpegは
./configure --enable-shared --enable-sse --enable-ssse3 --enable-pthreads --enable-gpl --enable-libmp3lame --enable-libfaac --enable-libfaad --enable-nonfree --enable-libx264みたいな感じでお好みで。libfaac(AACエンコ),libfaad(AACデコ),libmp3lame(MP3)あたりはaptでおkなので入れておくといい。それぞれ-devパッケージも。
で、コンパイルしてインストールしたんだけど、
ffmpeg: symbol lookup error: /usr/local/lib/libavdevice.so.52: undefined symbol: av_free_packet
とか言われたり、libx264なんてコーデックは知らんと言われたりして嵌った。
とりあえずlddで確認してみると、
hiro@ubutest:~/src/ffmpeg $ ldd /usr/local/bin/ffmpeg linux-gate.so.1 => (0xb7fdb000) libavdevice.so.52 => /usr/local/lib/libavdevice.so.52 (0xb7fc0000) libavformat.so.52 => /usr/lib/i686/cmov/libavformat.so.52 (0xb7ec2000) libavcodec.so.52 => /usr/lib/i686/cmov/libavcodec.so.52 (0xb76ec000) libavutil.so.50 => /usr/local/lib/libavutil.so.50 (0xb76da000) libswscale.so.0 => /usr/lib/i686/cmov/libswscale.so.0 (0xb76aa000) libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7684000) libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb766b000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7507000) libavutil.so.49 => /usr/lib/i686/cmov/libavutil.so.49 (0xb74f5000) libz.so.1 => /lib/libz.so.1 (0xb74df000) libgsm.so.1 => /usr/lib/libgsm.so.1 (0xb74d2000) libschroedinger-1.0.so.0 => /usr/lib/libschroedinger-1.0.so.0 (0xb7462000) libspeex.so.1 => /usr/lib/sse2/libspeex.so.1 (0xb7444000) libtheora.so.0 => /usr/lib/libtheora.so.0 (0xb73f3000) libvorbisenc.so.2 => /usr/lib/libvorbisenc.so.2 (0xb72f9000) libvorbis.so.0 => /usr/lib/libvorbis.so.0 (0xb72cf000) /lib/ld-linux.so.2 (0xb7fdc000) liboil-0.3.so.0 => /usr/lib/liboil-0.3.so.0 (0xb7260000) libogg.so.0 => /usr/lib/libogg.so.0 (0xb7259000) librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb7250000)
libx264の文字がどこにもなく、入れた覚えのないvorbisやらtheoraやらspeexみたいなものが出てくる。
なんでかなと思ったのだが、強調したlibavcodec.so.52 => /usr/lib/i686/cmov/libavcodec.so.52が問題。
libavcodecっていうのは、ffmpegにおける各コーデックを抽象化(?)しているライブラリらしく、libx264やらlameやらはこいつ経由で呼び出される。
libavcodec自体はffmpegと一緒にコンパイルされて/usr/local/libにインストールされるのだが、/usr/lib/〜にlibavcodecがあるとそっちにリンクされてしまう。
邪魔だから消せばいいじゃんと思うところなのだが、/usr/lib/i686/cmov/libavcodec.so.52っていうのは要はlibavcodecというパッケージであり、これにはgstreamer0.10-ffmpegが依存していて、Totem動画プレーヤなんかをまともに使いたかったら入れざるを得ないようになっている。
なんかリンカのオプションでライブラリを探すパスを指定できる。。。らしいんだけど、よく分からなかったので環境変数LD_LIBRARY_PATHを使うことにして、以下のようなラッパスクリプトで回避することにした。
#!/bin/sh env LD_LIBRARY_PATH=/usr/local/lib ffmpeg "$@"
ちなみにLD_LIBRARY_PATHをセットした場合のlddの出力は以下のような感じ。
hiro@ubutest:~/src/ffmpeg $ env LD_LIBRARY_PATH=/usr/local/lib ldd /usr/local/bin/ffmpeg linux-gate.so.1 => (0xb8005000) libavdevice.so.52 => /usr/local/lib/libavdevice.so.52 (0xb7ffc000) libavformat.so.52 => /usr/local/lib/libavformat.so.52 (0xb7efa000) libavcodec.so.52 => /usr/local/lib/libavcodec.so.52 (0xb7603000) libavutil.so.50 => /usr/local/lib/libavutil.so.50 (0xb75f1000) libswscale.so.0 => /usr/local/lib/libswscale.so.0 (0xb75b9000) libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7581000) libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7568000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7404000) libz.so.1 => /lib/libz.so.1 (0xb73ee000) libfaac.so.0 => /usr/lib/libfaac.so.0 (0xb73dc000) libfaad.so.0 => /usr/lib/libfaad.so.0 (0xb739c000) libmp3lame.so.0 => /usr/lib/libmp3lame.so.0 (0xb7327000) libx264.so.67 => /usr/local/lib/libx264.so.67 (0xb7265000) /lib/ld-linux.so.2 (0xb8006000)


