プレビュー ピンの実装 (省略可能)
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、レガシ API を使用する既存のコードを、可能であれば新しい API を使用するように書き換えるよう提案しています。]
このトピックでは、DirectShow キャプチャ フィルターにプレビュー ピンを実装する方法について説明します。
フィルターにプレビュー ピンがある場合、プレビュー ピンはキャプチャ ピンによって配信されたデータのコピーを送信する必要があります。 プレビュー ピンからデータを送信する場合にのみ、キャプチャ ピンがフレームをドロップすることはありません。 キャプチャ ピンは常にプレビュー ピンよりも優先されます。
キャプチャ ピンとプレビュー ピンは、同じ形式のデータを送信する必要があります。 そのため、同じメディアの種類を使用して接続する必要があります。 キャプチャ ピンが最初に接続された場合、プレビュー ピンは同じメディアの種類を提供し、他の種類は拒否する必要があります。 プレビュー ピンが最初に接続され、キャプチャ ピンが別のメディアの種類で接続されている場合、プレビュー ピンは新しいメディアの種類を使用して再接続する必要があります。 プレビュー ピンのダウンストリームのフィルターで新しい型が拒否された場合、キャプチャ ピンも型を拒否する必要があります。 IPin::QueryAccept メソッドを使用して、プレビュー ピンからダウンストリームのフィルターに対してクエリを実行し、IFilterGraph::Reconnect メソッドを使用してピンを再接続します。 これらのルールは、フィルター グラフ マネージャーがキャプチャ ピンを再接続する場合にも適用されます。
次の例は、このプロセスの概要を示しています。
// Override CBasePin::CheckMediaType.
CCapturePin::CheckMediaType(CMediaType *pmt)
{
if (m_pMyPreviewPin->IsConnected())
{
// The preview pin is already connected, so query the pin it is
// connected to. If the other pin rejects it, so do we.
hr = m_pMyPreviewPin->GetConnected()->QueryAccept(pmt);
if (hr != S_OK)
{
// The preview pin cannot reconnect with this media type.
return E_INVALIDARG;
}
// The preview pin will reconnect when SetMediaType is called.
}
// Decide whether the capture pin accepts the format.
BOOL fAcceptThisType = ... // (Not shown.)
return (fAcceptThisType? S_OK : E_FAIL);
}
// Override CBasePin::SetMediaType.
CCapturePin::SetMediaType(CMediaType *pmt);
{
if (m_pMyPreviewPin->IsConnected())
{
// The preview pin is already connected, so it must reconnect.
if (m_pMyPreviewPin->GetConnected()->QueryAccept(pmt) == S_OK)
{
// The downstream pin will accept the new type, so it's safe
// to reconnect.
m_pFilter->m_pGraph->Reconnect(m_pMyPreviewPin);
}
else
{
return VFW_E_INVALIDMEDIATYPE;
}
}
// Now do anything that the capture pin needs to set the type.
hr = MyInternalSetMediaType(pmt);
// And finally, call the base-class method.
return CBasePin::SetMediaType(pmt);
}
CPreviewPin::CheckMediaType(CMediaType *pmt)
{
if (m_pMyCapturePin->IsConnected())
{
// The preview pin must connect with the same type.
CMediaType cmt = m_pMyCapturePin->m_mt;
return (*pmt == cmt ? S_OK : VFW_E_INVALIDMEDIATYPE);
}
// Decide whether the preview pin accepts the format. You can use your
// knowledge of which types the capture pin will accept. Regardless,
// when the capture pin connects, the preview pin will reconnect.
return (fAcceptThisType? S_OK : E_FAIL);
}
関連トピック