Share via


データのフラッシュ

[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayerIMFMediaEngineAudio/Video Capture を使用することを強くお勧めします。 Microsoft は、レガシ API を使用する既存のコードを、可能であれば新しい API を使用するように書き換えるよう提案しています。]

次の擬似コードは、 IPin::BeginFlush メソッドを実装する方法を示しています。

HRESULT CMyInputPin::BeginFlush()
{
    CAutoLock lock_it(m_pLock);
   
    // First, make sure the Receive method will fail from now on.
    HRESULT hr = CBaseInputPin::BeginFlush();
    
    // Force downstream filters to release samples. If our Receive method
    // is blocked in GetBuffer or Deliver, this will unblock it.
    for (each output pin)
    {
        hr = pOutputPin->DeliverBeginFlush();
    }

    // Unblock our Receive method if it is waiting on an event.
    SetEvent(m_hSomeEventThatReceiveNeedsToWaitOn);

    // At this point, the Receive method can't be blocked. Make sure 
    // it finishes, by taking the streaming lock. (Not necessary if this 
    // is the last step.)
    { 
        CAutoLock lock_2(&m_csReceive);

        /* Now it's safe to do anything that would crash or hang 
           if Receive were executing. */
    }
    return hr;
}

フラッシュが開始されると、 BeginFlush メソッドはフィルター ロックを受け取り、状態の変更をシリアル化します。 アプリケーション スレッドでフラッシュが行われ、ストリーミング スレッドが Receive 呼び出しの途中にある可能性があるため、ストリーミング ロックを取得しても安全ではありません。 ピンは 、Receive がブロックされていないこと、および Receive への後続 の呼び出しが失敗することを保証する必要があります。 CBaseInputPin::BeginFlush メソッドは、内部フラグ CBaseInputPin::m_bFlushing を設定します。 フラグが TRUE の場合、 Receive メソッドは失敗します。

BeginFlush 呼び出しをダウンストリームに配信することで、ピンは、すべてのダウンストリーム フィルターがサンプルを解放し、Receive 呼びしから戻っていることを保証します。 これにより、 GetBuffer または Receive の待機中に入力ピンがブロックされないことが保証 されます。 Pin の Receive メソッドがイベントを待機する場合 (リソースを取得する場合など)、 BeginFlush メソッドはイベントを設定して待機を強制的に終了させる必要があります。 この時点で、 Receive メソッドは確実に返されます。 また、m_bFlushing フラグを指定すると、新しい Receive 呼び出しで作業が行われるのを防ぐことができます。

一部のフィルターでは、 BeginFlush が行う必要があるすべてです。 EndFlush メソッドは、サンプルの受信を再開できることをフィルターに通知します。 他のフィルターでは、 BeginFlush の変数またはリソースを使用する必要があります。これは Receive でも使用されます。 その場合、フィルターは最初にストリーミング ロックを保持する必要があります。 デッドロックが発生する可能性があるため、前の手順の前にこれを行わないでください。

EndFlush メソッドはフィルター ロックを保持し、呼び出しをダウンストリームに伝達します。

HRESULT CMyInputPin::EndFlush()
{
    CAutoLock lock_it(m_pLock);
    for (each output pin)
        hr = pOutputPin->DeliverEndFlush();
    return CBaseInputPin::EndFlush();
}

CBaseInputPin::EndFlush メソッドは、m_bFlushing フラグを FALSE にリセットし、Receive メソッドがサンプルの受信を再開できるようにします。 これは EndFlush の最後の手順である必要があります。フラッシュが完了し、すべてのダウンストリーム フィルターに通知されるまで、ピンはサンプルを受信できません。

スレッドとクリティカル セクション