過去 2 週間、.mts ビデオ ファイルからフレームを読み取り、OpenCV で処理する適切な方法を見つけようとしています。.mts ファイルが 25p (25 fps プログレッシブ) 形式の場合、OpenCV の VideoCapture はビデオ フレームのシークに問題なく機能しますが、50i (25 fps インターレース) 形式の場合、OpenCV の VideoCapture はフレームごとに適切にデコードできません。(たとえば、フレーム#1を取得してからフレーム#300を読み取り、その後フレーム#1を読み取るサンプルシナリオでは、フレーム#1の以前の読み取りとは異なる破損した画像を返します)(私はOpenCV 2.4.6を使用しています)
プログラムのビデオデコーダ部分を置き換えることにしました。
FFmpegSource2 を試しましたが、.mts を求める適切なフレームの問題は解決されませんでした (ほとんどの場合、FFMS_GetFrame 関数は、50i .mts ファイルのいくつかの連続するフレームに対して同じ出力を返します)。
DirectShowも試しました。しかし、TIME_FORMAT_FRAME に対する IMediaSeeking の IsFormatSupported メソッドは、50i .mts ビデオ ファイルに対して S_OK を返さず、この種のビデオ ファイルに対しては TIME_FORMAT_MEDIA_TIME のみをサポートします。自分で試したことはありませんが、フレームシークに TIME_FORMAT_MEDIA_TIME を使用しても上記と同じ問題が発生し、個々のフレームに前後にジャンプしてそれらのデータを読み取ることができない場合があると友人が言いました。
今、私はgstreamerを試してみるつもりです。次のリンクで gstreamer と openCV をリンクするためのサンプル メソッドを見つけました: gstreamer アプリケーションへの opencv 処理の追加
gstreamer 1.0 でコンパイルしようとすると、次のエラーが発生します。
エラー C3861: 'gst_app_sink_pull_buffer': 識別子が見つかりません
gst/gst.h、gst/app/gstappsink.h、gst/app/gstappsrc.h を含めました
次のヘルプ リンクを見て、そこにも gst_app_sink_pull_buffer 関数がありませんでした。 http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-appsink.html
gstreamer.freedesktop.org の gstreamer 1.0 (v1.2.0) を使用しています
www.gstreamer.com (gstreamer 0.1 に基づく) の gstreamer SDK がそのために機能する可能性がありますが、まだ試していないため、gstreamer.freedesktop.org の gstreamer を使用することを好みます。
gst_app_sink_pull_buffer がどこに定義されているかわかりません。gstreamer 1.0 のgstreamer アプリケーションに opencv 処理を追加するで gstreamer 0.1 に提供されているサンプル メソッドをコンパイルする方法を知っている人はいます か?
前もって感謝します。
更新 1: gstreamer は初めてです。これで、 opencv 処理を gstreamer アプリケーションに追加するサンプル メソッドをgstreamer 0.1 から gstreamer 1.0に移植する必要があることがわかりました。gst_app_sink_pull_buffer 関数を gst_app_sink_pull_sample と gst_sample_get_buffer に置き換えました。コードの他の部分にさらに取り組み、50i .mts ビデオ ファイルから目的のフレームを開き、OpenCV で処理できるかどうかを確認する必要があります。
更新 2: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-data-spoof.html#section-spoof-appsinkで非常に良い例を見つけました 。フレーム データ バッファを OpenCV Mat にロードする関数で GTk を使用してスナップショットを保存する部分。このプログラムは、多くのビデオ ファイル タイプで問題なく動作し、OpenCV Mat でビデオ ファイルのフレームを取得できます。しかし、入力ビデオ ファイルが 50i .mts ビデオ ファイルの場合、次のエラーが返され、フレーム データを読み取ることができません。
No accelerated IMDCT transform found
0:00:00.405110839 4632 0B775380 ERROR libav :0:: get_buffer() failed (-1 2 00000000)
0:00:00.405740899 4632 0B775380 ERROR libav :0:: decode_slice_header error
0:00:00.406401077 4632 0B7756A0 ERROR libav :0:: Missing reference picture
0:00:00.406705867 4632 0B7756A0 ERROR libav :0:: Missing reference picture
0:00:00.416044436 4632 0B7759C0 ERROR libav :0:: Cannot combine reference and non-reference fields in the same frame
0:00:00.416813339 4632 0B7759C0 ERROR libav :0:: decode_slice_header error
0:00:00.417725301 4632 0B775CE0 ERROR libav :0:: Missing reference picture
ステップバイステップのデバッグは、実行後に「加速された IMDCT 変換が見つかりません」と表示されることを示しています
ret = gst_element_get_state( pipeline, NULL, NULL, 5 * GST_SECOND );
Google検索では、警告として無視できることが示されています。
他のすべてのエラーは、実行直後に発生します
g_signal_emit_by_name( sink, "pull-preroll", &sample, NULL );
この問題を解決する方法がわかりませんか? この .mts ファイルは、別の例で playbin を使用して既に再生しましたが、playbin を使用すると、gstreamer でこの .mts ビデオ ファイルを適切に再生できます。