erichocean / libjingle

Automatically exported from code.google.com/p/libjingle
0 stars 0 forks source link

Device manager bug when taking the devices using the Core Audio #219

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

1.media_client_->SignalDevicesChange.connect(this, &Class::OnDevicesChange);        

2.calling media_client_->GetCapabilities(); when the Class::OnDevicesChange is 
triggered. 

3.remove the headphones from the pc. (the only connected.)

What is the expected output? What do you see instead?

I'm receiving the capabilities based on the old device list (which also include 
the last device which was removed from the computer ).

Instead I should receive the capabilities based on the current configuration.

If I put a sleep with some milliseconds the results it's correctly displayed.

What version of the product are you using? On what operating system?

libjingle 0.6.1 from SVN.
Windows 7 x64

Please provide any additional information below.

I have digged into the problem and seems that the device notification is done 
using WM_DEVICECHANGE and the device list is taken using Core Audio. This is a 
problem because when the WM_DEVICECHANGE is triggered the Core Audio doesn't 
know already about the change.

 if (uMsg == WM_DEVICECHANGE) {
    if (wParam == DBT_DEVICEARRIVAL ||
        wParam == DBT_DEVICEREMOVECOMPLETE) {
      DEV_BROADCAST_DEVICEINTERFACE* dbdi =
          reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(lParam);
      if (dbdi->dbcc_classguid == KSCATEGORY_AUDIO ||
        dbdi->dbcc_classguid == KSCATEGORY_VIDEO) {
        manager_->OnDevicesChange();
      }
    }

I think a fixing will be to make the triggering also using Core Audio (where is 
supported.).

IMMDeviceEnumerator* pEnumerator = nullptr;

HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),NULL, 
CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (void**)&pEnumerator);

if(FAILED(hr))
{
   ....
}

HRESULT hr = pEnumerator->RegisterEndpointNotificationCallback(this);

HRESULT STDMETHODCALLTYPE 
IDeviceManagerCoreAudioImpl::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD 
dwNewState)
{

    INT operation = 0;

    if(dwNewState == DEVICE_STATE_ACTIVE)
        operation = DEVICE_PLUGGED;
    else operation = DEVICE_UNPLUGGED;

    ...

    return S_OK;
}

Original issue reported on code.google.com by silviu.cpp@gmail.com on 5 Oct 2011 at 12:27