Microsoft DirectX 8.0

デバイスとフィルタの列挙

アプリケーションが、ユーザーのシステムにある特定のフィルタを見つけなければならないことがある。たとえば、ビデオ キャプチャ アプリケーションは、使用可能なキャプチャ デバイスのリストを表示する必要がある。Microsoft® DirectShow® はコンポーネントベースのアーキテクチャを使用しているため、システムにどのフィルタがインストールされているかが実行時までわからないことがある。ハードウェア デバイスを表すフィルタの場合は特にそうである。以下に示す DirectShow の 2 つのコンポーネントによって、フィルタを見つけやすくなる。

ここで議論する列挙子は、COM の列挙インターフェイスで使用される標準形に従う。詳細については、Microsoft Platform SDK の IEnumXXXX のトピックを参照すること。このトピックは、以下のセクションで構成される。

システム デバイス列挙子の使用

システム デバイス列挙子は、ユーザーのシステムに登録されているフィルタをカテゴリごとに列挙するための統一された方法を提供する。さらに、同じフィルタが複数のデバイスをサポートしている場合でも、それぞれのハードウェア デバイスを区別できる。このことは、Windows Driver Model (WDM) および KSProxy フィルタを使用するデバイスの場合に特に有用である。たとえば、ユーザーが複数の WDM ビデオ キャプチャ デバイスを持ち、それらすべてが同じフィルタによってサポートされることがある。システム デバイス列挙子は、これらを別々のデバイス インターフェイスとして扱う。

システム デバイス列挙子は、オーディオ キャプチャやビデオ圧縮など、特定カテゴリ向けの列挙子を作成することで機能する。カテゴリ列挙子は、そのカテゴリ内の各デバイスに対する一意のモニカを返す。また、関連のあるプラグ アンド プレイ デバイスを自動的にカテゴリに含める。カテゴリのリストについては、「フィルタ カテゴリ」を参照すること。

システム デバイス列挙子を作成するには、クラス識別子 (CLSID) に CLSID_SystemDeviceEnum を指定して CoCreateInstance を呼び出す。カテゴリ列挙子を入手するには、そのカテゴリの CLSID を使って ICreateDevEnum::CreateClassEnumerator を呼び出す。カテゴリ列挙子は IEnumMoniker インターフェイスをサポートしていて、このインターフェイスを使ってそれぞれのモニカを列挙できる。モニカの IMoniker::BindToObject を呼び出してデバイス オブジェクトを生成および初期化するか、IMoniker::BindToStorage を呼び出してデバイスのフレンドリ名を取得する (たとえば、ユーザー インターフェイスのリスト ボックスを満たすため)。次の図にこの処理を示す。

デバイスの列挙

以下の例に、システム デバイス列挙子のインスタンスを生成し、それを使ってビデオ コンプレッサ デバイスを列挙する方法を示す。簡単であるため、エラー チェックは行っていない。

ICreateDevEnum *pSysDevEnum = NULL;
CoCreateInstance(CLSID_SystemDeviceEnum, 
    NULL, CLSCTX_INPROC, IID_ICreateDevEnum, 
    (void **)&pSysDevEnum);

IEnumMoniker *pEnumCat = NULL;
pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat, 0);

IMoniker *pMoniker;
ULONG cFetched;
while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
    IPropertyBag *pPropBag;
    pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);

    VARIANT varName;
    varName.vt = VT_BSTR;
    pPropBag->Read(L"FriendlyName", &varName, 0);

    // この名前を使って何かを行う。

    SysFreeString(varName.bstrVal);
    pPropBag->Release();
    pMoniker->Release();
}
pEnumCat->Release();
pSysDevEnum->Release();

フィルタ マッパーの使用

フィルタ マッパーは、さまざまな検索条件に基づいてフィルタを列挙する COM オブジェクトである。フィルタ マッパーはシステム デバイス列挙子ほど効率的ではないので、特定のカテゴリのフィルタが必要な場合は、システム デバイス列挙子を使う方がよい。しかし、特定のメディア タイプの組み合わせをサポートするが、はっきりしたカテゴリには入らないフィルタを見つける場合は、フィルタ マッパーを使用する必要がある。その例が、レンダリング フィルタやデコーダ フィルタである。

フィルタ マッパーは、IFilterMapper2 インターフェイスをサポートしている。フィルタを捜すには、IFilterMapper2::EnumMatchingFilters を呼び出す。このメソッドは、検索条件を定義するパラメータをいくつか受け取り、条件に一致するフィルタの列挙子を返す。この列挙子は IEnumMoniker をサポートし、一致するそれぞれのフィルタに一意のモニカを与える。

以下の例では、デジタル ビデオ (DV) 入力を受け取り、1 つ以上の出力ピンを持つ任意のメディア タイプのフィルタを列挙している (DV ビデオ デコーダ フィルタ がこの条件に合致する)。

IFilterMapper2 *pMapper = NULL;
IEnumMoniker *pEnum = NULL;

CoCreateInstance(CLSID_FilterMapper2, 
    NULL, CLSCTX_INPROC, IID_IFilterMapper2, 
    (void **) &pMapper);
    
GUID arrayInTypes[2];
arrayInTypes[0] = MEDIATYPE_Video;
arrayInTypes[1] = MEDIASUBTYPE_dvsd;

hr = pMapper->EnumMatchingFilters(
        &pEnum,
        0,                  // 予約済み
        TRUE,               // 完全一致を使用?
        MERIT_DO_NOT_USE+1, // 最小のメリット
        TRUE,               // 1 つ以上の入力ピン?
        1,                  // 入力のメジャー タイプ/サブタイプの対の数
        arrayInTypes,       // 入力のメジャー タイプ/サブタイプの対の配列
        NULL,               // 入力メディア
        NULL,               // 入力ピンのカテゴリ
        FALSE,              // レンダラでなければならないか?
        TRUE,               // 1 つ以上の出力ピン?
        0,                  // 出力のメジャー タイプ/サブタイプの対の数
        NULL,               // 出力のメジャー タイプ/サブタイプの対の配列 
        NULL,               // 出力メディア
        NULL);              // 出力ピンのカテゴリ

// 前の例のように、pEnum を使って列挙する。

EnumMatchingFilters メソッドには、上の例にコメントを付けたようにかなりの数のパラメータがある。この例で重要なのは以下のパラメータである。