| 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 |