« レイヤー描画の方が軽いかも | メイン | 単純なVMR9モード »

2005年09月25日

吉里吉里 ムービー拡張日誌2:: オーバーレイでもセグメントループを

    

VMR9を使えば複数の入力ストリームが扱えるので、ダミーストリームを作って、そこからデータが送られるタイミングでEC_UPDATEイベントを送ることによって、フレームの更新タイミングを取得すれば、セグメントループもピリオドイベントも使えるようになると考えていたが、そんなことをしなくてもインプレイスフィルタをレンダーの前に挿入して、そいつがEC_UPDATEイベントを送るようにすれば、更新タイミングを取得できることに気付いた。

描画周りの流れは……
フィルタのReceiveが呼び出されたらCTransInPlaceFilter::Receiveで、出力ピンにつながっている入力ピンのReceive を呼び出す。
入力ピンはレンダーのReceiveを呼び出し、
1. サンプルのレンダリングをスケジュールする (CBaseRenderer::PrepareReceive)。
2. スケジュールされた時間を待機する (CBaseRenderer::WaitForRenderTime)。
3. サンプルをレンダリングする (CBaseRenderer::Render)。
4. サンプルを解放する (CBaseRenderer::ClearPendingSample)。
という流れで処理する。
非同期で処理されている場合は、レンダリングされる前に返ってくる可能性があるが、その時は少しの誤差があるがあきらめることにする。
つまり、CTransInPlaceFilterを継承したクラスのReceiveで次のように書けばOKなはず。

HRESULT hr = CTransInPlaceFilter::Receive(pSample);
if( m_pSink )
  m_pSink->Notify( EC_UPDATE, INT_MAX, NULL );
return hr;

後は、このフィルタをグラフ構築時にレンダーの前に突っ込んでやれば、レンダリング時にイベントが来るはず。



投稿者 Takenori : 2005年09月25日 22:55




comments powered by Disqus
Total : Today : Yesterday : なかのひと