次の方法で共有


EC_REPAINT 通知の処理

EC_REPAINT 通知は、レンダラがポーズまたは停止状態のときだけ送信される。この通知は、レンダラがデータを必要としていることをフィルタ グラフ マネージャに通知する。これらの通知の 1 つを受け取ったときにフィルタ グラフが停止状態であった場合、フィルタ グラフ マネージャはフィルタ グラフをポーズ状態にし、(GetState 呼び出しによって) すべてのフィルタがデータを受け取るのを待ち、再度フィルタ グラフを停止させる。停止状態のとき、ビデオ レンダラは後続の WM_PAINT メッセージを処理できるようにイメージを保持しなければならない。

したがって、停止またはポーズ状態でビデオ レンダラが WM_PAINT メッセージを受け取り、ウィンドウを描画するものがない場合は、EC_REPAINT をフィルタ グラフ マネージャに送信しなければならない。EC_REPAINT 通知がポーズ状態で受け取られた場合、フィルタ グラフ マネージャは、現在位置を使って IMediaPosition::put_CurrentPosition を呼び出す (すなわち現在位置へのシーク)。これにより、ソース フィルタはフィルタ グラフをフラッシュし、新しいデータがフィルタ グラフを介して送信される。

レンダラは、一度にこれらの通知のうち 1 つだけを送信しなければならない。したがって、通知を送信した場合、レンダラはいくつかのサンプルが配送されるまでそれ以上のデータが送信されないことを保証しなければならない。これを行う従来の方法は、フラグを使って再描画が送信可能かどうかを示す方法である。この場合、フラグは、EC_REPAINT 通知が送信された後にオフに設定される。このフラグは、データが配送されたり入力ピンがフラッシュされたときにリセットされなければならない。ただし、エンドオブストリームが入力ピンに通知済みの場合はこれに当てはまらない。

レンダラがその EC_REPAINT 通知を監視しないと、フィルタ グラフ マネージャは EC_REPAINT 要求であふれることになる (比較的負荷が高い処理になる)。たとえば、描画するイメージをレンダラが持たず、フルドラッグ操作で別のウィンドウがレンダラのウィンドウ上をドラッグした場合、レンダラは複数の WM_PAINT メッセージを受け取る。これらのメッセージのうちの最初のものだけがレンダラからフィルタ グラフ マネージャへの EC_REPAINT イベント通知を生成しなければならない。

レンダラは、その入力ピンを EC_REPAINT 通知の第 1 パラメータとして送信しなければならない。これにより、アタッチされた出力ピンに対して IMediaEventSink の問い合わせが行われ、サポートされている場合は EC_REPAINT 通知が最初に送信される。これにより、フィルタ グラフ以前に出力ピンが再描画を扱うことが可能になる。フィルタ グラフが停止状態の場合、デコミットされたレンダラ アロケータからのバッファを利用することができないので、この処理は行われない。

出力ピンが要求を処理することができず、フィルタ グラフが実行中の場合、EC_REPAINT 通知は無視される。出力ピンは、IMediaEventSink::Notify から NOERROR (S_OK) を返すことによって、再描画要求を正常に処理したことを通知しなければならない。出力ピンはフィルタ グラフ マネージャのワーカー スレッドで呼び出される。すなわち、レンダラが出力ピンを直接呼び出さないようにしてデッドロックが回避される。フィルタ グラフが停止状態またはポーズ状態で出力が要求を処理しない場合は、デフォルトの処理が行われる。