RaspberryPi Pi3でlibx265 リベンジ

 2016-09-10
前回は最新版のlibx265はコンパイル時にエラーになるので、ちょっと古い2016-02-02の版数を持ってきてお茶を濁していましたが、解決策が発見されました。やったぜ。

 

忙しい人のための結論

  • libx265の最新版の x265/source/CMakeLists.txt を書き換えてcpuとfpuを直接指定することで、セルフビルド可能
  • x265/source/CMakeLists.txt に指定するcpuとfpuはこれ→ -mcpu=cortex-a53 -mfpu=neon-vfpv4
  • 最新版のlibx265は最適化が進んでおり、1.7倍高速なので最新版をつかおー
  • エンコード速度は、600MHz動作時0.1989 fps、1200MHz動作時0.3873 fpsでした(preset=veryslowの参考値)



前回までのおさらい

最新のlibx265だとコンパイルするときに変なエラーが出るから古い版に戻してコンパイルするぜ!ふひひ!
更新ログを見ると処理速度の最適化が行われている様だけど、動かないモノをいくらコネコネしてもどうにもならないから仕方ないね!

こういうエラーが出た

pi% make
Scanning dependencies of target common
[ 1%] Building CXX object common/CMakeFiles/common.dir/arm/asm-primitives.cpp.o
*** Error in `/usr/bin/c++': double free or corruption (top): 0x01670820 ***
Aborted
common/CMakeFiles/common.dir/build.make:54: recipe for target 'common/CMakeFiles/common.dir/arm/asm-primitives.cpp.o' failed
make[2]: *** [common/CMakeFiles/common.dir/arm/asm-primitives.cpp.o] Error 134
CMakeFiles/Makefile2:294: recipe for target 'common/CMakeFiles/common.dir/all' failed
make[1]: *** [common/CMakeFiles/common.dir/all] Error 2
Makefile:117: recipe for target 'all' failed
make: *** [all] Error 2



原因はコンパイラのバグ

当初はエラーメッセージを斜め読みして、asm-primitives.cppのどこかのコードにdouble freeとかなんとかを発生させるバグがあるのではないかと疑っていましたが、正解はコンパイラのバグだったようです。
前回の記事を書いてからちょくちょくこの件について調べていましたが、ハッカーな方達が原因を突き止めたようです。

以下、参考文献

multicoreware / x265 / 課題 / #289 - build fails on ARM7 ---> asm-primitives.cpp.o — Bitbucket
https://bitbucket.org/multicoreware/x265/issues/289/build-fails-on-arm7-asm-primitivescppo
意訳: double freeってエラーが起こるんですけど!
意訳: raspberrypiのフォーラムで類似の投稿があったよ、ARMのアーキテクチャ自動検出に問題があるからnativeって記述を止めて、直接cortex-a53とかneon-vfpv4とかを書くといいよ


Raspberry Pi • View topic - gcc ARM options
https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=139091
意訳: double freeってエラーが起こるんですけど!
意訳: GCCのARM検出コードに問題があるっぽいね。CPU種別の判別するために/proc/cpuinfoをopenするんだけど、FileHandlerの扱いがまずくて、判別に失敗した際に同じFileHandlerを二度closeしようとしてしまうんだ。そして二度目のcloseでエラーになるよ。
意訳: ありがとう。 どうすればいいんだ?
意訳: ソースを使うんだ、ルーク。 -mcpu=cortex-a53 -mfpu=neon-vfpv4


というわけで、コンパイラがよろしくなかったらしいです。これだからcmakeは嫌いなんだよ・・・(個人の感想です)


最新版のlibx265をコンパイルしよう

上記の参考文献の通り、cpuとfpuを直接指定してやります。
libx265の場合は x265/source/CMakeLists.txt というファイルを1行書き換えるだけでした。
*** x265/source/CMakeLists.txt
--- x265/source/CMakeLists.txt_BAK
***************
*** 195,201 ****
elseif(ARM)
find_package(Neon)
if(CPU_HAS_NEON)
! set(ARM_ARGS -mcpu=cortex-a53 -mfloat-abi=hard -mfpu=neon-vfpv4 -marm -fPIC)
add_definitions(-DHAVE_NEON)
else()
set(ARM_ARGS -mcpu=native -mfloat-abi=hard -mfpu=vfp -marm)
--- 195,201 ----
elseif(ARM)
find_package(Neon)
if(CPU_HAS_NEON)
! set(ARM_ARGS -mcpu=native -mfloat-abi=hard -mfpu=neon -marm -fPIC)
add_definitions(-DHAVE_NEON)
else()
set(ARM_ARGS -mcpu=native -mfloat-abi=hard -mfpu=vfp -marm)

これで普通にmakeしてやるとイイカンジにバイナリが出来上がりました。 やったぜ。


最新版libx265は良いか?

更新ログによるとARM向けのfpuやアセンブラ関係の最適化が入ってるっぽかったので、2016-02-02版よりも高速になってるかなーっと期待します。
さっそく前回と同じ動画を同じ設定でエンコードしてみます。

time ffmpeg  -i "720x480_10m49s_x264-1749k_aac-160k.mp4" -s 854x480 \
-ar 44100 -ac 2 -vcodec libx265 -preset veryslow -threads 0 \
./out_Pi3-01_x265_20160908.mp4
.....snip....
encoded 19470 frames in 97892.48s (0.20 fps), 415.64 kb/s, Avg QP:33.77
ffmpeg -i -s 854x480 -ar 44100 -ac 2 -vcodec libx265 -preset veryslow 0 364358.99s user 125.53s system 372% cpu 27:11:33.75 total
19470frame/97892.48sなので、エンコード速度は 0.1989 fps でした。

2016-02-02版のlibx265では同条件で 0.1166 fps でした(19470frames/166966.01s)ので、約1.7倍の高速化が行われているようです。さっすがー!みなさん最新版つかいましょー。


RaspberryPi3Bの全力ではどうか?

今回もそうですが、前回の時も、CPUは600MHz動作という条件でした。これは発熱や電源の用意が必要なので、不安定要素を排除するためにあえて600MHz動作としていました。
でも折角なのでRasPi3Bとして全力全開無制限解放出力のときの実力も試してみました。動作条件は下記。
  • 電源はACアダプタの5V4A出力をピンヘッダから供給する。
  • ピンヘッダに電圧計を接続し5Vを下回っていないことを適時確認
  • SoCに放熱器(秋月の16PB017)を貼り付け、USBファン(TIMELYのBIGFAN120U)にて強制送風
  • ソフトウェア的な条件は前回・今回の600MHz時と同じ

...snip...
encoded 19470 frames in 50268.88s (0.39 fps), 415.64 kb/s, Avg QP:33.77
ffmpeg -i -s 854x480 -ar 44100 -ac 2 -vcodec libx265 -preset veryslow 0 186698.88s user 61.09s system 371% cpu 13:57:50.04 total
19470frames/50268.88sなので、エンコード速度は 0.3873 fps でした。

綺麗に600MHz時のほぼ2倍となりました。クロック速度がそのまま処理速度に影響するとみて問題ないようですね。
一応snmpでCPU周波数やその他のログを取っていますが、実行中はCPU温度も50度前後を維持しており、クロックが600MHzに制限される様なことはありませんでした。
 
 
コメント












管理者にだけ表示を許可する
トラックバック
トラックバックURL:
http://wbbwbb.blog83.fc2.com/tb.php/244-5092d18c
≪ トップページへこのページの先頭へ  ≫