Armadilloフォーラム

acmh264decのSIGSEGVパート2

kes-konishi

2016年4月6日 11時26分

KES)小西です。

a840+gtk+gstreamerでの環境で動画再生を行ったときの問題となります。
gstreamerのエレメントとして終端を
acmfbdevsink
を使用してフレームバッファに直接出力した場合は問題ありませんが、
終端を
ximagesink
としてx上に表示した場合、動画再生完了時にSEGVで終了します。

https://armadillo.atmark-techno.com/forum/armadillo/1803
でのパイプラインを最小化して
gst-launch-1.0 filesrc location=big-buck-bunny-30sec-800x480.mp4 !
qtdemux ! acmh264dec ! videoconvert ! ximagesink
で発生し、
acmh264decからの出力終端が合っていない可能性があります。

他のフレームワークQt等にgstreamerから描画されている方で同じ問題を踏んだ方はいらっしゃいますでしょうか?

また、gstreamerでのacmを使用した表示は、基本的にフレームバッファ直接出力のみ対応しているとのことでしょうか?

コメント

KES)小西です。

追加情報です。

 :
 :
#4 fault_handler_sighandler (signum=) at gst-launch.c:93
#5
#6 gst_acm_v4l2_buffer_pool_stop (bpool=0x1a6038)
#7 0x76ecb586 in do_stop (pool=0x1a6038) at gstbufferpool.c:412
#8 0x76ecc086 in gst_buffer_pool_set_active (pool=0x1a6038,
#9 0x76ecc17c in gst_buffer_pool_finalize (object=0x1a6038)
#10 0x768bd9a8 in gst_acm_v4l2_buffer_pool_finalize (object=0x1a6038)
#11 0x76e612a8 in g_object_unref ()
#12 0x7690b406 in gst_acm_h264_dec_cleanup_decoder (me=0x148da0)
#13 gst_acm_h264_dec_stop (dec=) at gstacmh264dec.c:599
#14 0x769d5b9a in gst_video_decoder_change_state (element=0x148da0,
#15 0x76edfa82 in gst_element_change_state (element=0x148da0,
#16 0x76ee014a in gst_element_set_state_func (element=0x148da0,
#17 0x76edf89a in gst_element_set_state (element=0x148da0,
#18 0x76ec770a in gst_bin_element_set_state (next=GST_STATE_READY,
#19 gst_bin_change_state_func (element=0x73000,
#20 0x76ef9202 in gst_pipeline_change_state (element=0x73000,
#21 0x76edfa82 in gst_element_change_state (element=0x73000,
#22 0x76ee014a in gst_element_set_state_func (element=0x73000,
#23 0x76edf89a in gst_element_set_state (element=0x73000,
#24 0x0000aeb4 in main (argc=11, argv=0x7e9797e4) at gst-launch.c:1171
なので、
gst_acm_v4l2_buffer_pool_stopで終了処理で不具合があるようです。

KES)小西です。

自己レスです。
修正完了しました。

gst-plugins-at-acm_1.0.2で不具合があります。
パイプライン上に表示フレームのバッファがある状態で
表示終了を行った場合、後処理が正しく行われていないため、不整合がおき、
g_free等で2重開放等がおきます。

ロジックから追いかけると、Xへの描画時はフレーム落ちしやすいため、
再現率が高く、サンプル等でフレームバッファへ直接の表示では
フレーム落ちしにくいので再現率が低いのだと思います。

また、Qt、GTK等からAPIとして動画再生する場合は、gstreamerの
本問題により、引きづられてSEGVで強制終了してしまうため、
Qt、GTK等のフレームワーク上で動画再生される方は注意してください。

追伸.
 イーサネットのプロトコルスタック内のこちらの修正のATDEへの取り込みありがとうございました。
これで大きなデータ転送でもカーネルパニックにならないです。

KES)小西です。

修正を公開します。

--- gstacmv4l2bufferpool.c.org  2016-04-07 09:17:44.000000000 +0900
+++ gstacmv4l2bufferpool.c      2016-04-07 10:32:37.000000000 +0900
@@ -543,8 +543,10 @@
                }
        }
        pool->num_queued = 0;
-       g_free (pool->buffers);
+       if (pool->buffers)
+               g_free (pool->buffers);
        pool->buffers = NULL;
+       pool->num_buffers = 0;
 
        return ret;
 }
@@ -1182,7 +1184,10 @@
                close (pool->init_param.video_fd);
        if (pool->allocator)
                gst_object_unref (pool->allocator);
-       g_free (pool->buffers);
+       if (pool->buffers)
+               g_free (pool->buffers);
+       pool->buffers = NULL;
+       pool->num_buffers = 0;
 
        G_OBJECT_CLASS (parent_class)->finalize (object);
 }

gst_acm_v4l2_buffer_pool_stopとgst_acm_v4l2_buffer_pool_finalizeの順序性になります。
エレメント間でキューが残っているときに、
gst_acm_v4l2_buffer_pool_stop
     ↓
gst_acm_v4l2_buffer_pool_finalize
     ↓
gst_acm_v4l2_buffer_pool_stop
の順序でコールバックされるため、開放済みの領域へのアクセスと2重開放が発生してました。

添付でパッチファイルをアップしておきます。

ファイル ファイルの説明
gstacmv4l2bufferpool.c.patch gstacmv4l2bufferpool.c.patch

at_shota.tamura

2016年4月21日 9時35分

KES 小西 様

田村です。

gstacmv4l2bufferpool のパッチありがとうございました。
弊社でも「SEGVが再現すること」「パッチにより解消されること」を確認しました。

今後のアップデートで、本修正を加えたgst-plugins-acmをリリースします。