rigaya / rkmppenc

Rockchip系SoCのHWエンコーダ(rkmpp)の性能実験
https://rigaya34589.blog.fc2.com/blog-category-35.html
Other
74 stars 7 forks source link

ファイルからのエンコードが完了しない #2

Closed techmadot closed 1 year ago

techmadot commented 1 year ago

TVRemotePlus さんからの紹介もあり、Rockchip RK3588 で H/W エンコーダが使えるソフトウェアとして大変期待しております。

発生している課題

以前から動作するかいろいろと試行錯誤していたのですが、録画ファイル(ts形式)から H264(mp4) にエンコード処理する際に処理が完了しないという課題に出遭っております。 手元にある録画ファイル群ではすべてが同じ状態です。

試したパターンなど

以下のパターンですべて同じように処理末尾で進行停止という状況でした。

環境情報

私の動作環境は Rock5B (8GB) で Debian (bullseye) を使用しております。 入力ファイルは 1920x1080 および 1440x1080 の解像度を持つものを使用しました。 ソースコードは acf9b9fa32f0bdec8f1cbcc9944d08f71aa47633 のものを使用していました。

その他の情報

この停止状態で gdb で止めてみたところ、以下のようなコールスタック状態でした。

#0  0x0000007ff5d33160 in __GI___clock_nanosleep (clock_id=<optimized out>,
    clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7fffffdeb8, rem=rem@entry=0x0)
    at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:48
#1  0x0000007ff5d38adc in __GI___nanosleep
    (requested_time=requested_time@entry=0x7fffffdeb8, remaining=remaining@entry=0x0)
    at nanosleep.c:27
#2  0x0000007ff5d601f4 in usleep (useconds=<optimized out>) at ../sysdeps/posix/usleep.c:32
#3  0x0000007ff7c1f670 in Mpp::get_packet_async(void**) ()
    at /lib/aarch64-linux-gnu/librockchip_mpp.so.1
#4  0x0000007ff7c220ac in  () at /lib/aarch64-linux-gnu/librockchip_mpp.so.1
#5  0x00000055558f581c in PipelineTaskMPPEncode::getOutputBitstream() (this=0x55568de400)
    at mppcore/mpp_pipeline.h:1687
#6  0x00000055558f6920 in PipelineTaskMPPEncode::sendFrame(std::unique_ptr<PipelineTaskOutput, std::default_delete<PipelineTaskOutput> >&)
    (this=0x55568de400, frame=std::unique_ptr<class PipelineTaskOutput> = {...})
    at mppcore/mpp_pipeline.h:1904
#7  0x00000055558e8db8 in MPPCore::run2() (this=0x555692bdd0) at mppcore/mpp_core.cpp:2554
#8  0x0000005555959f80 in mpp_run(MPPParam*) (pParams=0x7fffffe808) at mppenc/rkmppenc.cpp:303
#9  0x000000555595a6c8 in main(int, TCHAR**) (argc=7, argv=0x7ffffff528) at mppenc/rkmppenc.cpp:419
rigaya commented 1 year ago

ご報告と詳細な情報提供ありがとうございます。最後のほうのフレームをエンコーダから吐き出させるときに失敗している感じですね。

残念ながら、こちらではそのような症状は発生しておらず、またエラーの症状からかなり解決が難しそうと感じています。

私の環境は同じく ROCK 5Bですが、Ubuntu 20.04なので、そのあたりの違いも考えられるかと思います。

さらなる調査のため、2点お願いがございます。

1. mppの環境情報をお教えください。 rkmppenc --check-mppinfoを実行すると、mppに関する環境情報が出力されます。同じROCK 5Bなので変わらないとは思うのですが、念のため教えていただきたいです。

  rigaya@rock-5b:~$ rkmppenc --check-mppinfo
  SoC name        : radxa,rock-5b rockchip,rk3588
  Mpp service     : yes [mpp_service_v1] (okay)
  Mpp kernel      : 5.10
  2D accerelation : iepv2(okay) rga(okay)
  HW Encode       : H.264/AVC H.265/HEVC
  HW Decode       : H.264/AVC(10bit) H.265/HEVC(10bit) MPEG2 VP9(10bit) AV1

2. 最新版でのログのご提供をお願いします。

エンコード終了でなにが起こっているかを探るため、 eec221a でエンコード終了付近のログ出力強化を行いました。パッケージはこちらからダウンロードしてご利用ください。

このバージョンにおいて、下記コマンドを実行いただき、out.log をこのスレッドに添付するなどして提供いただきたく思います。

rkmppenc -i test_in.ts -o out.ts --avsw --log-level debug --log out.log

なお、処理が止まってしまうとのことで、その状態で実行し続けるとおそらくログファイルがどんどん大きくなってしまうと思うので、処理が止まってしまってから5秒から10秒程度でプロセスをkillいただければと思います。

ちなみに正常に進む場合、終盤の処理は下記のようになるはずですが、おそらくどこかで処理が止まってしまうのだと思います。

avsw: 361 frames, End of file
[mpeg2video @ 0x55a63ab2f0] invalid cbp -1 at 32 58
[mpeg2video @ 0x55a63ab2f0] Error concealment is not fully implemented for field pictures.
[mpeg2video @ 0x55a63ab2f0] Warning MVs not available
[mpeg2video @ 0x55a63ab2f0] concealing 900 DC, 900 AC, 900 MV errors in B frame
avsw: failed to send packet to video decoder, already flushed: End of file.
Break in task INPUT: more bitstream required..
avsw: failed to send packet to video decoder, already flushed: End of file.
MPPENC: Send EOS frame
MPPENC: encode_put_frame(eos) 361: no error..
MPPENC: Send EOS frame
MPPENC: encode_get_packet: null, unknown error..
MPPENC: encode_put_frame(eos) 361: no error..
MPPENC: Send EOS frame
MPPENC: encode_get_packet: yes, no error..
MPPENC: encode_put_frame(eos) 361: no error..
MPPENC: Send EOS frame
MPPENC: encode_get_packet: null, unknown error..
MPPENC: encode_put_frame(eos) 361: no error..
MPPENC: Send EOS frame
MPPENC: encode_get_packet: yes, no error..
MPPENC: encode_put_frame(eos) 361: no error..
MPPENC: Send EOS frame
MPPENC: encode_get_packet: yes, no error..
MPPENC: Got EOS packet.
Clear vpp filters...
Closing m_pmfxDEC/ENC/VPP...
Closing Encoder...
Closed Encoder.
techmadot commented 1 year ago

早速のご指示をありがとうございます。情報の取得を行いましたので記載いたします。 私の環境ではソースコードからビルドしたものを使用しており、これを使用した結果となっております。

check-mppinfo の結果

実行結果は以下の通りでした。 rigaya さんの環境と比べると Mpp kernel の箇所が異なっており、ここが課題なのかもしれません。

$ ./rkmppenc --check-mppinfo
SoC name        : radxa,rock-5b rockchip,rk3588
Mpp service     : yes [mpp_service_v1] (okay)
Mpp kernel      : unknown
2D accerelation : iepv2(okay) rga(okay)
HW Encode       : H.264/AVC H.265/HEVC
HW Decode       : H.264/AVC(10bit) H.265/HEVC(10bit) MPEG2 VP9(10bit) AV1

ログファイル

採取したログファイル: out.log ログファイルの末尾を抜粋したものが以下です。 ※ Ctrl+C ではプロセスを終了できない状態でしたので、 kill コマンドにより終了を行いました。

[h264_metadata @ 0x55a2234850] nal_unit_type: 7(SPS), nal_ref_idc: 3
avsw: 581 frames, End of file
avsw: failed to send packet to video decoder, already flushed: End of file.
Break in task INPUT: more bitstream required..
avsw: failed to send packet to video decoder, already flushed: End of file.

deb パッケージを使用した場合

続いて、rigaya さんから提示のありましたパッケージバイナリを用いて同様の情報採取をしたものを記載します。

check-mppinfo の結果

SoC name        : radxa,rock-5b rockchip,rk3588
Mpp service     : yes [mpp_service_v1] (okay)
Mpp kernel      : unknown
2D accerelation : iepv2(okay) rga(okay)
HW Encode       : H.264/AVC H.265/HEVC
HW Decode       : H.264/AVC(10bit) H.265/HEVC(10bit) MPEG2 VP9(10bit) AV1

ログファイル

採取したログファイル: out2.log ログファイルの末尾を抜粋したものが以下です。 ※ Ctrl+C ではプロセスを終了できない状態でしたので、 kill コマンドにより終了を行いました。

MPPENC: Send EOS frame
MPPENC: encode_get_packet: null, no error..
MPPENC: encode_put_frame(eos) 581: no error..
MPPENC: Send EOS frame
MPPENC: encode_get_packet: null, no error..
MPPENC: encode_put_frame(eos) 581: no error..
MPPENC: Send EOS frame
MPPENC: encode_get_packet: null, no error..
MPPENC: encode_put_frame(eos) 581: no error..
MPPENC: Send EOS frame
MPPENC: encode_get_packet: null, no error..
MPPENC: encode_put_frame(eos) 581: no error..
MPPENC: Send EOS frame
MPPENC: encode_get_packet: null, no error..
MPPENC: encode_put_frame(eos) 581: no error..
MPPENC: Send EOS frame

以上の結果となりました。 私も Ubuntu の環境で試して、データ依存ではなくOS/ソフトウェアの環境依存かどうかを切り分けたいと思います。 正常に動いているという Ubuntu は、 https://wiki.radxa.com/Rock5/downloads から入手できる Ubuntu Server 20.04 (rock-5b-ubuntu-focal-server-arm64-20221031-1328-gpt) ものでしょうか

rigaya commented 1 year ago

ご確認と情報提供ありがとうございます。

out2.log のほうでみると、やはり最後のフレームが取り出せていないようです。本来出るはずの、

MPPENC: encode_get_packet: yes, no error..
MPPENC: Got EOS packet.

というところに進まないので、永遠にエンコーダを待ってしまっています。

ただ、終了をエンコーダに知らせることはできている

MPPENC: Send EOS frame
MPPENC: encode_get_packet: yes, no error..
MPPENC: encode_put_frame(eos) 581: no error..

ので、原因が解せないところです。--check-mppinfoMpp kernel : unknown もやや気になるところですが、環境の違いかもしれません。

おそらく暫定対策としては、一定時間以上この状態になったらとりあえず抜けてしまうようにすればよいのかもしれません。(それでいいのかという不安はありますが…)

Ubuntu をお試しいただけるとのこと、ありがとうございます。

こちらでインストールしたのは、おっしゃる通り、https://wiki.radxa.com/Rock5/downloads からのものです。手元の記録によるとなぜか rock-5b-ubuntu-focal-server-arm64-20221101-0223-gpt.img.xz というのを使用していました。ただ、いま探してもリンクが見当たらないので、Ubuntu Server 20.04 (rock-5b-ubuntu-focal-server-arm64-20221031-1328-gpt) で同等ではないかと思います。

techmadot commented 1 year ago

ようやく本件の原因がわかりました。 私の環境が問題でして、 rigaya さんにはお手数をお掛け致しました。

まずクリーンな Ubuntu 20.04 Server のイメージから、 Readme に記載のインストール方法を参考にして構築したものでは正常に動作しました。 よって入力のデータファイル依存ではなく、システム環境によるものと判明しました。

次に、Debian イメージを用いて Ubuntu の場合と同様にクリーンな環境から構築を行いました。 こちらにおいても、正常にエンコードが完了する状態でした。

以上より、問題は私のシステム・環境側とわかりました。 調べてみると librockchip_mpp.so が期待されるものになっていないことが原因でした。

https://github.com/rigaya/rkmppenc/pull/1#issuecomment-1501035148 こちらでも触れられているように、私も GStreamer で H/W エンコードを使う都合で librockchip_mpp を自前でビルドしておりましたが、 Segmentation fault 発生のため昔のバージョンを使用しておりました。 正常動作した環境の librockchip_mpp.so を使い、 udev rules を再設定することで、本環境でも正常にエンコードが完了する状態となりました。

この状態で --check-mppinfo を実行した結果が以下の通りです。期待通りの出力でした。

$ rkmppenc --check-mppinfo
SoC name        : radxa,rock-5b rockchip,rk3588
Mpp service     : yes [mpp_service_v1] (okay)
Mpp kernel      : 5.10
2D accerelation : iepv2(okay) rga(okay)
HW Encode       : H.264/AVC H.265/HEVC
HW Decode       : H.264/AVC(10bit) H.265/HEVC(10bit) MPEG2 VP9(10bit) AV1

本件はこれで解決としてもらって大丈夫と思います。お手数をお掛け致しました。 トランスコードの性能が実時間に対して3倍程度と、大変魅力的なものを使うことができるようになって嬉しく感じております。

rigaya commented 1 year ago

無事rkmppencが動作するようになったとのことことで、よかったです。

古いmppでは問題が生じるというのも若干気にはなりますが、その場合も --check-mppinfo で判別できそうというのも確認できたのも、今後のトラブル時の参考となる情報で、ありがたいです。

詳細な情報共有とご連絡、ありがとうございました。