動的再接続
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
ほとんどの DirectShow フィルターでは、グラフがアクティブにデータをストリーミングしている間は、ピンを再接続できません。 ピンを再接続する前に、アプリケーションでグラフを停止する必要があります。 ただし、一部のフィルターでは、グラフの実行中にピン再接続がサポートされています。これは動的再接続と呼ばれるプロセスです。 これは、アプリケーションまたはグラフ内のフィルターによって行うことができます。
例として、次の図のグラフを考えてみましょう。
動的再接続のシナリオの 1 つは、グラフの実行中にグラフからフィルター 2 を削除し、別のフィルターに置き換えることです。 このシナリオを機能させるには、次のことが当てはまる必要があります。
- フィルター 3 (ピン D) の入力ピンは 、IPinConnection インターフェイスをサポートしている必要があります。 このインターフェイスを使用すると、フィルターを停止せずにピンを再接続できます。
- フィルター 1 (ピン A) の出力ピンは、再接続の実行中にメディア データのフローをブロックできる必要があります。 再接続中に、ピン A とピン D の間を移動できるデータはありません。 一般に、これは、出力ピンが IPinFlowControl インターフェイスをサポートする必要があります。 ただし、Filter 1 が再接続を開始するフィルターである場合は、独自のデータ フローをブロックするための内部メカニズムが存在する可能性があります。
動的再接続には、次の手順が含まれます。
- ピン A からデータ ストリームをブロックします。
- ピン A を再接続して、新しい中間フィルターを使用して D をピン留めします。
- ピン A のブロックを解除して、データが再び流れ始めます。
手順 1. データ ストリームをブロックする
データ ストリームをブロックするには、ピン A で IPinFlowControl::Block を呼び出します。このメソッドは、非同期または同期的に呼び出すことができます。 メソッドを 非同期的に呼び出すには、Win32 イベント オブジェクトを作成し、イベント ハンドルを Block メソッドに渡します。 メソッドはすぐに返されます。 WaitForSingleObject などの関数を使用して、イベントがシグナル通知されるのを待ちます。 ピンは、データ フローがブロックされたときにイベントを通知します。 次に例を示します。
// Create an event
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (hEvent != NULL)
{
// Block the data flow.
hr = pFlowControl->Block(AM_PIN_FLOW_CONTROL_BLOCK, hEvent);
if (SUCCEEDED(hr))
{
// Wait for the pin to finish.
DWORD dwRes = WaitForSingleObject(hEvent, dwMilliseconds);
}
}
メソッドを 同期的に呼び出すには、イベント ハンドルの代わりに 値 NULL を 渡すだけです。 これで、メソッドは操作が完了するまでブロックされます。 これは、ピンが新しいサンプルを提供する準備ができるまで発生しない可能性があります。 フィルターが一時停止されている場合は、任意の時間がかかる場合があります。 そのため、メイン アプリケーション スレッドから同期呼び出しを行わないでください。 ワーカー スレッドを使用するか、メソッドを非同期的に呼び出します。
手順 2. ピンを再接続する
ピンを再接続するには、フィルター グラフ マネージャーで IGraphConfig インターフェイスを照会し、IGraphConfig::Reconnect または IGraphConfig::Reconfigure を呼び出します。 Reconnect メソッドを使用する方が簡単です。次の処理を行います。
- 中間フィルター (例ではフィルター 2) を停止し、グラフから削除します。
- 必要に応じて、新しい中間フィルターを追加します。
- すべてのピンを接続します。
- グラフの状態に合わせて、新しいフィルターを一時停止または実行します。
Reconnect メソッドには、ピン接続のメディアの種類と使用する中間フィルターを指定するために使用できる省略可能なパラメーターがいくつかあります。 次に例を示します。
pGraph->AddFilter(pNewFilter, L"New Filter for the Graph");
pConfig->Reconnect(
pPinA, // Reconnect this output pin...
pPinD, // ... to this input pin.
pMediaType, // Use this media type.
pNewFilter, // Connect them through this filter.
NULL,
0);
詳細については、リファレンス ページを参照してください。 Reconnect メソッドの柔軟性が十分でない場合は、Reconfigure メソッドを使用できます。このメソッドは、アプリケーション定義のコールバック メソッドを呼び出してピンを再接続します。 このメソッドを使用するには、アプリケーションで IGraphConfigCallback インターフェイスを実装します。
Reconfigure を呼び出す前に、前に説明したように、出力ピンからのデータ フローをブロックします。 次に、再接続するグラフのセクションで保留中のデータをプッシュします。
- 再接続チェーンの最も下流にある入力ピン (例ではピン D) で IPinConnection::NotifyEndOfStream を呼び出します。 Win32 イベントにハンドルを渡します。
- データ フローをブロックした出力ピンのすぐ下流にある入力ピンで IPin::EndOfStream を呼び出します。 (この例では、データ フローがピン A でブロックされているため、ピン B で EndOfStream を呼び出します)。
- イベントが通知されるまで待ちます。 入力ピン (ピン D) は、ストリームの終了通知を受信したときにイベントを通知します。 これは、データがピン間を移動せず、呼び出し元がピンを安全に再接続できることを示します。
IGraphConfig::Reconnect メソッドは、前の手順を自動的に処理します。 これらの手順は、 Reconfigure メソッドを使用している場合にのみ実行する必要があります。
データがグラフにプッシュされたら、 Reconfigure を呼び出し、 IGraphConfigCallback コールバック インターフェイスへのポインターを渡します。 Filter Graph Manager は、指定した IGraphConfigCallback::Reconfigure メソッドを呼び出します。
手順 3. Data Flowのブロックを解除する
ピンを再接続したら、最初のパラメーターの値が 0 の IPinFlowControl::Block を呼び出して、データ フローのブロックを解除します。
注意
動的再接続がフィルターによって実行される場合は、注意する必要があるスレッド処理の問題がいくつかあります。 フィルター グラフ マネージャーがフィルターの停止を試みると、フィルターが停止するのをグラフが待機すると同時に、フィルターがグラフを介してデータがプッシュされるのを待機しているため、デッドロックが発生する可能性があります。 デッドロックの可能性を防ぐために、このセクションで説明する一部のメソッドは Win32 イベントを処理します。 フィルター グラフ マネージャーがフィルターを停止しようとすると、フィルターによってイベントが通知されます。 詳細については、「 IGraphConfig 」と「 IPinConnection」を参照してください。
関連トピック