2017-05-08 54 views
1

我想通過調用MFCreateAudioRenderer屬性指針集來創建具有給定GUID的音頻呈現器的實例。我給自己定的所有所需的值,但調用返回E_INVALIDARGmftrace.exe顯示奇怪的屬性與guid 1082E6C2-7660-4945-8E78-228A3B3329F6所需的MFCreateAudioRenderer

13808,33E0 15:09:52.27643 CMFAttributesDetours::GetUnknown @014C4550 - enter 
13808,33E0 15:09:52.27644 CMFAttributesDetours::GetUnknown @014C4550 attribute not found guidKey = {1082E6C2-7660-4945-8E78-228A3B3329F6} 
13808,33E0 15:09:52.27644 CMFAttributesDetours::GetUnknown @014C4550 - exit (failed hr=0xC00D36E6 MF_E_ATTRIBUTENOTFOUND) 

我不能在任何地方找到這個GUID,不知道如何設置。任何建議?

最少的樣品重現:

#include <atlbase.h> 
#include <atlcom.h> 

#include <Mfidl.h> 
#include <Mfapi.h> 
#include <Mmdeviceapi.h> 
#include <string> 
#include <vector> 
#include <map> 
#include <Functiondiscoverykeys_devpkey.h> 
#include <Audioclient.h> 
#include <Codecapi.h> 
#include <Audiopolicy.h> 

#pragma comment(lib, "Mfplat.lib") 
#pragma comment(lib, "Mf.lib") 

int main(int argc, char** argv) 
{ 
    CoInitializeEx(nullptr, COINIT_MULTITHREADED); 
    CComPtr<IMMDeviceEnumerator> pMMDeviceEnumerator; 
    pMMDeviceEnumerator.CoCreateInstance(__uuidof(MMDeviceEnumerator)); 
    std::map<std::wstring, CComPtr<IMMDevice>> Devices; 
    if (pMMDeviceEnumerator) 
    { 
     CComPtr<IMMDeviceCollection> pMMDeviceCollection; 
     if (SUCCEEDED(pMMDeviceEnumerator->EnumAudioEndpoints(EDataFlow::eRender, DEVICE_STATE_ACTIVE, &pMMDeviceCollection))) 
     { 
      UINT nDeviceCount = 0; 
      if (SUCCEEDED(pMMDeviceCollection->GetCount(&nDeviceCount))) 
      { 
       UINT nDeviceIndex = 0; 
       while (nDeviceIndex < nDeviceCount) 
       { 
        CComPtr<IMMDevice> pMMDevice; 
        if (SUCCEEDED(pMMDeviceCollection->Item(nDeviceIndex, &pMMDevice))) 
        { 
         CComPtr<IPropertyStore> pPropertyStore; 
         if (SUCCEEDED(pMMDevice->OpenPropertyStore(STGM_READ, &pPropertyStore))) 
         { 
          PROPVARIANT Variant; 
          PropVariantInit(&Variant); 
          if (SUCCEEDED(pPropertyStore->GetValue(PKEY_Device_FriendlyName, &Variant))) 
          { 
           wchar_t* pId = nullptr; 
           if (SUCCEEDED(pMMDevice->GetId(&pId))) 
           { 
            Devices.emplace(pId, pMMDevice); 
            CoTaskMemFree(pId); 
           } 
          } 
         } 
        } 
        ++nDeviceIndex; 
       } 
      } 
     } 
    } 
    std::vector<CComPtr<IMFMediaSink>> MediaSinks; 
    for (const auto& Device : Devices) 
    { 
     CComPtr<IMFAttributes> pAttributes; 
     MFCreateAttributes(&pAttributes, 0); 
     CComPtr<IMFMediaSink> pAudioRenderer; 
     HRESULT hResult = pAttributes->SetString(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, Device.first.c_str()); 
     hResult = pAttributes->SetUINT32(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, ERole::eMultimedia); 
     hResult = pAttributes->SetUINT32(MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY, AUDIO_STREAM_CATEGORY::AudioCategory_BackgroundCapableMedia); 
     hResult = pAttributes->SetUINT32(MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS, 0); 
     hResult = pAttributes->SetGUID(MF_AUDIO_RENDERER_ATTRIBUTE_SESSION_ID, GUID_NULL); 
     hResult = MFCreateAudioRenderer(pAttributes, &pAudioRenderer); 
     if (SUCCEEDED(hResult)) 
     { 
      MediaSinks.push_back(pAudioRenderer); 
     } 
    } 
    CoUninitialize(); 
} 
+1

@dan [你還沒有停止...?](http://stackoverflow.com/questions/43850854/how-to-intercept-alt1-or-altnumber-key-pressed-event-c#comment74738138_43850854)這一個額外的標籤是好的,但一個語言標籤*不*錯誤。 –

+0

它可能發生,你不需要這個未知的屬性。首先問題是你的其他屬性不好。我將從註釋流類別開始(使用的值已棄用)。 –

+0

@RomanR。如果那個人被正確地抱怨,mftrace就會被註釋掉。 –

回答

2

相關MSDN bit是:

...如果你指定設備的角色,特區使用任何音頻設備已經被分配給該角色。要指定設備角色,請設置MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE屬性。

您可以通過ID或ROLE識別設備,這兩個設備是互斥的,因此當您一次提供兩個設備時,這兩個設備是互斥的。