I want to get interface IBaseFilter system mixer, but get an error REGDB_E_CLASSNOTREG Class not registered in:
hr = pEndpoint->Activate(__uuidof(IBaseFilter), CLSCTX_ALL, /*&var*/ NULL, (void**)ppFilter);
Earlier this code to work.
Fully code:
filterName = "Stereo mixer (IDT High Definition Audio CODEC)"
HRESULT CCapture::GetAudioCaptureFilterByName(wstring *filterName, IBaseFilter **ppFilter)
{
HRESULT hr = S_OK;
IMMDeviceEnumerator *pEnumerator = 0;
IMMDeviceCollection *pCollection = 0;
IMMDevice *pEndpoint = 0;
IPropertyStore *pProps = 0;
LPWSTR pwszID = 0;
hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator);
if (FAILED(hr)) return hr;
hr = pEnumerator->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE, &pCollection);
if (FAILED(hr))
{
if (pEnumerator) pEnumerator->Release();
return hr;
}
UINT count;
hr = pCollection->GetCount(&count);
if (FAILED(hr))
{
if (pCollection) pCollection->Release();
if (pEnumerator) pEnumerator->Release();
return hr;
}
if (count == 0)
{
if (pCollection) pCollection->Release();
if (pEnumerator) pEnumerator->Release();
return hr;
}
for (ULONG i = 0; i < count; i++)
{
hr = pCollection->Item(i, &pEndpoint);
if (FAILED(hr))
{
if (pCollection) pCollection->Release();
if (pEnumerator) pEnumerator->Release();
return hr;
}
// Получаем ID устройства.
hr = pEndpoint->GetId(&pwszID);
if (FAILED(hr))
{
if (pEndpoint) pEndpoint->Release();
if (pCollection) pCollection->Release();
if (pEnumerator) pEnumerator->Release();
return hr;
}
hr = pEndpoint->OpenPropertyStore(STGM_READ, &pProps);
if (FAILED(hr))
{
CoTaskMemFree(pwszID);
if (pEndpoint) pEndpoint->Release();
if (pCollection) pCollection->Release();
if (pEnumerator) pEnumerator->Release();
return hr;
}
PROPVARIANT varName;
PropVariantInit(&varName);
// Получаем дружественное имя устройства.
hr = pProps->GetValue(PKEY_Device_FriendlyName, &varName);
if (FAILED(hr))
{
CoTaskMemFree(pwszID);
if (pProps) pProps->Release();
if (pEndpoint) pEndpoint->Release();
if (pCollection) pCollection->Release();
if (pEnumerator) pEnumerator->Release();
return hr;
}
wstring *wstr = new wstring(varName.pwszVal);
if (wstr->compare(*filterName) == 0)
{
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 = pEndpoint->Activate(__uuidof(IBaseFilter), CLSCTX_ALL, /*&var*/ NULL, (void**)ppFilter);
delete wstr;
CoTaskMemFree(pwszID);
PropVariantClear(&varName);
if (pProps) pProps->Release();
if (pEndpoint) pEndpoint->Release();
if (pCollection) pCollection->Release();
if (pEnumerator) pEnumerator->Release();
return hr;
}
delete wstr;
CoTaskMemFree(pwszID);
pwszID = NULL;
PropVariantClear(&varName);
if (pProps) pProps->Release();
if (pEndpoint) pEndpoint->Release();
pProps = 0;
pEndpoint = 0;
}
hr = E_FAIL;
if (pProps) pProps->Release();
if (pEndpoint) pEndpoint->Release();
if (pCollection) pCollection->Release();
if (pEnumerator) pEnumerator->Release();
return hr;
}
The problem is caused by conflict with installed DirectShowSpy tool.
MMDevice's Activate
for IBaseFilter
presumably does the following:
if(interface is IBaseFilter)
{
IMMDeviceActivator pMmDeviceActivator;
CoCreateInstace(CLSID_SystemDeviceEnum, ..., &pMmDeviceActivator);
return pMmDeviceActivator->Activate(pMmDevice, ...)
}
Implementation of IMMDeviceActivator
by System Device Enumerator CLSID_SystemDeviceEnum
is undocumented (the interface is reserved for internal use) and DirectShowSpy did not handle it well. Since version 1.0.0.2106 it does it right.