OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/audio/win/core_audio_util_win.h" | 5 #include "media/audio/win/core_audio_util_win.h" |
6 | 6 |
7 #include <devicetopology.h> | 7 #include <devicetopology.h> |
8 #include <dxdiag.h> | 8 #include <dxdiag.h> |
9 #include <functiondiscoverykeys_devpkey.h> | 9 #include <functiondiscoverykeys_devpkey.h> |
10 #include <stddef.h> | 10 #include <stddef.h> |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); | 246 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
247 if (cmd_line->HasSwitch(switches::kEnableExclusiveAudio)) | 247 if (cmd_line->HasSwitch(switches::kEnableExclusiveAudio)) |
248 return AUDCLNT_SHAREMODE_EXCLUSIVE; | 248 return AUDCLNT_SHAREMODE_EXCLUSIVE; |
249 return AUDCLNT_SHAREMODE_SHARED; | 249 return AUDCLNT_SHAREMODE_SHARED; |
250 } | 250 } |
251 | 251 |
252 int CoreAudioUtil::NumberOfActiveDevices(EDataFlow data_flow) { | 252 int CoreAudioUtil::NumberOfActiveDevices(EDataFlow data_flow) { |
253 // Create the IMMDeviceEnumerator interface. | 253 // Create the IMMDeviceEnumerator interface. |
254 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = | 254 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = |
255 CreateDeviceEnumerator(); | 255 CreateDeviceEnumerator(); |
256 if (!device_enumerator.get()) | 256 if (!device_enumerator.Get()) |
257 return 0; | 257 return 0; |
258 | 258 |
259 // Generate a collection of active (present and not disabled) audio endpoint | 259 // Generate a collection of active (present and not disabled) audio endpoint |
260 // devices for the specified data-flow direction. | 260 // devices for the specified data-flow direction. |
261 // This method will succeed even if all devices are disabled. | 261 // This method will succeed even if all devices are disabled. |
262 ScopedComPtr<IMMDeviceCollection> collection; | 262 ScopedComPtr<IMMDeviceCollection> collection; |
263 HRESULT hr = device_enumerator->EnumAudioEndpoints(data_flow, | 263 HRESULT hr = device_enumerator->EnumAudioEndpoints(data_flow, |
264 DEVICE_STATE_ACTIVE, | 264 DEVICE_STATE_ACTIVE, |
265 collection.Receive()); | 265 collection.Receive()); |
266 if (FAILED(hr)) { | 266 if (FAILED(hr)) { |
(...skipping 13 matching lines...) Expand all Loading... |
280 return CreateDeviceEnumeratorInternal(true); | 280 return CreateDeviceEnumeratorInternal(true); |
281 } | 281 } |
282 | 282 |
283 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDefaultDevice(EDataFlow data_flow, | 283 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDefaultDevice(EDataFlow data_flow, |
284 ERole role) { | 284 ERole role) { |
285 ScopedComPtr<IMMDevice> endpoint_device; | 285 ScopedComPtr<IMMDevice> endpoint_device; |
286 | 286 |
287 // Create the IMMDeviceEnumerator interface. | 287 // Create the IMMDeviceEnumerator interface. |
288 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = | 288 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = |
289 CreateDeviceEnumerator(); | 289 CreateDeviceEnumerator(); |
290 if (!device_enumerator.get()) | 290 if (!device_enumerator.Get()) |
291 return endpoint_device; | 291 return endpoint_device; |
292 | 292 |
293 // Retrieve the default audio endpoint for the specified data-flow | 293 // Retrieve the default audio endpoint for the specified data-flow |
294 // direction and role. | 294 // direction and role. |
295 HRESULT hr = device_enumerator->GetDefaultAudioEndpoint( | 295 HRESULT hr = device_enumerator->GetDefaultAudioEndpoint( |
296 data_flow, role, endpoint_device.Receive()); | 296 data_flow, role, endpoint_device.Receive()); |
297 | 297 |
298 if (FAILED(hr)) { | 298 if (FAILED(hr)) { |
299 DVLOG(1) << "IMMDeviceEnumerator::GetDefaultAudioEndpoint: " | 299 DVLOG(1) << "IMMDeviceEnumerator::GetDefaultAudioEndpoint: " |
300 << std::hex << hr; | 300 << std::hex << hr; |
301 return endpoint_device; | 301 return endpoint_device; |
302 } | 302 } |
303 | 303 |
304 // Verify that the audio endpoint device is active, i.e., that the audio | 304 // Verify that the audio endpoint device is active, i.e., that the audio |
305 // adapter that connects to the endpoint device is present and enabled. | 305 // adapter that connects to the endpoint device is present and enabled. |
306 if (!IsDeviceActive(endpoint_device.get())) { | 306 if (!IsDeviceActive(endpoint_device.Get())) { |
307 DVLOG(1) << "Selected endpoint device is not active"; | 307 DVLOG(1) << "Selected endpoint device is not active"; |
308 endpoint_device.Reset(); | 308 endpoint_device.Reset(); |
309 } | 309 } |
310 return endpoint_device; | 310 return endpoint_device; |
311 } | 311 } |
312 | 312 |
313 std::string CoreAudioUtil::GetDefaultOutputDeviceID() { | 313 std::string CoreAudioUtil::GetDefaultOutputDeviceID() { |
314 ScopedComPtr<IMMDevice> device(CreateDefaultDevice(eRender, eConsole)); | 314 ScopedComPtr<IMMDevice> device(CreateDefaultDevice(eRender, eConsole)); |
315 return device.get() ? GetDeviceID(device.get()) : std::string(); | 315 return device.Get() ? GetDeviceID(device.Get()) : std::string(); |
316 } | 316 } |
317 | 317 |
318 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDevice( | 318 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDevice( |
319 const std::string& device_id) { | 319 const std::string& device_id) { |
320 ScopedComPtr<IMMDevice> endpoint_device; | 320 ScopedComPtr<IMMDevice> endpoint_device; |
321 | 321 |
322 // Create the IMMDeviceEnumerator interface. | 322 // Create the IMMDeviceEnumerator interface. |
323 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = | 323 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = |
324 CreateDeviceEnumerator(); | 324 CreateDeviceEnumerator(); |
325 if (!device_enumerator.get()) | 325 if (!device_enumerator.Get()) |
326 return endpoint_device; | 326 return endpoint_device; |
327 | 327 |
328 // Retrieve an audio device specified by an endpoint device-identification | 328 // Retrieve an audio device specified by an endpoint device-identification |
329 // string. | 329 // string. |
330 HRESULT hr = device_enumerator->GetDevice( | 330 HRESULT hr = device_enumerator->GetDevice( |
331 base::UTF8ToUTF16(device_id).c_str(), endpoint_device.Receive()); | 331 base::UTF8ToUTF16(device_id).c_str(), endpoint_device.Receive()); |
332 DVLOG_IF(1, FAILED(hr)) << "IMMDeviceEnumerator::GetDevice: " | 332 DVLOG_IF(1, FAILED(hr)) << "IMMDeviceEnumerator::GetDevice: " |
333 << std::hex << hr; | 333 << std::hex << hr; |
334 | 334 |
335 if (FAILED(hr)) { | 335 if (FAILED(hr)) { |
336 DVLOG(1) << "IMMDeviceEnumerator::GetDevice: " << std::hex << hr; | 336 DVLOG(1) << "IMMDeviceEnumerator::GetDevice: " << std::hex << hr; |
337 return endpoint_device; | 337 return endpoint_device; |
338 } | 338 } |
339 | 339 |
340 // Verify that the audio endpoint device is active, i.e., that the audio | 340 // Verify that the audio endpoint device is active, i.e., that the audio |
341 // adapter that connects to the endpoint device is present and enabled. | 341 // adapter that connects to the endpoint device is present and enabled. |
342 if (!IsDeviceActive(endpoint_device.get())) { | 342 if (!IsDeviceActive(endpoint_device.Get())) { |
343 DVLOG(1) << "Selected endpoint device is not active"; | 343 DVLOG(1) << "Selected endpoint device is not active"; |
344 endpoint_device.Reset(); | 344 endpoint_device.Reset(); |
345 } | 345 } |
346 return endpoint_device; | 346 return endpoint_device; |
347 } | 347 } |
348 | 348 |
349 HRESULT CoreAudioUtil::GetDeviceName(IMMDevice* device, AudioDeviceName* name) { | 349 HRESULT CoreAudioUtil::GetDeviceName(IMMDevice* device, AudioDeviceName* name) { |
350 // Retrieve unique name of endpoint device. | 350 // Retrieve unique name of endpoint device. |
351 // Example: "{0.0.1.00000000}.{8db6020f-18e3-4f25-b6f5-7726c9122574}". | 351 // Example: "{0.0.1.00000000}.{8db6020f-18e3-4f25-b6f5-7726c9122574}". |
352 AudioDeviceName device_name; | 352 AudioDeviceName device_name; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 if (input_device_id == AudioDeviceDescription::kCommunicationsDeviceId) | 423 if (input_device_id == AudioDeviceDescription::kCommunicationsDeviceId) |
424 return AudioDeviceDescription::kCommunicationsDeviceId; | 424 return AudioDeviceDescription::kCommunicationsDeviceId; |
425 | 425 |
426 ScopedComPtr<IMMDevice> input_device; | 426 ScopedComPtr<IMMDevice> input_device; |
427 if (IsDefaultDeviceId(input_device_id)) { | 427 if (IsDefaultDeviceId(input_device_id)) { |
428 input_device = CreateDefaultDevice(eCapture, eConsole); | 428 input_device = CreateDefaultDevice(eCapture, eConsole); |
429 } else { | 429 } else { |
430 input_device = CreateDevice(input_device_id); | 430 input_device = CreateDevice(input_device_id); |
431 } | 431 } |
432 | 432 |
433 if (!input_device.get()) | 433 if (!input_device.Get()) |
434 return std::string(); | 434 return std::string(); |
435 | 435 |
436 // See if we can get id of the associated controller. | 436 // See if we can get id of the associated controller. |
437 ScopedComPtr<IMMDeviceEnumerator> enumerator(CreateDeviceEnumerator()); | 437 ScopedComPtr<IMMDeviceEnumerator> enumerator(CreateDeviceEnumerator()); |
438 std::string controller_id( | 438 std::string controller_id( |
439 GetAudioControllerID(input_device.get(), enumerator.get())); | 439 GetAudioControllerID(input_device.Get(), enumerator.Get())); |
440 if (controller_id.empty()) | 440 if (controller_id.empty()) |
441 return std::string(); | 441 return std::string(); |
442 | 442 |
443 // Now enumerate the available (and active) output devices and see if any of | 443 // Now enumerate the available (and active) output devices and see if any of |
444 // them is associated with the same controller. | 444 // them is associated with the same controller. |
445 ScopedComPtr<IMMDeviceCollection> collection; | 445 ScopedComPtr<IMMDeviceCollection> collection; |
446 enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, | 446 enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, |
447 collection.Receive()); | 447 collection.Receive()); |
448 if (!collection.get()) | 448 if (!collection.Get()) |
449 return std::string(); | 449 return std::string(); |
450 | 450 |
451 UINT count = 0; | 451 UINT count = 0; |
452 collection->GetCount(&count); | 452 collection->GetCount(&count); |
453 ScopedComPtr<IMMDevice> output_device; | 453 ScopedComPtr<IMMDevice> output_device; |
454 for (UINT i = 0; i < count; ++i) { | 454 for (UINT i = 0; i < count; ++i) { |
455 collection->Item(i, output_device.Receive()); | 455 collection->Item(i, output_device.Receive()); |
456 std::string output_controller_id( | 456 std::string output_controller_id( |
457 GetAudioControllerID(output_device.get(), enumerator.get())); | 457 GetAudioControllerID(output_device.Get(), enumerator.Get())); |
458 if (output_controller_id == controller_id) | 458 if (output_controller_id == controller_id) |
459 break; | 459 break; |
460 output_device = NULL; | 460 output_device = NULL; |
461 } | 461 } |
462 | 462 |
463 return output_device.get() ? GetDeviceID(output_device.get()) : std::string(); | 463 return output_device.Get() ? GetDeviceID(output_device.Get()) : std::string(); |
464 } | 464 } |
465 | 465 |
466 std::string CoreAudioUtil::GetFriendlyName(const std::string& device_id) { | 466 std::string CoreAudioUtil::GetFriendlyName(const std::string& device_id) { |
467 ScopedComPtr<IMMDevice> audio_device = CreateDevice(device_id); | 467 ScopedComPtr<IMMDevice> audio_device = CreateDevice(device_id); |
468 if (!audio_device.get()) | 468 if (!audio_device.Get()) |
469 return std::string(); | 469 return std::string(); |
470 | 470 |
471 AudioDeviceName device_name; | 471 AudioDeviceName device_name; |
472 HRESULT hr = GetDeviceName(audio_device.get(), &device_name); | 472 HRESULT hr = GetDeviceName(audio_device.Get(), &device_name); |
473 if (FAILED(hr)) | 473 if (FAILED(hr)) |
474 return std::string(); | 474 return std::string(); |
475 | 475 |
476 return device_name.device_name; | 476 return device_name.device_name; |
477 } | 477 } |
478 | 478 |
479 bool CoreAudioUtil::DeviceIsDefault(EDataFlow flow, | 479 bool CoreAudioUtil::DeviceIsDefault(EDataFlow flow, |
480 ERole role, | 480 ERole role, |
481 const std::string& device_id) { | 481 const std::string& device_id) { |
482 ScopedComPtr<IMMDevice> device = CreateDefaultDevice(flow, role); | 482 ScopedComPtr<IMMDevice> device = CreateDefaultDevice(flow, role); |
483 if (!device.get()) | 483 if (!device.Get()) |
484 return false; | 484 return false; |
485 | 485 |
486 std::string str_default(GetDeviceID(device.get())); | 486 std::string str_default(GetDeviceID(device.Get())); |
487 return device_id.compare(str_default) == 0; | 487 return device_id.compare(str_default) == 0; |
488 } | 488 } |
489 | 489 |
490 EDataFlow CoreAudioUtil::GetDataFlow(IMMDevice* device) { | 490 EDataFlow CoreAudioUtil::GetDataFlow(IMMDevice* device) { |
491 ScopedComPtr<IMMEndpoint> endpoint; | 491 ScopedComPtr<IMMEndpoint> endpoint; |
492 HRESULT hr = device->QueryInterface(endpoint.Receive()); | 492 HRESULT hr = device->QueryInterface(endpoint.Receive()); |
493 if (FAILED(hr)) { | 493 if (FAILED(hr)) { |
494 DVLOG(1) << "IMMDevice::QueryInterface: " << std::hex << hr; | 494 DVLOG(1) << "IMMDevice::QueryInterface: " << std::hex << hr; |
495 return eAll; | 495 return eAll; |
496 } | 496 } |
(...skipping 16 matching lines...) Expand all Loading... |
513 CLSCTX_INPROC_SERVER, | 513 CLSCTX_INPROC_SERVER, |
514 NULL, | 514 NULL, |
515 audio_client.ReceiveVoid()); | 515 audio_client.ReceiveVoid()); |
516 DVLOG_IF(1, FAILED(hr)) << "IMMDevice::Activate: " << std::hex << hr; | 516 DVLOG_IF(1, FAILED(hr)) << "IMMDevice::Activate: " << std::hex << hr; |
517 return audio_client; | 517 return audio_client; |
518 } | 518 } |
519 | 519 |
520 ScopedComPtr<IAudioClient> CoreAudioUtil::CreateDefaultClient( | 520 ScopedComPtr<IAudioClient> CoreAudioUtil::CreateDefaultClient( |
521 EDataFlow data_flow, ERole role) { | 521 EDataFlow data_flow, ERole role) { |
522 ScopedComPtr<IMMDevice> default_device(CreateDefaultDevice(data_flow, role)); | 522 ScopedComPtr<IMMDevice> default_device(CreateDefaultDevice(data_flow, role)); |
523 return (default_device.get() ? CreateClient(default_device.get()) | 523 return (default_device.Get() ? CreateClient(default_device.Get()) |
524 : ScopedComPtr<IAudioClient>()); | 524 : ScopedComPtr<IAudioClient>()); |
525 } | 525 } |
526 | 526 |
527 ScopedComPtr<IAudioClient> CoreAudioUtil::CreateClient( | 527 ScopedComPtr<IAudioClient> CoreAudioUtil::CreateClient( |
528 const std::string& device_id, EDataFlow data_flow, ERole role) { | 528 const std::string& device_id, EDataFlow data_flow, ERole role) { |
529 if (IsDefaultDeviceId(device_id)) | 529 if (IsDefaultDeviceId(device_id)) |
530 return CreateDefaultClient(data_flow, role); | 530 return CreateDefaultClient(data_flow, role); |
531 | 531 |
532 ScopedComPtr<IMMDevice> device(CreateDevice(device_id)); | 532 ScopedComPtr<IMMDevice> device(CreateDevice(device_id)); |
533 if (!device.get()) | 533 if (!device.Get()) |
534 return ScopedComPtr<IAudioClient>(); | 534 return ScopedComPtr<IAudioClient>(); |
535 | 535 |
536 return CreateClient(device.get()); | 536 return CreateClient(device.Get()); |
537 } | 537 } |
538 | 538 |
539 HRESULT CoreAudioUtil::GetSharedModeMixFormat( | 539 HRESULT CoreAudioUtil::GetSharedModeMixFormat( |
540 IAudioClient* client, WAVEFORMATPCMEX* format) { | 540 IAudioClient* client, WAVEFORMATPCMEX* format) { |
541 ScopedCoMem<WAVEFORMATPCMEX> format_pcmex; | 541 ScopedCoMem<WAVEFORMATPCMEX> format_pcmex; |
542 HRESULT hr = client->GetMixFormat( | 542 HRESULT hr = client->GetMixFormat( |
543 reinterpret_cast<WAVEFORMATEX**>(&format_pcmex)); | 543 reinterpret_cast<WAVEFORMATEX**>(&format_pcmex)); |
544 if (FAILED(hr)) | 544 if (FAILED(hr)) |
545 return hr; | 545 return hr; |
546 | 546 |
(...skipping 25 matching lines...) Expand all Loading... |
572 | 572 |
573 return (hr == S_OK); | 573 return (hr == S_OK); |
574 } | 574 } |
575 | 575 |
576 bool CoreAudioUtil::IsChannelLayoutSupported(const std::string& device_id, | 576 bool CoreAudioUtil::IsChannelLayoutSupported(const std::string& device_id, |
577 EDataFlow data_flow, | 577 EDataFlow data_flow, |
578 ERole role, | 578 ERole role, |
579 ChannelLayout channel_layout) { | 579 ChannelLayout channel_layout) { |
580 // First, get the preferred mixing format for shared mode streams. | 580 // First, get the preferred mixing format for shared mode streams. |
581 ScopedComPtr<IAudioClient> client(CreateClient(device_id, data_flow, role)); | 581 ScopedComPtr<IAudioClient> client(CreateClient(device_id, data_flow, role)); |
582 if (!client.get()) | 582 if (!client.Get()) |
583 return false; | 583 return false; |
584 | 584 |
585 WAVEFORMATPCMEX format; | 585 WAVEFORMATPCMEX format; |
586 HRESULT hr = GetSharedModeMixFormat(client.get(), &format); | 586 HRESULT hr = GetSharedModeMixFormat(client.Get(), &format); |
587 if (FAILED(hr)) | 587 if (FAILED(hr)) |
588 return false; | 588 return false; |
589 | 589 |
590 // Next, check if it is possible to use an alternative format where the | 590 // Next, check if it is possible to use an alternative format where the |
591 // channel layout (and possibly number of channels) is modified. | 591 // channel layout (and possibly number of channels) is modified. |
592 | 592 |
593 // Convert generic channel layout into Windows-specific channel configuration. | 593 // Convert generic channel layout into Windows-specific channel configuration. |
594 ChannelConfig new_config = ChannelLayoutToChannelConfig(channel_layout); | 594 ChannelConfig new_config = ChannelLayoutToChannelConfig(channel_layout); |
595 if (new_config == KSAUDIO_SPEAKER_UNSUPPORTED) { | 595 if (new_config == KSAUDIO_SPEAKER_UNSUPPORTED) { |
596 return false; | 596 return false; |
(...skipping 12 matching lines...) Expand all Loading... |
609 DVLOG(2) << format; | 609 DVLOG(2) << format; |
610 | 610 |
611 // Some devices can initialize a shared-mode stream with a format that is | 611 // Some devices can initialize a shared-mode stream with a format that is |
612 // not identical to the mix format obtained from the GetMixFormat() method. | 612 // not identical to the mix format obtained from the GetMixFormat() method. |
613 // However, chances of succeeding increases if we use the same number of | 613 // However, chances of succeeding increases if we use the same number of |
614 // channels and the same sample rate as the mix format. I.e, this call will | 614 // channels and the same sample rate as the mix format. I.e, this call will |
615 // return true only in those cases where the audio engine is able to support | 615 // return true only in those cases where the audio engine is able to support |
616 // an even wider range of shared-mode formats where the installation package | 616 // an even wider range of shared-mode formats where the installation package |
617 // for the audio device includes a local effects (LFX) audio processing | 617 // for the audio device includes a local effects (LFX) audio processing |
618 // object (APO) that can handle format conversions. | 618 // object (APO) that can handle format conversions. |
619 return CoreAudioUtil::IsFormatSupported(client.get(), | 619 return CoreAudioUtil::IsFormatSupported(client.Get(), |
620 AUDCLNT_SHAREMODE_SHARED, &format); | 620 AUDCLNT_SHAREMODE_SHARED, &format); |
621 } | 621 } |
622 | 622 |
623 HRESULT CoreAudioUtil::GetDevicePeriod(IAudioClient* client, | 623 HRESULT CoreAudioUtil::GetDevicePeriod(IAudioClient* client, |
624 AUDCLNT_SHAREMODE share_mode, | 624 AUDCLNT_SHAREMODE share_mode, |
625 REFERENCE_TIME* device_period) { | 625 REFERENCE_TIME* device_period) { |
626 // Get the period of the engine thread. | 626 // Get the period of the engine thread. |
627 REFERENCE_TIME default_period = 0; | 627 REFERENCE_TIME default_period = 0; |
628 REFERENCE_TIME minimum_period = 0; | 628 REFERENCE_TIME minimum_period = 0; |
629 HRESULT hr = client->GetDevicePeriod(&default_period, &minimum_period); | 629 HRESULT hr = client->GetDevicePeriod(&default_period, &minimum_period); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 device_id == AudioDeviceDescription::kLoopbackWithMuteDeviceId) { | 714 device_id == AudioDeviceDescription::kLoopbackWithMuteDeviceId) { |
715 DCHECK(!is_output_device); | 715 DCHECK(!is_output_device); |
716 device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); | 716 device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); |
717 } else if (device_id == AudioDeviceDescription::kCommunicationsDeviceId) { | 717 } else if (device_id == AudioDeviceDescription::kCommunicationsDeviceId) { |
718 device = CoreAudioUtil::CreateDefaultDevice( | 718 device = CoreAudioUtil::CreateDefaultDevice( |
719 is_output_device ? eRender : eCapture, eCommunications); | 719 is_output_device ? eRender : eCapture, eCommunications); |
720 } else { | 720 } else { |
721 device = CreateDevice(device_id); | 721 device = CreateDevice(device_id); |
722 } | 722 } |
723 | 723 |
724 if (!device.get()) { | 724 if (!device.Get()) { |
725 // Map NULL-pointer to new error code which can be different from the | 725 // Map NULL-pointer to new error code which can be different from the |
726 // actual error code. The exact value is not important here. | 726 // actual error code. The exact value is not important here. |
727 return AUDCLNT_E_DEVICE_INVALIDATED; | 727 return AUDCLNT_E_DEVICE_INVALIDATED; |
728 } | 728 } |
729 | 729 |
730 ScopedComPtr<IAudioClient> client(CreateClient(device.get())); | 730 ScopedComPtr<IAudioClient> client(CreateClient(device.Get())); |
731 if (!client.get()) { | 731 if (!client.Get()) { |
732 // Map NULL-pointer to new error code which can be different from the | 732 // Map NULL-pointer to new error code which can be different from the |
733 // actual error code. The exact value is not important here. | 733 // actual error code. The exact value is not important here. |
734 return AUDCLNT_E_ENDPOINT_CREATE_FAILED; | 734 return AUDCLNT_E_ENDPOINT_CREATE_FAILED; |
735 } | 735 } |
736 | 736 |
737 HRESULT hr = GetPreferredAudioParameters(client.get(), params); | 737 HRESULT hr = GetPreferredAudioParameters(client.Get(), params); |
738 if (FAILED(hr) || is_output_device || !params->IsValid()) | 738 if (FAILED(hr) || is_output_device || !params->IsValid()) |
739 return hr; | 739 return hr; |
740 | 740 |
741 // The following functionality is only for input devices. | 741 // The following functionality is only for input devices. |
742 DCHECK(!is_output_device); | 742 DCHECK(!is_output_device); |
743 | 743 |
744 // TODO(dalecurtis): Old code rewrote != 1 channels to stereo, do we still | 744 // TODO(dalecurtis): Old code rewrote != 1 channels to stereo, do we still |
745 // need to do the same thing? | 745 // need to do the same thing? |
746 if (params->channels() != 1) { | 746 if (params->channels() != 1) { |
747 params->Reset(params->format(), CHANNEL_LAYOUT_STEREO, | 747 params->Reset(params->format(), CHANNEL_LAYOUT_STEREO, |
748 params->sample_rate(), params->bits_per_sample(), | 748 params->sample_rate(), params->bits_per_sample(), |
749 params->frames_per_buffer()); | 749 params->frames_per_buffer()); |
750 } | 750 } |
751 | 751 |
752 return hr; | 752 return hr; |
753 } | 753 } |
754 | 754 |
755 ChannelConfig CoreAudioUtil::GetChannelConfig(const std::string& device_id, | 755 ChannelConfig CoreAudioUtil::GetChannelConfig(const std::string& device_id, |
756 EDataFlow data_flow) { | 756 EDataFlow data_flow) { |
757 ScopedComPtr<IAudioClient> client( | 757 ScopedComPtr<IAudioClient> client( |
758 CreateClient(device_id, data_flow, eConsole)); | 758 CreateClient(device_id, data_flow, eConsole)); |
759 | 759 |
760 WAVEFORMATPCMEX format = {}; | 760 WAVEFORMATPCMEX format = {}; |
761 if (!client.get() || FAILED(GetSharedModeMixFormat(client.get(), &format))) | 761 if (!client.Get() || FAILED(GetSharedModeMixFormat(client.Get(), &format))) |
762 return 0; | 762 return 0; |
763 | 763 |
764 return static_cast<ChannelConfig>(format.dwChannelMask); | 764 return static_cast<ChannelConfig>(format.dwChannelMask); |
765 } | 765 } |
766 | 766 |
767 HRESULT CoreAudioUtil::SharedModeInitialize(IAudioClient* client, | 767 HRESULT CoreAudioUtil::SharedModeInitialize(IAudioClient* client, |
768 const WAVEFORMATPCMEX* format, | 768 const WAVEFORMATPCMEX* format, |
769 HANDLE event_handle, | 769 HANDLE event_handle, |
770 uint32_t* endpoint_buffer_size, | 770 uint32_t* endpoint_buffer_size, |
771 const GUID* session_guid) { | 771 const GUID* session_guid) { |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 | 920 |
921 if (variant.type() == VT_BSTR && variant.ptr()->bstrVal) { | 921 if (variant.type() == VT_BSTR && variant.ptr()->bstrVal) { |
922 base::WideToUTF8(variant.ptr()->bstrVal, wcslen(variant.ptr()->bstrVal), | 922 base::WideToUTF8(variant.ptr()->bstrVal, wcslen(variant.ptr()->bstrVal), |
923 driver_version); | 923 driver_version); |
924 } | 924 } |
925 | 925 |
926 return true; | 926 return true; |
927 } | 927 } |
928 | 928 |
929 } // namespace media | 929 } // namespace media |
OLD | NEW |