WDM クラス ドライバー フィルター
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、レガシ API を使用する既存のコードを、可能であれば新しい API を使用するように書き換えるよう提案しています。]
キャプチャ デバイスで Windows ドライバー モデル (WDM) ドライバーを使用している場合、グラフにはキャプチャ フィルターの上流にある特定のフィルターが必要になる場合があります。 これらのフィルターは、ストリーム クラス ドライバー フィルターまたは WDM フィルターと呼ばれます。 ハードウェアによって提供される追加機能がサポートされます。 たとえば、TV チューナー カードには、チャネルを設定するための機能があります。 対応するフィルターは、IAMTVTuner インターフェイスを公開する TV チューナー フィルターです。 この機能をアプリケーションで使用できるようにするには、TV チューナー フィルターをキャプチャ フィルターに接続する必要があります。
ICaptureGraphBuilder2 インターフェイスは、グラフに WDM フィルターを追加する最も簡単な方法を提供します。 グラフの作成中に、ある時点で FindInterface または RenderStream を呼び出します。 これらの方法のいずれかを使用すると、必要な WDM フィルターが自動的に検索され、キャプチャ フィルターに接続されます。 このセクションの残りの部分では、WDM フィルターを手動で追加する方法について説明します。 ただし、推奨される方法は、これらの ICaptureGraphBuilder2 メソッドのいずれかを呼び出す方法であることに注意してください。
WDM フィルターのピンは、1 つ以上のメディアをサポートします。 メディアは、バスなどの通信方法を定義します。 同じメディアをサポートするピンを接続する必要があります。 REGPINMEDIUM 構造体は、カーネル ストリーミング ドライバーに使用されるKSPIN_MEDIUM構造体に相当し、DirectShow でメディアを定義します。 REGPINMEDIUM 構造体の clsMedium メンバーは、メディアのクラス識別子 (CLSID) を指定します。 ピンのメディアを取得するには、 IKsPin::KsQueryMediums メソッドを 呼び出します。 このメソッドは、 KSMULTIPLE_ITEM 構造体を含むメモリ ブロックへのポインターを返し、その後に 0 個以上の REGPINMEDIUM 構造体が続きます。 各 REGPINMEDIUM 構造体は、ピンがサポートするメディアを識別します。
メディアの CLSID が GUID_NULL または KSMEDIUMSETID_Standard の場合は、ピンを接続しないでください。 これらは、ピンがメディアをサポートしていないことを示す既定値です。
また、フィルターがそのピンの接続されたインスタンスを 1 つだけ必要とする場合を除き、ピンを接続しないでください。 それ以外の場合、アプリケーションは接続を持つべきではないさまざまなピンを接続しようとする可能性があります。これにより、プログラムが応答を停止する可能性があります。 必要なインスタンスの数を調べるには、次のコード例に示すように、KSPROPERTY_PIN_NECESSARYINSTANCES プロパティ セットを取得します。 (簡潔にするために、この例ではリターン コードをテストしたり、インターフェイスを解放したりしません。もちろん、アプリケーションでは両方を実行する必要があります)。
// Obtain the pin factory identifier.
IKsPinFactory *pPinFactory;
hr = pPin->QueryInterface(IID_IKsPinFactory, (void **)&pPinFactory);
ULONG ulFactoryId;
hr = pPinFactory->KsPinFactory(&ulFactoryId);
// Get the "instance" property from the filter.
IKsControl *pKsControl;
hr = pFilter->QueryInterface(IID_IKsControl, (void **)&pKsControl);
KSP_PIN ksPin;
ksPin.Property.Set = KSPROPSETID_Pin;
ksPin.Property.Id = KSPROPERTY_PIN_NECESSARYINSTANCES;
ksPin.Property.Flags = KSPROPERTY_TYPE_GET;
ksPin.PinId = ulFactoryId;
ksPin.Reserved = 0;
KSPROPERTY ksProp;
ULONG ulInstances, bytes;
pKsControl->KsProperty((PKSPROPERTY)&ksPin, sizeof(ksPin),
&ulInstances, sizeof(ULONG), &bytes);
if (hr == S_OK && bytes == sizeof(ULONG))
{
if (ulInstances == 1)
{
// Filter requires one instance of this pin.
// This pin is OK.
}
}
次の擬似コードは、WDM フィルターを検索して接続する方法を示す非常に簡単なアウトラインです。 多くの詳細は省略されており、アプリケーションで実行する必要がある一般的な手順のみを示します。
Add supporting filters:
{
foreach input pin:
skip if (pin is connected)
Get pin medium
skip if (medium is GUID_NULL or KSMEDIUMSETID_Standard)
Query filter for KSPROPERTY_PIN_NECESSARYINSTANCES property
skip if (necessary instances != 1)
Match an existing pin || Find a matching filter
}
Match an existing pin:
{
foreach filter in the graph
foreach unconnected pin
Get pin medium
if (mediums match)
connect the pins
}
Find a matching filter:
{
Query the filter graph manager for IFilterMapper2.
Find a filter with an output pin that matches the medium.
Add the filter to the graph.
Connect the pins.
Add supporting filters. (Recursive call.)
}
関連トピック