Armadilloフォーラム

vpudecでメモリリーク発生

yseki

2023年2月7日 1時10分

お世話になっております。

h.264ストリーミングをデコードするとメモリリークが発生するようです。
少し古いですが、NXPのコミュニティでも同様の質問が上がっていますが、解決済みかわかりませんでした。
https://community.nxp.com/t5/i-MX-Processors/Memory-leak-in-VPU-Decoder…
https://community.nxp.com/t5/i-MX-Processors/iMX8MM-Memory-usage-increa…

申し訳ありませんが、具体的な解決策についてご教示いただくようお願いします。

コメント

at_makoto.sato

2023年2月7日 9時36分

佐藤です。

すいません。
お手数ですが、デコードしようとしている動画ファイルなどがあれば、
提供していただくことは可能でしょうか。

お世話になっております。

佐藤様、返信が遅くなり申し訳ありません。

添付のファイルを下記パイプラインで動作するとメモリリークするかと思います。
gst-launch-1.0 multifilesrc location=./test.mp4 loop=true ! tsdemux ! h264parse ! vpudec ! waylandsink

動画ファイルは1分程度で、わかりやすいようループしていますが、30秒、40秒程度の再生でも、freeコマンドのavailableが減少している確認が取れると思います。

ファイル ファイルの説明
test.zip 解凍するとmp4ファイルとなります。

at_dominique.m…

2023年2月9日 16時34分

ysekiさん

> 動画ファイルは1分程度で、わかりやすいようループしていますが、30秒、40秒程度の再生でも、freeコマンドのavailableが減少している確認が取れると思います。

正常の状態でも、free コマンドの used/available は少し変わります。
提供していただいたファイルとコマンドをただいま30分試してみましたが、結果的に available が少し増えました:

               total        used        free      shared  buff/cache   available
Mem:         1690212      497024      932088       37708      261100     1080104
後
Mem:         1690212      486768      941588       37708      261856     1090052

何か具体的な問題ありましたか?
NXP のフォーラムの内容を確認したところ、特定なストリームに対して問題が起きていましたので、ysekiさんが使用している IP カメラなどの問題の可能性も考えられます。

よろしくお願いします。

ベースOSを「baseos-x2-installer-3.17.1-at.2.zip」に書き換え、コンテナ(v1.0.8)も作り直しました。
ライブラリ「imx_lib.img」はダウンロードできるものがないようですので、最新に更新しました。

この環境で試してみましたが、やはりメモリリークしました。
28分くらいでメモリ不足でエラーとなりました。

gst-launch-1.0 multifilesrc location=./test.mp4 loopp=true ! tsdemux ! h264parse ! vpudec ! waylandsink
total used free shared buff/cache available
起動直後
Mem: 1703704 415416 387428 5700 900860 1192476
10分後
Mem: 1703704 673736 129652 5700 900316 934156
20分後
Mem: 1703704 846768 83796 3524 773140 763296
30分後
Mem: 1703704 1017816 42840 3284 643048 592492
再起動後
Mem: 1703704 416796 642436 3284 644472 1193932

また切り分けのため、h264parse以降を書き換えて確認しましたが、やはりvpudecが原因と思われます。
gst-launch-1.0 multifilesrc location=./test.mp4 loopp=true ! tsdemux ! h264parse ! fakesink
10分後
Mem: 1703704 445892 609412 3288 648400 1164412

gst-launch-1.0 multifilesrc location=./test.mp4 loopp=true ! tsdemux ! h264parse ! vpudec ! fakesink
10分後
Mem: 1703704 865704 190912 3288 647088 744600

ファイル ファイルの説明
imx_lib.zip ライブラリ
teraterm.zip 実行ログ

at_dominique.m…

2023年2月13日 8時39分

ysekiさん

> ベースOSを「baseos-x2-installer-3.17.1-at.2.zip」に書き換え、コンテナ(v1.0.8)も作り直しました。
> ライブラリ「imx_lib.img」はダウンロードできるものがないようですので、最新に更新しました。
>
> この環境で試してみましたが、やはりメモリリークしました。
> 28分くらいでメモリ不足でエラーとなりました。

申し訳ございません、それははっきりとリークしていますね。
詳しい情報を提供してくださったおかげで再現できました。いくつかあってありますので、確認してから再び連絡させていただきます。

よろしくお願いします。

at_dominique.m…

2023年2月16日 9時10分

ysekiさん

> 詳しい情報を提供してくださったおかげで再現できました。いくつかあってありますので、確認してから再び連絡させていただきます。

数日経ちましたので、現状報告をさせていただきます。
確認したかった NXP からいただいた新しいソフトウェアでも同じ現象なので、すぐの解決は難しいです。

ひとまず NXP のフォーラムにどうなったかを聞いてみましたが、こちらでも調査を始めました。
ドライバーではなく gstreamer の方がメモリリークしていることを確認できましたので、vpudec のどこかで GstVideoFrame を unref し忘れてるだけに思われます。条件をもうちょっと調査したら解決できると思いますので、今月のアップデートには間に合わなくても 3月末予定のアップデートまでに修正したいと思います。

修正ができた次第にまた連絡しますので、その時に確認していただけたら助かります。
お手数ですが、それまでは avdec_h264 を使うか、定期的に gstreamer の pipeline を作り直す形でリークをワークアラウンドしてみてください。

よろしくおねがいします。

at_dominique.m…

2023年3月31日 11時19分

ysekiさん

大変お待たせしました、
マルティネです。

この不具合を修正できましたので、よろしければ添付した .deb ファイルを使ってください。

パッチは以下の通りです:

diff --git a/plugins/vpu/gstvpudecobject.c b/plugins/vpu/gstvpudecobject.c
index eab7625bd8c0..0574bcfbe459 100644
--- a/plugins/vpu/gstvpudecobject.c
+++ b/plugins/vpu/gstvpudecobject.c
@@ -1501,12 +1501,12 @@ gst_vpu_dec_object_decode (GstVpuDecObject * vpu_dec_object, \
       GST_LOG_OBJECT (vpu_dec_object, "Got not enough input message!!");
       if (!IS_AMPHION() && vpu_dec_object->state < STATE_REGISTRIED_FRAME_BUFFER) {
         GST_WARNING_OBJECT (vpu_dec_object, "Dropped video frame before VPU init ok!");
-        ret = gst_vpu_dec_object_send_output (vpu_dec_object, bdec, TRUE);
-        if (ret != GST_FLOW_OK) {
-          GST_ERROR_OBJECT(vpu_dec_object, "gst_vpu_dec_object_send_output fail: %s\n", \
-              gst_flow_get_name (ret));
-          return ret;
-        }
+      }
+      ret = gst_vpu_dec_object_send_output (vpu_dec_object, bdec, TRUE);
+      if (ret != GST_FLOW_OK) {
+        GST_ERROR_OBJECT(vpu_dec_object, "gst_vpu_dec_object_send_output fail: %s\n", \
+            gst_flow_get_name (ret));
+        return ret;
       }
       break;
     }

フレームが細かく別けている場合に、vpudec のプラグインが一つのフレームだけを読み取りできない場合にもそのフレームを drop しないとリークしてしまいます。

NXP にも同じパッチを送ってみますが、弊社としてはこれでもう少し動作確認を行ってから問題なければ来月リリースしようと思います。
そちらでも確認していただけたら幸いです。

よろしくお願いします。

ファイル ファイルの説明
gstreamer1.0-imx_4.6.0-3_arm64.deb vpudec プラグインの修正されたバージョン