MFCreateAudioRenderer 需要 guid 1082E6C2-7660-4945-8E78-228A3B3329F6 的奇怪属性
Weird attribute with guid 1082E6C2-7660-4945-8E78-228A3B3329F6 required for MFCreateAudioRenderer
我正在尝试通过使用属性指针集调用 MFCreateAudioRenderer
来创建具有给定 GUID 的音频渲染器实例。我已经设置了所有必需的值,但是调用 returns E_INVALIDARG
和 mftrace.exe
显示
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();
}
相关MSDN bit是:
...If you specify a device role, the SAR uses whatever audio device has been assigned for that role. To specify the device role, set the MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
attribute.
您可以通过 ID 或 ROLE 来识别设备,这两者是互斥的,因此 E_INVALIDARG
当您同时提供两者时。
我正在尝试通过使用属性指针集调用 MFCreateAudioRenderer
来创建具有给定 GUID 的音频渲染器实例。我已经设置了所有必需的值,但是调用 returns E_INVALIDARG
和 mftrace.exe
显示
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();
}
相关MSDN bit是:
...If you specify a device role, the SAR uses whatever audio device has been assigned for that role. To specify the device role, set the
MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
attribute.
您可以通过 ID 或 ROLE 来识别设备,这两者是互斥的,因此 E_INVALIDARG
当您同时提供两者时。