カクタスソフトウェア
カクタスソフトウェア
サウンド MIDI マルチメディア アプリケーション

DMOを列挙する

コンピュータにインストールされているDMOを列挙する手順を示します。

  1. 列挙したいDMOのカテゴリーを指定してDMOの列挙子を取得します。
  2. 列挙子を用いてDMOを列挙します。

列挙子を取得する

列挙子の取得にはDMOEnum()関数を用います。

HRESULT DMOEnum(
    REFGUID     guidCategory,
    DWORD       dwFlags,
    DWORD       cInTypes,
    const DMO_PARTIAL_MEDIATYPE *pInTypes,
    DWORD       cOutTypes,
    const DMO_PARTIAL_MEDIATYPE *pOutTypes,
    IEnumDMO    **ppEnum
);

guidCategory

DMOのカテゴリーを示すGUIDです。カテゴリーには以下の種類があり、取得したいカテゴリーを指定します。すべてのカテゴリーを取得するときはGUID_NULLを指定します。

GUID 説明
DMOCATEGORY_AUDIO_DECODER オーディオデコーダ
DMOCATEGORY_AUDIO_EFFECT オーディオエフェクト
DMOCATEGORY_AUDIO_ENCODER オーディオエンコーダ
DMOCATEGORY_VIDEO_DECODER ビデオデコーダ
DMOCATEGORY_VIDEO_EFFECT ビデオエフェクト
DMOCATEGORY_VIDEO_ENCODER ビデオエンコーダ
DMOCATEGORY_AUDIO_CAPTURE_EFFECT オーディオキャプチャエフェクト

dwFlags

利用が制限されているDMOも含めて列挙するかどうかを示します。利用が制限されているDMOも含めるときはDMO_ENUMF_INCLUDE_KEYEDを指定します。含めないときはゼロを指定します。

cInTypes pInTypes cOutTypes pOutTypes

2組のDWORDとDMO_PARTIAL_MEDIATYPEの引数は、入出力のメディアタイプを指定したいときに用います。指定しないときはそれぞれゼロとNULLを指定します。

ppEnum

IEnumDMOインターフェースを受け取るアドレスです。関数が成功するとインターフェースへのポインターが戻ります。

以下にオーディオエフェクト用DMOの列挙子を取得するコード例を示します。

IEnumDMO* pEnum = NULL; 

HRESULT hr = DMOEnum(
    DMOCATEGORY_AUDIO_EFFECT,   // オーディオエフェクト
    DMO_ENUMF_INCLUDE_KEYED,    // 保護されたDMOを含む
    0, NULL,                    // 入力指定なし
    0, NULL,                    // 出力指定なし
    &pEnum);

以下のコード例はC#用のものです。

このコードを利用するにはDMO関連の関数や構造体をマーシャリングするDMOSysクラスが必要です。詳しくはセクション「DMOのマーシャリング」を参照して下さい。
IEnumDMO iEnum = null;

int result = DMOSys.DMOEnum(
    ref DMOSys.DMOCategoryAudioEffect,
    DMOEnumFlags.IncludeKeyed,
    0, null,
    0, null,
    out iEnum);

DMOを列挙する

IEnumDMOインターフェースのNext()関数を用いてDMOを列挙します。この関数は一度に複数のDMOを取得できますが、一つずつ取得した方が処理は楽でしょう。

HRESULT Next(
    DWORD cItemsToFetch,
    CLSID *pCLSID,
    WCHAR **Names,
    DWORD *pcItemsFetched
);

cItemsToFetch

一度に取得するDMOの数を指定します。

pCLSID

DMO固有のCLSIDが戻る配列です。

Names

DMOのフレンドリ名が戻る配列です。文字の種別はユニコードです。利用が終わった文字列はCoTaskMemFree関数で開放する必要があります。

pcItemsFetched

取得できたDMOの数が戻ります。cItemsToFetchが1のときはNULLを指定することができます。

CLSID   clsidDMO;
WCHAR*  wszName;

while (1)
{
    HRESULT hr = pEnum->Next(1, &clsidDMO, &wszName, NULL);
    if (hr != S_OK)     break;

    // clsidDMO: DMOのCLSID
    // wszName: DMOのフレンドリ名

    CoTaskMemFree(wszName);
}

pEnum->Release();

以下にC#用コード例を示します。

Guid[] clsidCurrentDMO = new Guid[1];   // 要素が1つの配列
IntPtr[] wszDMOName = new IntPtr[1];    // stringをIntPtrで受ける
int ulNumInfoReturned = 0;

while (true)
{
    int result = iEnumDMO.Next(1, clsidCurrentDMO, wszDMOName, out ulNumInfoReturned);
    if (result != S_OK)     break;

    // フレンドリ名とGuidを利用する
    string szName = Marshal.PtrToStringUni(wszDMOName[0]);
    Guid clsidDMO = clsidCurrentDMO[0];

    Marshal.FreeCoTaskMem(wszDMOName[0]); wszDMOName[0] = IntPtr.Zero;
}

Marshal.ReleaseComObject(iEnumDMO); iEnumDMO = null;

フレンドリ名とGuidを格納する配列

C/C++では配列とポインターの表現があいまいなため、要素が一つの配列を変数へのポインターで代用することができます。しかしC#では型付けが厳密なため一つの要素を持つ配列として宣言します。

文字列をIntPtrで受ける

本来文字列はstringで受けるべきですが、利用後FreeCoTaskMemでエリアを開放する必要があるときはIntPtrで受けます。文字列はMarshal.PtrToStringUni関数を用いて抽出します。

ドキュメントの先頭へ

カクタスソフトウェア 技術協力 資料室 資料室の広場 SourceForge.jp お問い合わせ