다음을 통해 공유


DirectShow 애플리케이션에 대한 디바이스 역할

참고

MMDevice API는 디바이스 역할을 지원합니다. 그러나 Windows Vista의 사용자 인터페이스는 이 기능에 대한 지원을 구현하지 않습니다. 디바이스 역할에 대한 사용자 인터페이스 지원은 이후 버전의 Windows에서 구현될 수 있습니다. 자세한 내용은 Windows Vista의 디바이스 역할을 참조하세요.

 

DirectShow API는 애플리케이션이 특정 디바이스 역할에 할당된 오디오 엔드포인트 디바이스를 선택할 수 있는 수단을 제공하지 않습니다. 그러나 Windows Vista에서는 핵심 오디오 API를 DirectShow 애플리케이션과 함께 사용하여 디바이스 역할에 따라 디바이스를 선택할 수 있습니다. 핵심 오디오 API의 도움으로 애플리케이션은 다음을 수행할 수 있습니다.

  • 사용자가 특정 디바이스 역할에 할당한 오디오 엔드포인트 디바이스를 식별합니다.
  • 오디오 엔드포인트 디바이스를 캡슐화하는 IBaseFilter 인터페이스를 사용하여 DirectShow 오디오 렌더링 필터를 만듭니다.
  • 필터를 통합하는 DirectShow 그래프를 빌드합니다.

DirectShow 및 IBaseFilter에 대한 자세한 내용은 Windows SDK 설명서를 참조하세요.

다음 코드 예제에서는 특정 디바이스 역할에 할당된 렌더링 엔드포인트 디바이스를 캡슐화하는 DirectShow 오디오 렌더링 필터를 만드는 방법을 보여 줍니다.

//-----------------------------------------------------------
// Create a DirectShow audio rendering filter that
// encapsulates the audio endpoint device that is currently
// assigned to the specified device role.
//-----------------------------------------------------------
#define EXIT_ON_ERROR(hres)  \
              if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk)  \
              if ((punk) != NULL)  \
                { (punk)->Release(); (punk) = NULL; }

// This application's audio session GUID
const GUID guidAudioSessionId = {
    0xb13ff52e, 0xa5cf, 0x4fca,
    {0x9f, 0xc3, 0x42, 0x26, 0x5b, 0x0b, 0x14, 0xfb}
};

HRESULT CreateAudioRenderer(ERole role, IBaseFilter** ppAudioRenderer)
{
    HRESULT hr = S_OK;
    IMMDeviceEnumerator *pEnumerator = NULL;
    IMMDevice *pDevice = NULL;

    if (ppAudioRenderer == NULL)
    {
        return E_POINTER;
    }

    // Activate the IBaseFilter interface on the
    // audio renderer with the specified role.
    hr = CoCreateInstance(CLSID_MMDeviceEnumerator,
                          NULL, CLSCTX_INPROC_SERVER,
                          __uuidof(IMMDeviceEnumerator),
                          (void**)&pEnumerator);
    EXIT_ON_ERROR(hr)

    hr = pEnumerator->GetDefaultAudioEndpoint(eRender, role,
                                              &pDevice);
    EXIT_ON_ERROR(hr)

    DIRECTX_AUDIO_ACTIVATION_PARAMS  daap;
    daap.cbDirectXAudioActivationParams = sizeof(daap);
    daap.guidAudioSession = guidAudioSessionId;
    daap.dwAudioStreamFlags = AUDCLNT_STREAMFLAGS_CROSSPROCESS;

    PROPVARIANT  var;
    PropVariantInit(&var);

    var.vt = VT_BLOB;
    var.blob.cbSize = sizeof(daap);
    var.blob.pBlobData = (BYTE*)&daap;

    hr = pDevice->Activate(__uuidof(IBaseFilter),
                           CLSCTX_ALL, &var,
                           (void**)ppAudioRenderer);
    EXIT_ON_ERROR(hr)

Exit:
    SAFE_RELEASE(pEnumerator);
    SAFE_RELEASE(pDevice);
    return hr;
}

앞의 코드 예제에서 CreateAudioRenderer 함수는 디바이스 역할(eConsole, eMultimedia 또는 eCommunications)을 입력 매개 변수로 허용합니다. 두 번째 매개 변수는 함수가 instance IBaseFilter 인터페이스의 주소를 쓰는 포인터입니다. 또한 이 예제에서는 IMMDevice::Activate 메서드를 사용하여 IBaseFilter instance 오디오 스트림을 애플리케이션별 세션 GUID(guidAudioSessionId 상수로 지정됨)를 사용하여 프로세스 간 오디오 세션에 할당하는 방법을 보여 줍니다. 활성화 호출의 세 번째 매개 변수는 세션 GUID 및 프로세스 간 플래그가 포함된 구조를 가리킵니다. 사용자가 애플리케이션의 여러 인스턴스를 실행하는 경우 모든 인스턴스의 오디오 스트림은 동일한 세션 GUID를 사용하므로 동일한 세션에 속합니다.

또는 호출자는 활성화 호출에서 NULL을 세 번째 매개 변수로 지정하여 스트림을 기본 세션에 세션 GUID 값이 GUID_NULL 프로세스별 세션으로 할당할 수 있습니다. 자세한 내용은 IMMDevice::Activate를 참조하세요.

레거시 오디오 API와의 상호 운용성