Changeset 3438 for pjproject/trunk/pjmedia/src/pjmedia-audiodev/wmme_dev.c
- Timestamp:
- Mar 11, 2011 6:57:24 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia-audiodev/wmme_dev.c
r2941 r3438 39 39 #endif 40 40 41 #ifndef PJMEDIA_WMME_DEV_USE_MMDEVICE_API 42 # define PJMEDIAWMME_DEV_USE_MMDEVICE_API \ 43 (defined(_WIN32_WINNT) && (_WIN32_WINNT>=0x0600)) 44 #endif 45 46 #if PJMEDIA_WMME_DEV_USE_MMDEVICE_API != 0 47 # define DRV_QUERYFUNCTIONINSTANCEID (DRV_RESERVED + 17) 48 # define DRV_QUERYFUNCTIONINSTANCEIDSIZE (DRV_RESERVED + 18) 49 #endif 50 41 51 /* mingw lacks WAVE_FORMAT_ALAW/MULAW */ 42 52 #ifndef WAVE_FORMAT_ALAW … … 61 71 pjmedia_aud_dev_info info; 62 72 unsigned deviceId; 73 const wchar_t *endpointId; 63 74 }; 64 75 … … 67 78 { 68 79 pjmedia_aud_dev_factory base; 80 pj_pool_t *base_pool; 69 81 pj_pool_t *pool; 70 82 pj_pool_factory *pf; … … 122 134 static pj_status_t factory_init(pjmedia_aud_dev_factory *f); 123 135 static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f); 136 static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f); 124 137 static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f); 125 138 static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, … … 157 170 &factory_get_dev_info, 158 171 &factory_default_param, 159 &factory_create_stream 172 &factory_create_stream, 173 &factory_refresh 160 174 }; 161 175 … … 182 196 pj_pool_t *pool; 183 197 184 pool = pj_pool_create(pf, "WMME ", 1000, 1000, NULL);198 pool = pj_pool_create(pf, "WMME base", 1000, 1000, NULL); 185 199 f = PJ_POOL_ZALLOC_T(pool, struct wmme_factory); 186 200 f->pf = pf; 187 f-> pool = pool;201 f->base_pool = pool; 188 202 f->base.op = &factory_op; 189 203 … … 191 205 } 192 206 207 /* Internal: Windows Vista and Windows 7 have their device 208 * names truncated when using the waveXXX api. The names 209 * should be acquired from the MMDevice APIs 210 */ 211 #if PJMEDIA_WMME_DEV_USE_MMDEVICE_API != 0 212 213 #define COBJMACROS 214 #include <mmdeviceapi.h> 215 #define INITGUID 216 #include <Guiddef.h> 217 #include <FunctionDiscoveryKeys_devpkey.h> 218 219 DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C, 220 0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E); 221 DEFINE_GUID(IID_IMMDeviceEnumerator, 0xA95664D2, 0x9614, 0x4F35, 222 0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6); 223 224 static void get_dev_names(pjmedia_aud_dev_factory *f) 225 { 226 struct wmme_factory *wf = (struct wmme_factory*)f; 227 HRESULT coinit = S_OK; 228 HRESULT hr = S_OK; 229 IMMDeviceEnumerator *pEnumerator = NULL; 230 IMMDeviceCollection *pDevices = NULL; 231 UINT cDevices = 0; 232 UINT nDevice = 0; 233 234 coinit = CoInitializeEx(NULL, COINIT_MULTITHREADED); 235 if (coinit == RPC_E_CHANGED_MODE) 236 coinit = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); 237 if (FAILED(coinit)) 238 goto on_error; 239 240 hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, 241 CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, 242 (void**)&pEnumerator); 243 if (FAILED(hr)) 244 goto on_error; 245 hr = IMMDeviceEnumerator_EnumAudioEndpoints(pEnumerator, eAll, 246 DEVICE_STATE_ACTIVE, 247 &pDevices); 248 if (FAILED(hr)) 249 goto on_error; 250 hr = IMMDeviceCollection_GetCount(pDevices, &cDevices); 251 if (FAILED(hr)) 252 goto on_error; 253 254 for (nDevice = 0; nDevice < cDevices; ++nDevice) { 255 IMMDevice *pDevice = NULL; 256 IPropertyStore *pProps = NULL; 257 LPWSTR pwszID = NULL; 258 PROPVARIANT varName; 259 unsigned i; 260 261 PropVariantInit(&varName); 262 263 hr = IMMDeviceCollection_Item(pDevices, nDevice, &pDevice); 264 if (FAILED(hr)) 265 goto cleanup; 266 hr = IMMDevice_GetId(pDevice, &pwszID); 267 if (FAILED(hr)) 268 goto cleanup; 269 hr = IMMDevice_OpenPropertyStore(pDevice, STGM_READ, &pProps); 270 if (FAILED(hr)) 271 goto cleanup; 272 hr = IPropertyStore_GetValue(pProps, &PKEY_Device_FriendlyName, 273 &varName); 274 if (FAILED(hr)) 275 goto cleanup; 276 277 for (i = 0; i < wf->dev_count; ++i) { 278 if (0 == wcscmp(wf->dev_info[i].endpointId, pwszID)) { 279 wcstombs(wf->dev_info[i].info.name, varName.pwszVal, 280 sizeof(wf->dev_info[i].info.name)); 281 break; 282 } 283 } 284 285 PropVariantClear(&varName); 286 287 cleanup: 288 if (pProps) 289 IPropertyStore_Release(pProps); 290 if (pwszID) 291 CoTaskMemFree(pwszID); 292 if (pDevice) 293 hr = IMMDevice_Release(pDevice); 294 } 295 296 on_error: 297 if (pDevices) 298 hr = IMMDeviceCollection_Release(pDevices); 299 300 if (pEnumerator) 301 hr = IMMDeviceEnumerator_Release(pEnumerator); 302 303 if (SUCCEEDED(coinit)) 304 CoUninitialize(); 305 } 306 307 #else 308 309 static void get_dev_names(pjmedia_aud_dev_factory *f) 310 { 311 PJ_UNUSED_ARG(f); 312 } 313 314 #endif 193 315 194 316 /* Internal: build device info from WAVEINCAPS/WAVEOUTCAPS */ … … 262 384 static pj_status_t factory_init(pjmedia_aud_dev_factory *f) 263 385 { 386 pj_status_t ret = factory_refresh(f); 387 if (ret != PJ_SUCCESS) 388 return ret; 389 390 PJ_LOG(4, (THIS_FILE, "WMME initialized")); 391 return PJ_SUCCESS; 392 } 393 394 /* API: refresh the device list */ 395 static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f) 396 { 264 397 struct wmme_factory *wf = (struct wmme_factory*)f; 265 398 unsigned c; … … 268 401 pj_bool_t waveMapperAdded = PJ_FALSE; 269 402 403 if (wf->pool != NULL) { 404 pj_pool_release(wf->pool); 405 wf->pool = NULL; 406 } 407 270 408 /* Enumerate sound devices */ 271 409 wf->dev_count = 0; 410 wf->pool = pj_pool_create(wf->pf, "WMME", 1000, 1000, NULL); 272 411 273 412 inputDeviceCount = waveInGetNumDevs(); … … 315 454 build_dev_info(WAVE_MAPPER, &wf->dev_info[wf->dev_count], 316 455 &wic, &woc); 456 wf->dev_info[wf->dev_count].endpointId = L""; 317 457 ++wf->dev_count; 318 458 waveMapperAdded = PJ_TRUE; … … 328 468 WAVEINCAPS wic; 329 469 MMRESULT mr; 470 DWORD cbEndpointId; 330 471 331 472 pj_bzero(&wic, sizeof(WAVEINCAPS)); … … 341 482 build_dev_info(uDeviceID, &wf->dev_info[wf->dev_count], 342 483 &wic, NULL); 484 485 #if PJMEDIA_WMME_DEV_USE_MMDEVICE_API != 0 486 /* Try to get the endpoint id of the audio device */ 487 wf->dev_info[wf->dev_count].endpointId = L""; 488 489 mr = waveInMessage((HWAVEIN)IntToPtr(uDeviceID), 490 DRV_QUERYFUNCTIONINSTANCEIDSIZE, 491 (DWORD_PTR)&cbEndpointId, (DWORD_PTR)NULL); 492 if (mr == MMSYSERR_NOERROR) { 493 const wchar_t **epid = &wf->dev_info[wf->dev_count].endpointId; 494 *epid = (const wchar_t*) pj_pool_calloc(wf->pool, 495 cbEndpointId, 1); 496 mr = waveInMessage((HWAVEIN)IntToPtr(uDeviceID), 497 DRV_QUERYFUNCTIONINSTANCEID, 498 (DWORD_PTR)*epid, 499 cbEndpointId); 500 } 501 #else 502 PJ_UNUSED_ARG(cbEndpointId); 503 #endif 504 343 505 ++wf->dev_count; 344 506 } … … 352 514 WAVEOUTCAPS woc; 353 515 MMRESULT mr; 516 DWORD cbEndpointId; 354 517 355 518 pj_bzero(&woc, sizeof(WAVEOUTCAPS)); … … 365 528 build_dev_info(uDeviceID, &wf->dev_info[wf->dev_count], 366 529 NULL, &woc); 530 531 #if PJMEDIA_WMME_DEV_USE_MMDEVICE_API != 0 532 /* Try to get the endpoint id of the audio device */ 533 wf->dev_info[wf->dev_count].endpointId = L""; 534 535 mr = waveOutMessage((HWAVEOUT)IntToPtr(uDeviceID), 536 DRV_QUERYFUNCTIONINSTANCEIDSIZE, 537 (DWORD_PTR)&cbEndpointId, (DWORD_PTR)NULL); 538 if (mr == MMSYSERR_NOERROR) { 539 const wchar_t **epid = &wf->dev_info[wf->dev_count].endpointId; 540 *epid = (const wchar_t*)pj_pool_calloc(wf->pool, 541 cbEndpointId, 1); 542 mr = waveOutMessage((HWAVEOUT)IntToPtr(uDeviceID), 543 DRV_QUERYFUNCTIONINSTANCEID, 544 (DWORD_PTR)*epid, cbEndpointId); 545 } 546 #else 547 PJ_UNUSED_ARG(cbEndpointId); 548 #endif 549 367 550 ++wf->dev_count; 368 551 } 369 552 } 370 553 371 PJ_LOG(4, (THIS_FILE, "WMME initialized, found %d devices:", 554 /* On Windows Vista and Windows 7 get the full device names */ 555 get_dev_names(f); 556 557 PJ_LOG(4, (THIS_FILE, "WMME found %d devices:", 372 558 wf->dev_count)); 373 559 for (c = 0; c < wf->dev_count; ++c) { … … 386 572 { 387 573 struct wmme_factory *wf = (struct wmme_factory*)f; 388 pj_pool_t *pool = wf->pool; 389 390 wf->pool = NULL; 574 pj_pool_t *pool = wf->base_pool; 575 576 pj_pool_release(wf->pool); 577 wf->base_pool = NULL; 391 578 pj_pool_release(pool); 392 579
Note: See TracChangeset
for help on using the changeset viewer.