以前書いたように、gstreamer用のOMXプラグイン(gst-omx)Version 1.0はバグを含んでいて、とある動画を変換すると一部フレームが欠落して残念な感じになってました。
- http://tnishinaga.hatenablog.com/entry/2014/05/08/024659
- http://tnishinaga.hatenablog.com/entry/2014/05/07/032019
というわけで仕方なく、最新のgst-omxを持ってきてビルドして、それを使って動画の変換をしてみました。
以下にそれまでの手順をメモを元に示しますが、再現性は現在確認中です。
上手くいかなかったらコメントで知らせてください。
おおまかな手順
まず、以前の記事で作成した環境上で、gst-omxプラグインだけをアップデートしようと試みましたが、gstreamer関連のヘッダに定義された定数が上手く取ってこれずにビルド失敗。 色々探したのですが解決方法が見つからず、断念。
しかたがないので環境をまっさらにして、gstreamerからなにから1からコンパイルすることになりました。
おおまかな手順は以下の様な感じです。
もろもろのコンパイルとインストール
gstreamerとその他プラグインを入れてしまいます。
一括で入るようにスクリプトとしてまとめたので、使ってください。
インストール先は既存の環境に考慮して/usr/local
にします。
#!/bin/bash -v # Create a log file of the build as well as displaying the build on the tty as it runs exec > >(tee build_gstreamer.log) exec 2>&1 ################# COMPILE GSTREAMER 1.x ############ sudo aptitude install -y build-essential autotools-dev automake autoconf \ libtool autopoint libxml2-dev zlib1g-dev libglib2.0-dev \ pkg-config bison flex python git gtk-doc-tools libasound2-dev \ libgudev-1.0-dev libxt-dev libvorbis-dev libcdparanoia-dev \ libpango1.0-dev libtheora-dev libvisual-0.4-dev iso-codes \ libgtk-3-dev libraw1394-dev libiec61883-dev libavc1394-dev \ libv4l-dev libcairo2-dev libcaca-dev libspeex-dev libpng-dev \ libshout3-dev libjpeg-dev libaa1-dev libflac-dev libdv4-dev \ libtag1-dev libwavpack-dev libpulse-dev libsoup2.4-dev libbz2-dev \ libcdaudio-dev libdc1394-22-dev ladspa-sdk libass-dev \ libcurl4-gnutls-dev libdca-dev libdirac-dev libdvdnav-dev \ libexempi-dev libexif-dev libfaad-dev libgme-dev libgsm1-dev \ libiptcdata0-dev libkate-dev libmimic-dev libmms-dev \ libmodplug-dev libmpcdec-dev libofa0-dev libopus-dev \ librsvg2-dev librtmp-dev libschroedinger-dev libslv2-dev \ libsndfile1-dev libsoundtouch-dev libspandsp-dev libx11-dev \ libxvidcore-dev libzbar-dev libzvbi-dev liba52-0.7.4-dev \ libcdio-dev libdvdread-dev libmad0-dev libmp3lame-dev \ libmpeg2-4-dev libopencore-amrnb-dev libopencore-amrwb-dev \ libsidplay1-dev libtwolame-dev libx264-dev sudo aptitude -y install python-gobject python-gobject-dev python-pip sudo aptitude -y install libusb-1.0-0-dev libxv-dev sudo aptitude -y install libmpg123-dev libsoundtouch0-dev libvo-aacenc-dev sudo aptitude -y install libavutil-dev sudo aptitude -y install yasm sudo aptitude -y install inotify-tools sudo aptitude -y install python-dev gtk-doc-tools cd $HOME mkdir packages cd packages/ mkdir gstreamer-1.x cd gstreamer-1.x wget http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-1.2.2.tar.xz wget http://gstreamer.freedesktop.org/src/orc/orc-0.4.18.tar.gz wget http://gstreamer.freedesktop.org/src/gst-plugins-base/gst-plugins-base-1.2.2.tar.xz wget http://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-1.2.2.tar.xz wget http://gstreamer.freedesktop.org/src/gst-plugins-ugly/gst-plugins-ugly-1.2.2.tar.xz wget http://gstreamer.freedesktop.org/src/gst-libav/gst-libav-1.2.2.tar.xz wget http://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugins-bad-1.2.2.tar.xz # unpack find ./ -name "*.tar.xz" | xargs -n 1 tar -xJf find ./ -name "*.tar.gz" | xargs -n 1 tar -xzf cd gstreamer-* ./configure --prefix=/usr/local/ make -j 2 sudo make install cd .. cd orc-0.4.18 LIBS="$LIBS -L/usr/loca/lib" ./configure --prefix=/usr/local make -j 2 sudo make install cd .. cd gst-plugins-base-* LIBS="$LIBS -L/usr/loca/lib" ./configure --enable-orc --with-libv4l2 --with-x make -j 2 sudo make install cd .. cd gst-plugins-good-* LIBS="$LIBS -L/usr/loca/lib" ./configure --prefix=/usr/local make -j 2 sudo make install cd .. cd gst-plugins-ugly-* LIBS="$LIBS -L/usr/loca/lib" ./configure --prefix=/usr/local make -j 2 sudo make install cd .. cd gst-libav-* LIBS="$LIBS -L/usr/loca/lib" ./configure --prefix=/usr/local make -j 2 sudo make install cd .. # Install libusb-1.0 to enable uvch264src sudo apt-get install libusb-1.0 cd gst-plugins-bad-* LIBS="$LIBS -L/usr/loca/lib" LDFLAGS='-L/opt/vc/lib' CPPFLAGS='-I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux' ./configure --prefix=/usr/local/ make -j 2 sudo make install cd .. ################# COMPILE GST-OMX ########## git clone http://anongit.freedesktop.org/git/gstreamer/gst-omx.git cd gst-omx LIBS="$LIBS -L/usr/loca/lib" LDFLAGS='-L/opt/vc/lib' CPPFLAGS='-I/opt/vc/include -I/opt/vc/include/IL -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux' ./autogen.sh --with-omx-target=rpi --prefix=/usr/local make -j 2 sudo make install export GST_OMX_CONFIG_DIR=/usr/local/etc/xdg/ echo "export GST_OMX_CONFIG_DIR=/usr/local/etc/xdg/" >> ~/.bashrc
これでインストールは完了。
動画を変換してみる
最新版では以前の問題が改善されたのかを確かめてみます。
$ gst-launch-1.0 filesrc location=sakigake.mpg ! progressreport ! mpegpsdemux name=demuxer demuxer. ! queue ! mpegaudioparse ! mad ! audioresample ! audioconvert dithering=0 ! voaacenc bitrate=128000 ! mux. mp4mux name=mux ! filesink location=hoge.mp4 demuxer. ! queue ! mpegvideoparse ! omxmpeg2videodec ! videoconvert ! omxh264enc target-bitrate=5000000 control-rate=variable ! video/x-h264,stream-format=byte-stream, profile=high ! h264parse ! mux. Setting pipeline to PAUSED ... Pipeline is PREROLLING ... Pipeline is PREROLLED ... Setting pipeline to PLAYING ... New clock: GstSystemClock progressreport0 (00:00:05): 5275648 / 161112068 bytes ( 3.3 %) progressreport0 (00:00:10): 10551296 / 161112068 bytes ( 6.5 %) progressreport0 (00:00:15): 15400960 / 161112068 bytes ( 9.6 %) progressreport0 (00:00:20): 20447232 / 161112068 bytes (12.7 %) progressreport0 (00:00:25): 25591808 / 161112068 bytes (15.9 %) progressreport0 (00:00:30): 30244864 / 161112068 bytes (18.8 %) progressreport0 (00:00:36): 35356672 / 161112068 bytes (21.9 %) progressreport0 (00:00:41): 39845888 / 161112068 bytes (24.7 %) progressreport0 (00:00:46): 44826624 / 161112068 bytes (27.8 %) progressreport0 (00:00:51): 49872896 / 161112068 bytes (31.0 %) progressreport0 (00:00:56): 54919168 / 161112068 bytes (34.1 %) progressreport0 (00:01:01): 59932672 / 161112068 bytes (37.2 %) progressreport0 (00:01:06): 64880640 / 161112068 bytes (40.3 %) progressreport0 (00:01:11): 69959680 / 161112068 bytes (43.4 %) progressreport0 (00:01:16): 74940416 / 161112068 bytes (46.5 %) progressreport0 (00:01:21): 79953920 / 161112068 bytes (49.6 %) progressreport0 (00:01:26): 84967424 / 161112068 bytes (52.7 %) progressreport0 (00:01:31): 90013696 / 161112068 bytes (55.9 %) progressreport0 (00:01:36): 94896128 / 161112068 bytes (58.9 %) progressreport0 (00:01:41): 99975168 / 161112068 bytes (62.1 %) progressreport0 (00:01:46): 105054208 / 161112068 bytes (65.2 %) progressreport0 (00:01:51): 109969408 / 161112068 bytes (68.3 %) progressreport0 (00:01:56): 115081216 / 161112068 bytes (71.4 %) progressreport0 (00:02:01): 120160256 / 161112068 bytes (74.6 %) progressreport0 (00:02:06): 125075456 / 161112068 bytes (77.6 %) progressreport0 (00:02:11): 130121728 / 161112068 bytes (80.8 %) progressreport0 (00:02:16): 135102464 / 161112068 bytes (83.9 %) progressreport0 (00:02:21): 140017664 / 161112068 bytes (86.9 %) progressreport0 (00:02:26): 145457152 / 161112068 bytes (90.3 %) progressreport0 (00:02:31): 150274048 / 161112068 bytes (93.3 %) progressreport0 (00:02:36): 155385856 / 161112068 bytes (96.4 %) progressreport0 (00:02:41): 159678464 / 161112068 bytes (99.1 %) Got EOS from element "pipeline0". Execution ended after 0:02:42.476965191 Setting pipeline to PAUSED ... Setting pipeline to READY ... Setting pipeline to NULL ... Freeing pipeline ...
うまくいきました。
以前出ていた警告も消えています。
画像の乱れは一部改善していましたが,完全にはなくなりませんでした.
原因はフレームの欠落っぽいので、この辺りの設定をいじって何とかならないか、もう少し調べてみることにします。
$ gst-inspect-1.0 omxh264enc Element Properties: name : The name of the object flags: readable, writable String. Default: "omxh264enc-omxh264enc0" parent : The parent of the object flags: readable, writable Object of type "GstObject" control-rate : Bitrate control method flags: readable, writable, changeable only in NULL or READY state Enum "GstOMXVideoEncControlRate" Default: -1, "default" (0): disable - Disable (1): variable - Variable (2): constant - Constant (3): variable-skip-frames - Variable Skip Frames (4): constant-skip-frames - Constant Skip Frames (-1): default - Component Default target-bitrate : Target bitrate (0xffffffff=component default) flags: readable, writable, changeable in NULL, READY, PAUSED or PLAYING state Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295 quant-i-frames : Quantization parameter for I-frames (0xffffffff=component default) flags: readable, writable, changeable only in NULL or READY state Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295 quant-p-frames : Quantization parameter for P-frames (0xffffffff=component default) flags: readable, writable, changeable only in NULL or READY state Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295 quant-b-frames : Quantization parameter for B-frames (0xffffffff=component default) flags: readable, writable, changeable only in NULL or READY state Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295 inline-header : Inline SPS/PPS header before IDR flags: readable, writable, changeable only in NULL or READY state Boolean. Default: true periodicty-idr : Periodicity of IDR frames (0xffffffff=component default) flags: readable, writable, changeable only in NULL or READY state Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295 interval-intraframes: Interval of coding Intra frames (0xffffffff=component default) flags: readable, writable, changeable only in NULL or READY state Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295
なんか色々いじれるみたいですし。
(フレームの量子化パラメータって何…?そもそもI,P,Bフレームの理解が……H.264の教科書を読まないとダメ…?)
余談
道中躓いたところなど。
LD_LIBRARY_PATHの話
orcライブラリはaptから入っていたもの(古い方)と、私たちが後から入れたもの(version 0.4.18)が同一システム上にインストールされることになります。
ライブラリの名前も同じなので、通常/usr/lib
以下のライブラリ、つまり最初から入っていたほうが優先されます。
本当は古い方を消してしまいたいのですが、調べてみると他のライブラリに依存されているらしく、依存関係の処理が大変そうだったので残すことにしました。
では/usr/local/lib
以下(version 0.4.18)のライブラリを優先させるにはどうすればいい(記事)……と悩んでいたところ、Twitterでsunaさんとざますさんに解決方法を教えていただきました。
その解決方法はこれ。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
LD_LIBRARY_PATHを設定すると、そのディレクトリ以下のライブラリを優先的に使用するようになるようです。
試しにこれを実行してからorc-0.4.18を使用するプログラムを動かすと、きちんと/usr/local/lib
以下のorc-0.4.18が読まれて、エラーもなく動くようになりました。
gst-omxのヘッダファイルの話
gst-omxのコンパイル、最初は以下の様なエラーが出て上手く行きませんでした。
# コマンド git clone http://anongit.freedesktop.org/git/gstreamer/gst-omx.git ./autogen.sh --noconfigure ./configure --with-omx-target=rpi make -j 2 # エラー make[2]: Entering directory `/home/pi/src/gst-omx/omx' CC libgstomx_la-gstomx.lo CC libgstomx_la-gstomxbufferpool.lo In file included from gstomx.c:30:0: gstomx.h:52:26: fatal error: OMX_Broadcom.h: No such file or directory compilation terminated. In file included from gstomxbufferpool.h:32:0, from gstomxbufferpool.c:27: gstomx.h:52:26: fatal error: OMX_Broadcom.h: No such file or directory compilation terminated. make[2]: *** [libgstomx_la-gstomx.lo] Error 1 make[2]: *** Waiting for unfinished jobs.... make[2]: *** [libgstomx_la-gstomxbufferpool.lo] Error 1 make[2]: Leaving directory `/home/pi/src/gst-omx/omx' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/pi/src/gst-omx' make: *** [all] Error 2
原因は/opt/vc/include/IL/
以下のヘッダを使っていないことでした。
いろいろやりかたはあると思いますが、結局CFLAGSに追加してconfigureするのが一番ラクみたいです( autogen.sh に指定しても同じことになります)
LDFLAGS='-L/opt/vc/lib' CPPFLAGS='-I/opt/vc/include -I/opt/vc/include/IL -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux' ./autogen.sh --with-omx-target=rpi --prefix=/usr/local
gst-omxが認識されなかった話
gst-omxのコンパイルとインストールができたのに、肝心のgstreamerがプラグインを認識してくれなかった。
以下のコマンドで確認しても、結果はなし。つまりプラグインとして有効になってない。
$ gst-inspect-1.0 | grep omx
プラグイン自体は/usr/local/lib/gstreamer-1.0/libgstomx.so
に入ってるので確認してみたところ、
$ gst-inspect-1.0 /usr/local/lib/gstreamer-1.0/libgstomx.so Could not load plugin file: File "/usr/local/lib/gstreamer-1.0/libgstomx.so" appears to be a GStreamer plugin, but it failed to initialize
初期化ができない、と言われて動かなかった。
そしてそういう動かないプラグインは、ブラックリストに入れられるらしい。
ブラックリストの中身は以下のコマンドで確認できる。
$ gst-inspect-1.0 -b Blacklisted files: libgstomx.so Total count: 1 blacklisted file
解決方法は環境変数GST_OMX_CONFIG_DIR
を設定すること。
設定ファイルは/usr/local/etc/xdg/
以下に入ってるので、これを指定する。
export GST_OMX_CONFIG_DIR=/usr/local/etc/xdg/ echo "export GST_OMX_CONFIG_DIR=/usr/local/etc/xdg/" >> ~/.bashrc
後は以下のコマンドでプラグインリストのキャッシュを削除して、再構築すれば使えるようになる。
$ rm -rf ~/.cache/gstreamer-1.0/ $ gst-inspect-1.0 | grep omx omx: omxhdmiaudiosink: OpenMAX HDMI Audio Sink omx: omxanalogaudiosink: OpenMAX Analog Audio Sink omx: omxh264enc: OpenMAX H.264 Video Encoder omx: omxvc1dec: OpenMAX WMV Video Decoder omx: omxmjpegdec: OpenMAX MJPEG Video Decoder omx: omxvp8dec: OpenMAX VP8 Video Decoder omx: omxtheoradec: OpenMAX Theora Video Decoder omx: omxh264dec: OpenMAX H.264 Video Decoder omx: omxh263dec: OpenMAX H.263 Video Decoder omx: omxmpeg4videodec: OpenMAX MPEG4 Video Decoder omx: omxmpeg2videodec: OpenMAX MPEG2 Video Decoder
一件落着。
参考サイト
http://www.trans-omni.co.uk/pi/GStreamer-1.0/build_gstreamer http://stackoverflow.com/questions/15360688/how-to-register-a-gstreamer-plugin http://www.raspberrypi.org/forums/viewtopic.php?t=6852 http://www.raspberrypi.org/forums/viewtopic.php?t=71206&p=514990 http://www.raspberrypi.org/forums/viewtopic.php?f=38&t=6852&start=25
追記
IDRフレームの値を50にすると、フレーム抜けが収まった。
$ gst-launch-1.0 filesrc location=sakigake.mpg ! progressreport ! mpegpsdemux name=demuxer demuxer. ! queue ! mpegaudioparse ! mad ! audioresample ! audioconvert dithering=0 ! voaacenc bitrate=128000 ! mux. mp4mux name=mux ! filesink location=hoge.mp4 demuxer. ! queue ! mpegvideoparse ! omxmpeg2videodec ! videoconvert ! omxh264enc target-bitrate=5000000 control-rate=variable periodicty-idr=50 ! video/x-h264,stream-format=byte-stream, profile=high ! h264parse ! mux.
ただ、この動画をomxplayerやVLCで再生すると、微妙にカクカクしたものになる。 QuickTimeで再生するとそんなことはないんだけど…。
他のフレームの値とかをいじったら改善するだろうか……調査に協力してくれる方、募集中です…。
2014/05/12
ここに書いたスクリプトで環境構築できなかったので、現在修正版を作っています。 しばらくお待ちください……。
2014/05/13
修正しました。