Поделиться через


Роли устройств для приложений DirectShow

Примечание.

API MMDevice поддерживает роли устройств. Однако пользовательский интерфейс в Windows Vista не реализует поддержку этой функции. Поддержка пользовательского интерфейса для ролей устройств может быть реализована в будущей версии Windows. Дополнительные сведения см. в статье "Роли устройств" в Windows Vista.

 

API DirectShow не предоставляет средства для приложения, чтобы выбрать устройство аудио конечной точки, назначенное определенной роли устройства. Однако в Windows Vista основные API аудио можно использовать в сочетании с приложением DirectShow, чтобы включить выбор устройства на основе роли устройства. С помощью основных ИНТЕРФЕЙСов API аудио, приложение может:

  • Определите устройство конечной точки звука, назначенное пользователю определенной роли устройства.
  • Создайте фильтр отрисовки звука DirectShow с интерфейсом IBaseFilter , который инкапсулирует устройство аудио конечной точки.
  • Создайте граф DirectShow, который включает фильтр.

Дополнительные сведения о DirectShow и IBaseFilter см. в документации по пакету SDK для Windows.

В следующем примере кода показано, как создать фильтр отрисовки аудио 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) в качестве входного параметра. Второй параметр — это указатель, с помощью которого функция записывает адрес экземпляра интерфейса IBaseFilter. Кроме того, в примере показано, как использовать метод IMMDevice::Activate для назначения аудиопотока в экземпляре IBaseFilter межпроцессному звуковому сеансу с GUID сеанса для конкретного приложения (задается константой guidAudioSessionId). Третий параметр в активации указывает на структуру, содержащую GUID сеанса и флаг перекрестного процесса. Если пользователь запускает несколько экземпляров приложения, звуковые потоки из всех экземпляров используют один и тот же GUID сеанса и, следовательно, принадлежат к одному сеансу.

Кроме того, вызывающий объект может указать ЗНАЧЕНИЕ NULL в качестве третьего параметра в вызове Активации, чтобы назначить поток сеансу по умолчанию в качестве сеанса для конкретного процесса со значением GUID сеанса GUID_NULL. Дополнительные сведения см. в разделе IMMDevice::Activate.

Взаимодействие с устаревшими API аудио