2012-01-23 6 views
2

DirectShowを使用していくつかの画面を取得するためのビデオを再生しています。IMediaSeekingでビデオの終わりを検出する

私はIMediaControl->RunIVMRWindowlessControl->GetCurrentImage、そしてIMediaSeeking->SetPositionsを呼び出すことでこれをループで実行しています。

問題は、ビデオが終了したときに検出できないことです。 IMediaSeeking->SetPositionsは常に同じ値(S_FALSE)を返します。 IMediaControl->Runも常にS_FALSEを返します。私はまた、EC_COMPLETEを確認するためにIMediaControl->Runへの呼び出しの後にIMediaEvent->GetEventを試しましたが、代わりに(常に)EC_CLOCK_CHANGEDを返します。

動画の最後を検出するにはどうすればよいですか?おかげ

UPDATE:こう何かのような

long eventCode = 0; 
    LONG_PTR ptrParam1 = 0; 
    LONG_PTR ptrParam2 = 0; 
    long timeoutMs = INFINITE; 

    while (SUCCEEDED(pEvent->GetEvent(&eventCode, &ptrParam1, &ptrParam1, timeoutMs))) 
    { 
     if (eventCode == EC_COMPLETE) 
     { 
      break; 
     } 

     // Free the event data. 
     hr = pEvent->FreeEventParams(eventCode, ptrParam1, ptrParam1); 
     if (FAILED(hr)) 
     { 
      break; 
     } 
    } 

ブロック数のイベントの後:$ 53(EC_VMR_RENDERDEVICE_SET)、0x0Dを(EC_CLOCK_CHANGED)、0x0Eの(EC_PAUSED)、のGetEventへの次の呼び出しをブロックしているとビデオがレンダリングされますIVideoWindow

+0

DirectShowイベント処理は別のスレッドで実行されますか? –

+0

現在のウィンドウと同じスレッドにあります。 – cprogrammer

答えて

2

IMediaEvent->GetEventを実行する必要がありますが、EC_CLOCK_CHANGEDだけでなく、さまざまなイベントが発生することに注意してください。受信を維持し、EC_COMPLETEを取得する必要があります。 MSDNのStep 6: Handle Graph Eventsで詳しく説明しています。

+0

trueですが、イベントを列挙するのがブロックされているようです。私はいくつかのコードで私の質問を更新しました。 – cprogrammer

+0

'INFINITE'タイムアウトを指定すると、確実にブロックされます。そのため、ウィンドウメッセージやイベントオブジェクトを使用して、新しいイベントに通知する方法をMSDNで調べる必要があります。 –

+0

私はINFINITEのパラメータに気付きましたが、私は任意の値(例:3000)がこれに対する正しい解決策ではないと思います。ですから、値を列挙することは正しい方法ではなく、イベント(wnd msgまたはobjectを使用して)に登録する必要があることを理解しています。私の見解では(これはDirectShowとの最初の接触です)、これは 'IMediaEvent'オブジェクトを列挙して私がやっていることです。あなたはより具体的にすることができますか、私はより多くの情報を見つけることができるmsdnでより正確な場所を提供できますか?ありがとう – cprogrammer

1

フィルタグラフの状態をIMediaControl::GetStateで確認し、停止しているかどうかを確認してください。また、動画の再生時間をIMediaSeeking::GetDurationから得ることもできます。

もう1つの方法はevent signalingです。このイベント処理はオフスレッドにすることができます。

関連する問題