読者です 読者をやめる 読者になる 読者になる

/home/tnishinaga/TechMEMO

日々行ったこと、面白かったことを書き留めます。

Raspberry Piで最新のgst-omxをコンパイルして動画を変換してみた

以前書いたように、gstreamer用のOMXプラグイン(gst-omx)Version 1.0はバグを含んでいて、とある動画を変換すると一部フレームが欠落して残念な感じになってました。

というわけで仕方なく、最新の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)のライブラリを優先させるにはどうすればいい(記事)……と悩んでいたところ、Twittersunaさんとざますさんに解決方法を教えていただきました。

その解決方法はこれ。

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

修正しました。