DirectShow フィルターグラフがファイルの終わりに達したことを検出する方法はありますか? そのファイルの終わりまでに、SampleGrabber フィルターを使用するフィルターグラフは別の SampleCB 呼び出しを受信しないことを意味します。
機能しないものを次に示します。
- 信頼
IMediaDet::get_StreamLength
(ビデオには実際よりも多くのフレームがあるとよく言われます) - Trust
IMediaSeeking::GetDuration
(IMediaDet と一致、+/- 1 フレーム) - 使用
IMediaControl::GetState
(すべてのフレームがファイルから既に処理されている場合でも、フィルターグラフは実行されたままになります)
バックグラウンド:
私はビデオ処理を行っており、SampleGrabber でフィルターグラフを作成するクラスを持っています。が呼び出されるたびSampleGrabber::SampleCB
に、mutex でブロックして、filtergraph をプル モードで実行できるようにします。別のフレームの準備ができたら、メイン スレッドでミューテックスのブロックを解除し、完了しSampleGrabber::SampleCB
たというシグナルが送信されるのを待ちます。一部のビデオでIMediaDet::get_StreamLength
は、ビデオに実際に存在するよりも多くのフレームがあることがわかります。最終フレームを抽出し、実際に存在するフレームよりも 1 つ多く要求すると、メイン スレッドSampleGrabber::SampleCB
は二度と呼び出されないため、永久にブロックされます。いつ検出できるようにしたいのですか?SampleGrabber::SampleCB
ファイルソースに対して呼び出されることはありません。Windows Media Player などのアプリケーションは、ビデオが最後の実際のフレームの後に終了したことを GUI が報告するため、何らかの方法でこれを行うことができます。これを行う方法があるようです。
編集:
WaitForSingleObject
メインスレッドのブロックを実装するために使用しています。私がこれまでに使用してきた回避策は、Greg が提案したことを実行することです: 有限のタイムアウトを設定します。残念ながら、これは少しトリッキーになります。待機は、真の eof、低速のネットワーク ファイルシステム、ネットワーク接続の切断、低速のデコーダなど、さまざまな理由で失敗する可能性があります。