次の方法で共有


Media Foundation のオーディオ/ビデオ キャプチャ

Microsoft Media Foundation では、オーディオとビデオのキャプチャがサポートされています。 ビデオ キャプチャ デバイスは、UVC クラス ドライバーを介してサポートされており、UVC 1.1 と互換性がある必要があります。 オーディオ キャプチャ デバイスは、Windows Audio Session API (WASAPI) を通じてサポートされます。

キャプチャ デバイスは Media Foundation でメディア ソース オブジェクトによって表され、IMFMediaSource インターフェイスが公開されます。 ほとんどの場合、アプリケーションはこのインターフェイスを直接使用しませんが、ソース リーダー などの上位レベルの API を使用してキャプチャ デバイスを制御します。

キャプチャ デバイスの列挙

システム上のキャプチャ デバイスを列挙するには、次の手順を実行します。

  1. MFCreateAttributes 関数を呼び出して、属性ストアを作成します。

  2. MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE 属性を次のいずれかの値に設定します。

    価値 形容
    MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID オーディオ キャプチャ デバイスを列挙します。
    MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID ビデオ キャプチャ デバイスを列挙します。

     

  3. MFEnumDeviceSources 関数を呼び出します。 この関数は、IMFActivateポインター配列を割り当てます。 各ポインターは、システム上の 1 つのデバイスのアクティブ化オブジェクトを表します。

  4. IMFActivate::ActivateObject メソッドを呼び出して、アクティブ化オブジェクトの 1 つからメディア ソースのインスタンスを作成します。

次の例では、列挙リストの最初のビデオ キャプチャ デバイスのメディア ソースを作成します。

HRESULT CreateVideoCaptureDevice(IMFMediaSource **ppSource)
{
    *ppSource = NULL;

    UINT32 count = 0;

    IMFAttributes *pConfig = NULL;
    IMFActivate **ppDevices = NULL;

    // Create an attribute store to hold the search criteria.
    HRESULT hr = MFCreateAttributes(&pConfig, 1);

    // Request video capture devices.
    if (SUCCEEDED(hr))
    {
        hr = pConfig->SetGUID(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, 
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
            );
    }

    // Enumerate the devices,
    if (SUCCEEDED(hr))
    {
        hr = MFEnumDeviceSources(pConfig, &ppDevices, &count);
    }

    // Create a media source for the first device in the list.
    if (SUCCEEDED(hr))
    {
        if (count > 0)
        {
            hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(ppSource));
        }
        else
        {
            hr = MF_E_NOT_FOUND;
        }
    }

    for (DWORD i = 0; i < count; i++)
    {
        ppDevices[i]->Release();
    }
    CoTaskMemFree(ppDevices);
    return hr;
}

次のようなさまざまな属性について、アクティブ化オブジェクトに対してクエリを実行できます。

  • MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME 属性には、デバイスの表示名が含まれています。 表示名はユーザーに表示するのに適していますが、一意ではない可能性があります。
  • ビデオ デバイスの場合、MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK 属性にはデバイスへのシンボリック リンクが含まれます。 シンボリック リンクは、システム上のデバイスを一意に識別しますが、読み取り可能な文字列ではありません。
  • オーディオ デバイスの場合、MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID 属性にはデバイスのオーディオ エンドポイント ID が含まれます。 オーディオ エンドポイント ID はシンボリック リンクに似ています。 システム上のデバイスを一意に識別しますが、読み取り可能な文字列ではありません。

次の例では、IMFActivate ポインターの配列を取得し、各デバイスの表示名をデバッグ ウィンドウに出力します。

void DebugShowDeviceNames(IMFActivate **ppDevices, UINT count)
{
    for (DWORD i = 0; i < count; i++)
    {
        HRESULT hr = S_OK;
        WCHAR *szFriendlyName = NULL;
    
        // Try to get the display name.
        UINT32 cchName;
        hr = ppDevices[i]->GetAllocatedString(
            MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,
            &szFriendlyName, &cchName);

        if (SUCCEEDED(hr))
        {
            OutputDebugString(szFriendlyName);
            OutputDebugString(L"\n");
        }
        CoTaskMemFree(szFriendlyName);
    }
}

ビデオ デバイスのシンボリック リンクが既にわかっている場合は、デバイスのメディア ソースを作成する別の方法があります。

  1. MFCreateAttributes呼び出して属性ストアを作成します。
  2. MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE 属性を MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUIDに設定します。
  3. MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK 属性をシンボリック リンクに設定します。
  4. MFCreateDeviceSource または MFCreateDeviceSourceActivate関数呼び出します。 前者は、IMFMediaSource ポインターを返します。 後者は、アクティブ化オブジェクトへの IMFActivate ポインターを返します。 アクティブ化オブジェクトを使用して、ソースを作成できます。 (アクティブ化オブジェクトは別のプロセスにマーシャリングできるため、別のプロセスでソースを作成する場合に便利です。詳細については、「アクティブ化オブジェクト する」を参照してください。

次の例では、ビデオ デバイスのシンボリック リンクを取得し、メディア ソースを作成します。

HRESULT CreateVideoCaptureDevice(PCWSTR *pszSymbolicLink, IMFMediaSource **ppSource)
{
    *ppSource = NULL;
    
    IMFAttributes *pAttributes = NULL;
    IMFMediaSource *pSource = NULL;

    HRESULT hr = MFCreateAttributes(&pAttributes, 2);

    // Set the device type to video.
    if (SUCCEEDED(hr))
    {
        hr = pAttributes->SetGUID(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
            );
    }


    // Set the symbolic link.
    if (SUCCEEDED(hr))
    {
        hr = pAttributes->SetString(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
            (LPCWSTR)pszSymbolicLink
            );            
    }

    if (SUCCEEDED(hr))
    {
        hr = MFCreateDeviceSource(pAttributes, ppSource);
    }

    SafeRelease(&pAttributes);
    return hr;    
}

オーディオ エンドポイント ID からオーディオ デバイスを作成する同等の方法があります。

  1. MFCreateAttributes呼び出して属性ストアを作成します。
  2. MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE 属性を MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUIDに設定します。
  3. MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID 属性をエンドポイント ID に設定します。
  4. MFCreateDeviceSource または MFCreateDeviceSourceActivate関数呼び出します。

次の例では、オーディオ エンドポイント ID を取得し、メディア ソースを作成します。

HRESULT CreateAudioCaptureDevice(PCWSTR *pszEndPointID, IMFMediaSource **ppSource)
{
    *ppSource = NULL;
    
    IMFAttributes *pAttributes = NULL;
    IMFMediaSource *pSource = NULL;

    HRESULT hr = MFCreateAttributes(&pAttributes, 2);

    // Set the device type to audio.
    if (SUCCEEDED(hr))
    {
        hr = pAttributes->SetGUID(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID
            );
    }

    // Set the endpoint ID.
    if (SUCCEEDED(hr))
    {
        hr = pAttributes->SetString(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID,
            (LPCWSTR)pszEndPointID
            ); 
    }

    if (SUCCEEDED(hr))
    {
        hr = MFCreateDeviceSource(pAttributes, ppSource);
    }

    SafeRelease(&pAttributes);
    return hr;    
}

キャプチャ デバイスを使用する

キャプチャ デバイスのメディア ソースを作成したら、ソース リーダー を使用してデバイスからデータを取得します。 ソース リーダーは、キャプチャ オーディオ データまたはビデオ フレームを含むメディア サンプルを提供します。 次の手順は、アプリケーションのシナリオによって異なります。

  • ビデオ プレビュー: Microsoft Direct3D または Direct2D を使用してビデオを表示します。
  • ファイル キャプチャ: シンク ライター を使用してファイルをエンコードします。
  • オーディオ プレビュー: WASAPI 使用します。

オーディオ キャプチャとビデオ キャプチャを組み合わせる場合は、集約メディア ソースを使用します。 集約メディア ソースには、メディア ソースのコレクションが含まれており、すべてのストリームが 1 つのメディア ソース オブジェクトに結合されます。 集約メディア ソースのインスタンスを作成するには、MFCreateAggregateSource 関数を呼び出します。

キャプチャ デバイスをシャットダウンする

キャプチャ デバイスが不要になったら、MFCreateDeviceSourceまたは IMFActivate::ActivateObjectを呼び出して取得した IMFMediaSource オブジェクトでShutdown を呼び出して、デバイスをシャットダウンする必要があります。 Shutdown 呼び出しに失敗すると、Shutdown が呼び出されるまで、システムが IMFMediaSource リソース 参照を保持する可能性があるため、メモリ リーク 発生する可能性があります。

if (g_pSource)
{
    g_pSource->Shutdown();
    g_pSource->Release();
    g_pSource = NULL;
}

キャプチャ デバイスへのシンボリック リンクを含む文字列を割り当てた場合は、このオブジェクトも解放する必要があります。

    CoTaskMemFree(g_pwszSymbolicLink);
    g_pwszSymbolicLink = NULL;

    g_cchSymbolicLink = 0;

オーディオ/ビデオ キャプチャ