Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: media/audio/win/core_audio_util_win.cc

Issue 2646423005: Remove the wave based audio capture implementation for Windows (Closed)
Patch Set: Minor cleanup + documentation Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/audio/win/audio_manager_win.cc ('k') | media/audio/win/device_enumeration_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 } 252 }
253 253
254 AUDCLNT_SHAREMODE CoreAudioUtil::GetShareMode() { 254 AUDCLNT_SHAREMODE CoreAudioUtil::GetShareMode() {
255 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); 255 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
256 if (cmd_line->HasSwitch(switches::kEnableExclusiveAudio)) 256 if (cmd_line->HasSwitch(switches::kEnableExclusiveAudio))
257 return AUDCLNT_SHAREMODE_EXCLUSIVE; 257 return AUDCLNT_SHAREMODE_EXCLUSIVE;
258 return AUDCLNT_SHAREMODE_SHARED; 258 return AUDCLNT_SHAREMODE_SHARED;
259 } 259 }
260 260
261 int CoreAudioUtil::NumberOfActiveDevices(EDataFlow data_flow) { 261 int CoreAudioUtil::NumberOfActiveDevices(EDataFlow data_flow) {
262 DCHECK(IsSupported());
263 // Create the IMMDeviceEnumerator interface. 262 // Create the IMMDeviceEnumerator interface.
264 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = 263 ScopedComPtr<IMMDeviceEnumerator> device_enumerator =
265 CreateDeviceEnumerator(); 264 CreateDeviceEnumerator();
266 if (!device_enumerator.get()) 265 if (!device_enumerator.get())
267 return 0; 266 return 0;
268 267
269 // Generate a collection of active (present and not disabled) audio endpoint 268 // Generate a collection of active (present and not disabled) audio endpoint
270 // devices for the specified data-flow direction. 269 // devices for the specified data-flow direction.
271 // This method will succeed even if all devices are disabled. 270 // This method will succeed even if all devices are disabled.
272 ScopedComPtr<IMMDeviceCollection> collection; 271 ScopedComPtr<IMMDeviceCollection> collection;
273 HRESULT hr = device_enumerator->EnumAudioEndpoints(data_flow, 272 HRESULT hr = device_enumerator->EnumAudioEndpoints(data_flow,
274 DEVICE_STATE_ACTIVE, 273 DEVICE_STATE_ACTIVE,
275 collection.Receive()); 274 collection.Receive());
276 if (FAILED(hr)) { 275 if (FAILED(hr)) {
277 LOG(ERROR) << "IMMDeviceCollection::EnumAudioEndpoints: " << std::hex << hr; 276 LOG(ERROR) << "IMMDeviceCollection::EnumAudioEndpoints: " << std::hex << hr;
278 return 0; 277 return 0;
279 } 278 }
280 279
281 // Retrieve the number of active audio devices for the specified direction 280 // Retrieve the number of active audio devices for the specified direction
282 UINT number_of_active_devices = 0; 281 UINT number_of_active_devices = 0;
283 collection->GetCount(&number_of_active_devices); 282 collection->GetCount(&number_of_active_devices);
284 DVLOG(2) << ((data_flow == eCapture) ? "[in ] " : "[out] ") 283 DVLOG(2) << ((data_flow == eCapture) ? "[in ] " : "[out] ")
285 << "number of devices: " << number_of_active_devices; 284 << "number of devices: " << number_of_active_devices;
286 return static_cast<int>(number_of_active_devices); 285 return static_cast<int>(number_of_active_devices);
287 } 286 }
288 287
289 ScopedComPtr<IMMDeviceEnumerator> CoreAudioUtil::CreateDeviceEnumerator() { 288 ScopedComPtr<IMMDeviceEnumerator> CoreAudioUtil::CreateDeviceEnumerator() {
290 DCHECK(IsSupported()); 289 return CreateDeviceEnumeratorInternal(true);
291 ScopedComPtr<IMMDeviceEnumerator> device_enumerator =
292 CreateDeviceEnumeratorInternal(true);
293 CHECK(device_enumerator);
294 return device_enumerator;
295 } 290 }
296 291
297 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDefaultDevice(EDataFlow data_flow, 292 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDefaultDevice(EDataFlow data_flow,
298 ERole role) { 293 ERole role) {
299 DCHECK(IsSupported());
300 ScopedComPtr<IMMDevice> endpoint_device; 294 ScopedComPtr<IMMDevice> endpoint_device;
301 295
302 // Create the IMMDeviceEnumerator interface. 296 // Create the IMMDeviceEnumerator interface.
303 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = 297 ScopedComPtr<IMMDeviceEnumerator> device_enumerator =
304 CreateDeviceEnumerator(); 298 CreateDeviceEnumerator();
305 if (!device_enumerator.get()) 299 if (!device_enumerator.get())
306 return endpoint_device; 300 return endpoint_device;
307 301
308 // Retrieve the default audio endpoint for the specified data-flow 302 // Retrieve the default audio endpoint for the specified data-flow
309 // direction and role. 303 // direction and role.
310 HRESULT hr = device_enumerator->GetDefaultAudioEndpoint( 304 HRESULT hr = device_enumerator->GetDefaultAudioEndpoint(
311 data_flow, role, endpoint_device.Receive()); 305 data_flow, role, endpoint_device.Receive());
312 306
313 if (FAILED(hr)) { 307 if (FAILED(hr)) {
314 DVLOG(1) << "IMMDeviceEnumerator::GetDefaultAudioEndpoint: " 308 DVLOG(1) << "IMMDeviceEnumerator::GetDefaultAudioEndpoint: "
315 << std::hex << hr; 309 << std::hex << hr;
316 return endpoint_device; 310 return endpoint_device;
317 } 311 }
318 312
319 // Verify that the audio endpoint device is active, i.e., that the audio 313 // Verify that the audio endpoint device is active, i.e., that the audio
320 // adapter that connects to the endpoint device is present and enabled. 314 // adapter that connects to the endpoint device is present and enabled.
321 if (!IsDeviceActive(endpoint_device.get())) { 315 if (!IsDeviceActive(endpoint_device.get())) {
322 DVLOG(1) << "Selected endpoint device is not active"; 316 DVLOG(1) << "Selected endpoint device is not active";
323 endpoint_device.Release(); 317 endpoint_device.Release();
324 } 318 }
325 return endpoint_device; 319 return endpoint_device;
326 } 320 }
327 321
328 std::string CoreAudioUtil::GetDefaultOutputDeviceID() { 322 std::string CoreAudioUtil::GetDefaultOutputDeviceID() {
329 DCHECK(IsSupported());
330 ScopedComPtr<IMMDevice> device(CreateDefaultDevice(eRender, eConsole)); 323 ScopedComPtr<IMMDevice> device(CreateDefaultDevice(eRender, eConsole));
331 return device.get() ? GetDeviceID(device.get()) : std::string(); 324 return device.get() ? GetDeviceID(device.get()) : std::string();
332 } 325 }
333 326
334 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDevice( 327 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDevice(
335 const std::string& device_id) { 328 const std::string& device_id) {
336 DCHECK(IsSupported());
337 ScopedComPtr<IMMDevice> endpoint_device; 329 ScopedComPtr<IMMDevice> endpoint_device;
338 330
339 // Create the IMMDeviceEnumerator interface. 331 // Create the IMMDeviceEnumerator interface.
340 ScopedComPtr<IMMDeviceEnumerator> device_enumerator = 332 ScopedComPtr<IMMDeviceEnumerator> device_enumerator =
341 CreateDeviceEnumerator(); 333 CreateDeviceEnumerator();
342 if (!device_enumerator.get()) 334 if (!device_enumerator.get())
343 return endpoint_device; 335 return endpoint_device;
344 336
345 // Retrieve an audio device specified by an endpoint device-identification 337 // Retrieve an audio device specified by an endpoint device-identification
346 // string. 338 // string.
(...skipping 10 matching lines...) Expand all
357 // Verify that the audio endpoint device is active, i.e., that the audio 349 // Verify that the audio endpoint device is active, i.e., that the audio
358 // adapter that connects to the endpoint device is present and enabled. 350 // adapter that connects to the endpoint device is present and enabled.
359 if (!IsDeviceActive(endpoint_device.get())) { 351 if (!IsDeviceActive(endpoint_device.get())) {
360 DVLOG(1) << "Selected endpoint device is not active"; 352 DVLOG(1) << "Selected endpoint device is not active";
361 endpoint_device.Release(); 353 endpoint_device.Release();
362 } 354 }
363 return endpoint_device; 355 return endpoint_device;
364 } 356 }
365 357
366 HRESULT CoreAudioUtil::GetDeviceName(IMMDevice* device, AudioDeviceName* name) { 358 HRESULT CoreAudioUtil::GetDeviceName(IMMDevice* device, AudioDeviceName* name) {
367 DCHECK(IsSupported());
368
369 // Retrieve unique name of endpoint device. 359 // Retrieve unique name of endpoint device.
370 // Example: "{0.0.1.00000000}.{8db6020f-18e3-4f25-b6f5-7726c9122574}". 360 // Example: "{0.0.1.00000000}.{8db6020f-18e3-4f25-b6f5-7726c9122574}".
371 AudioDeviceName device_name; 361 AudioDeviceName device_name;
372 device_name.unique_id = GetDeviceID(device); 362 device_name.unique_id = GetDeviceID(device);
373 if (device_name.unique_id.empty()) 363 if (device_name.unique_id.empty())
374 return E_FAIL; 364 return E_FAIL;
375 365
376 HRESULT hr = GetDeviceFriendlyNameInternal(device, &device_name.device_name); 366 HRESULT hr = GetDeviceFriendlyNameInternal(device, &device_name.device_name);
377 if (FAILED(hr)) 367 if (FAILED(hr))
378 return hr; 368 return hr;
379 369
380 *name = device_name; 370 *name = device_name;
381 DVLOG(2) << "friendly name: " << device_name.device_name; 371 DVLOG(2) << "friendly name: " << device_name.device_name;
382 DVLOG(2) << "unique id : " << device_name.unique_id; 372 DVLOG(2) << "unique id : " << device_name.unique_id;
383 return hr; 373 return hr;
384 } 374 }
385 375
386 std::string CoreAudioUtil::GetAudioControllerID(IMMDevice* device, 376 std::string CoreAudioUtil::GetAudioControllerID(IMMDevice* device,
387 IMMDeviceEnumerator* enumerator) { 377 IMMDeviceEnumerator* enumerator) {
388 DCHECK(IsSupported());
389
390 // Fetching the controller device id could be as simple as fetching the value 378 // Fetching the controller device id could be as simple as fetching the value
391 // of the "{B3F8FA53-0004-438E-9003-51A46E139BFC},2" property in the property 379 // of the "{B3F8FA53-0004-438E-9003-51A46E139BFC},2" property in the property
392 // store of the |device|, but that key isn't defined in any header and 380 // store of the |device|, but that key isn't defined in any header and
393 // according to MS should not be relied upon. 381 // according to MS should not be relied upon.
394 // So, instead, we go deeper, look at the device topology and fetch the 382 // So, instead, we go deeper, look at the device topology and fetch the
395 // PKEY_Device_InstanceId of the associated physical audio device. 383 // PKEY_Device_InstanceId of the associated physical audio device.
396 ScopedComPtr<IDeviceTopology> topology; 384 ScopedComPtr<IDeviceTopology> topology;
397 ScopedComPtr<IConnector> connector; 385 ScopedComPtr<IConnector> connector;
398 ScopedCoMem<WCHAR> filter_id; 386 ScopedCoMem<WCHAR> filter_id;
399 if (FAILED(device->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, 387 if (FAILED(device->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 GetAudioControllerID(output_device.get(), enumerator.get())); 466 GetAudioControllerID(output_device.get(), enumerator.get()));
479 if (output_controller_id == controller_id) 467 if (output_controller_id == controller_id)
480 break; 468 break;
481 output_device = NULL; 469 output_device = NULL;
482 } 470 }
483 471
484 return output_device.get() ? GetDeviceID(output_device.get()) : std::string(); 472 return output_device.get() ? GetDeviceID(output_device.get()) : std::string();
485 } 473 }
486 474
487 std::string CoreAudioUtil::GetFriendlyName(const std::string& device_id) { 475 std::string CoreAudioUtil::GetFriendlyName(const std::string& device_id) {
488 DCHECK(IsSupported());
489 ScopedComPtr<IMMDevice> audio_device = CreateDevice(device_id); 476 ScopedComPtr<IMMDevice> audio_device = CreateDevice(device_id);
490 if (!audio_device.get()) 477 if (!audio_device.get())
491 return std::string(); 478 return std::string();
492 479
493 AudioDeviceName device_name; 480 AudioDeviceName device_name;
494 HRESULT hr = GetDeviceName(audio_device.get(), &device_name); 481 HRESULT hr = GetDeviceName(audio_device.get(), &device_name);
495 if (FAILED(hr)) 482 if (FAILED(hr))
496 return std::string(); 483 return std::string();
497 484
498 return device_name.device_name; 485 return device_name.device_name;
499 } 486 }
500 487
501 bool CoreAudioUtil::DeviceIsDefault(EDataFlow flow, 488 bool CoreAudioUtil::DeviceIsDefault(EDataFlow flow,
502 ERole role, 489 ERole role,
503 const std::string& device_id) { 490 const std::string& device_id) {
504 DCHECK(IsSupported());
505 ScopedComPtr<IMMDevice> device = CreateDefaultDevice(flow, role); 491 ScopedComPtr<IMMDevice> device = CreateDefaultDevice(flow, role);
506 if (!device.get()) 492 if (!device.get())
507 return false; 493 return false;
508 494
509 std::string str_default(GetDeviceID(device.get())); 495 std::string str_default(GetDeviceID(device.get()));
510 return device_id.compare(str_default) == 0; 496 return device_id.compare(str_default) == 0;
511 } 497 }
512 498
513 EDataFlow CoreAudioUtil::GetDataFlow(IMMDevice* device) { 499 EDataFlow CoreAudioUtil::GetDataFlow(IMMDevice* device) {
514 DCHECK(IsSupported());
515 ScopedComPtr<IMMEndpoint> endpoint; 500 ScopedComPtr<IMMEndpoint> endpoint;
516 HRESULT hr = device->QueryInterface(endpoint.Receive()); 501 HRESULT hr = device->QueryInterface(endpoint.Receive());
517 if (FAILED(hr)) { 502 if (FAILED(hr)) {
518 DVLOG(1) << "IMMDevice::QueryInterface: " << std::hex << hr; 503 DVLOG(1) << "IMMDevice::QueryInterface: " << std::hex << hr;
519 return eAll; 504 return eAll;
520 } 505 }
521 506
522 EDataFlow data_flow; 507 EDataFlow data_flow;
523 hr = endpoint->GetDataFlow(&data_flow); 508 hr = endpoint->GetDataFlow(&data_flow);
524 if (FAILED(hr)) { 509 if (FAILED(hr)) {
525 DVLOG(1) << "IMMEndpoint::GetDataFlow: " << std::hex << hr; 510 DVLOG(1) << "IMMEndpoint::GetDataFlow: " << std::hex << hr;
526 return eAll; 511 return eAll;
527 } 512 }
528 return data_flow; 513 return data_flow;
529 } 514 }
530 515
531 ScopedComPtr<IAudioClient> CoreAudioUtil::CreateClient( 516 ScopedComPtr<IAudioClient> CoreAudioUtil::CreateClient(
532 IMMDevice* audio_device) { 517 IMMDevice* audio_device) {
533 DCHECK(IsSupported());
534
535 // Creates and activates an IAudioClient COM object given the selected 518 // Creates and activates an IAudioClient COM object given the selected
536 // endpoint device. 519 // endpoint device.
537 ScopedComPtr<IAudioClient> audio_client; 520 ScopedComPtr<IAudioClient> audio_client;
538 HRESULT hr = audio_device->Activate(__uuidof(IAudioClient), 521 HRESULT hr = audio_device->Activate(__uuidof(IAudioClient),
539 CLSCTX_INPROC_SERVER, 522 CLSCTX_INPROC_SERVER,
540 NULL, 523 NULL,
541 audio_client.ReceiveVoid()); 524 audio_client.ReceiveVoid());
542 DVLOG_IF(1, FAILED(hr)) << "IMMDevice::Activate: " << std::hex << hr; 525 DVLOG_IF(1, FAILED(hr)) << "IMMDevice::Activate: " << std::hex << hr;
543 return audio_client; 526 return audio_client;
544 } 527 }
545 528
546 ScopedComPtr<IAudioClient> CoreAudioUtil::CreateDefaultClient( 529 ScopedComPtr<IAudioClient> CoreAudioUtil::CreateDefaultClient(
547 EDataFlow data_flow, ERole role) { 530 EDataFlow data_flow, ERole role) {
548 DCHECK(IsSupported());
549 ScopedComPtr<IMMDevice> default_device(CreateDefaultDevice(data_flow, role)); 531 ScopedComPtr<IMMDevice> default_device(CreateDefaultDevice(data_flow, role));
550 return (default_device.get() ? CreateClient(default_device.get()) 532 return (default_device.get() ? CreateClient(default_device.get())
551 : ScopedComPtr<IAudioClient>()); 533 : ScopedComPtr<IAudioClient>());
552 } 534 }
553 535
554 ScopedComPtr<IAudioClient> CoreAudioUtil::CreateClient( 536 ScopedComPtr<IAudioClient> CoreAudioUtil::CreateClient(
555 const std::string& device_id, EDataFlow data_flow, ERole role) { 537 const std::string& device_id, EDataFlow data_flow, ERole role) {
556 if (IsDefaultDeviceId(device_id)) 538 if (IsDefaultDeviceId(device_id))
557 return CreateDefaultClient(data_flow, role); 539 return CreateDefaultClient(data_flow, role);
558 540
559 ScopedComPtr<IMMDevice> device(CreateDevice(device_id)); 541 ScopedComPtr<IMMDevice> device(CreateDevice(device_id));
560 if (!device.get()) 542 if (!device.get())
561 return ScopedComPtr<IAudioClient>(); 543 return ScopedComPtr<IAudioClient>();
562 544
563 return CreateClient(device.get()); 545 return CreateClient(device.get());
564 } 546 }
565 547
566 HRESULT CoreAudioUtil::GetSharedModeMixFormat( 548 HRESULT CoreAudioUtil::GetSharedModeMixFormat(
567 IAudioClient* client, WAVEFORMATPCMEX* format) { 549 IAudioClient* client, WAVEFORMATPCMEX* format) {
568 DCHECK(IsSupported());
569 ScopedCoMem<WAVEFORMATPCMEX> format_pcmex; 550 ScopedCoMem<WAVEFORMATPCMEX> format_pcmex;
570 HRESULT hr = client->GetMixFormat( 551 HRESULT hr = client->GetMixFormat(
571 reinterpret_cast<WAVEFORMATEX**>(&format_pcmex)); 552 reinterpret_cast<WAVEFORMATEX**>(&format_pcmex));
572 if (FAILED(hr)) 553 if (FAILED(hr))
573 return hr; 554 return hr;
574 555
575 size_t bytes = sizeof(WAVEFORMATEX) + format_pcmex->Format.cbSize; 556 size_t bytes = sizeof(WAVEFORMATEX) + format_pcmex->Format.cbSize;
576 DCHECK_EQ(bytes, sizeof(WAVEFORMATPCMEX)); 557 DCHECK_EQ(bytes, sizeof(WAVEFORMATPCMEX));
577 558
578 memcpy(format, format_pcmex, bytes); 559 memcpy(format, format_pcmex, bytes);
579 DVLOG(2) << *format; 560 DVLOG(2) << *format;
580 561
581 return hr; 562 return hr;
582 } 563 }
583 564
584 bool CoreAudioUtil::IsFormatSupported(IAudioClient* client, 565 bool CoreAudioUtil::IsFormatSupported(IAudioClient* client,
585 AUDCLNT_SHAREMODE share_mode, 566 AUDCLNT_SHAREMODE share_mode,
586 const WAVEFORMATPCMEX* format) { 567 const WAVEFORMATPCMEX* format) {
587 DCHECK(IsSupported());
588 ScopedCoMem<WAVEFORMATEXTENSIBLE> closest_match; 568 ScopedCoMem<WAVEFORMATEXTENSIBLE> closest_match;
589 HRESULT hr = client->IsFormatSupported( 569 HRESULT hr = client->IsFormatSupported(
590 share_mode, reinterpret_cast<const WAVEFORMATEX*>(format), 570 share_mode, reinterpret_cast<const WAVEFORMATEX*>(format),
591 reinterpret_cast<WAVEFORMATEX**>(&closest_match)); 571 reinterpret_cast<WAVEFORMATEX**>(&closest_match));
592 572
593 // This log can only be triggered for shared mode. 573 // This log can only be triggered for shared mode.
594 DLOG_IF(ERROR, hr == S_FALSE) << "Format is not supported " 574 DLOG_IF(ERROR, hr == S_FALSE) << "Format is not supported "
595 << "but a closest match exists."; 575 << "but a closest match exists.";
596 // This log can be triggered both for shared and exclusive modes. 576 // This log can be triggered both for shared and exclusive modes.
597 DLOG_IF(ERROR, hr == AUDCLNT_E_UNSUPPORTED_FORMAT) << "Unsupported format."; 577 DLOG_IF(ERROR, hr == AUDCLNT_E_UNSUPPORTED_FORMAT) << "Unsupported format.";
598 if (hr == S_FALSE) { 578 if (hr == S_FALSE) {
599 DVLOG(2) << *closest_match; 579 DVLOG(2) << *closest_match;
600 } 580 }
601 581
602 return (hr == S_OK); 582 return (hr == S_OK);
603 } 583 }
604 584
605 bool CoreAudioUtil::IsChannelLayoutSupported(const std::string& device_id, 585 bool CoreAudioUtil::IsChannelLayoutSupported(const std::string& device_id,
606 EDataFlow data_flow, 586 EDataFlow data_flow,
607 ERole role, 587 ERole role,
608 ChannelLayout channel_layout) { 588 ChannelLayout channel_layout) {
609 DCHECK(IsSupported());
610
611 // First, get the preferred mixing format for shared mode streams. 589 // First, get the preferred mixing format for shared mode streams.
612
613 ScopedComPtr<IAudioClient> client(CreateClient(device_id, data_flow, role)); 590 ScopedComPtr<IAudioClient> client(CreateClient(device_id, data_flow, role));
614 if (!client.get()) 591 if (!client.get())
615 return false; 592 return false;
616 593
617 WAVEFORMATPCMEX format; 594 WAVEFORMATPCMEX format;
618 HRESULT hr = GetSharedModeMixFormat(client.get(), &format); 595 HRESULT hr = GetSharedModeMixFormat(client.get(), &format);
619 if (FAILED(hr)) 596 if (FAILED(hr))
620 return false; 597 return false;
621 598
622 // Next, check if it is possible to use an alternative format where the 599 // Next, check if it is possible to use an alternative format where the
(...skipping 25 matching lines...) Expand all
648 // an even wider range of shared-mode formats where the installation package 625 // an even wider range of shared-mode formats where the installation package
649 // for the audio device includes a local effects (LFX) audio processing 626 // for the audio device includes a local effects (LFX) audio processing
650 // object (APO) that can handle format conversions. 627 // object (APO) that can handle format conversions.
651 return CoreAudioUtil::IsFormatSupported(client.get(), 628 return CoreAudioUtil::IsFormatSupported(client.get(),
652 AUDCLNT_SHAREMODE_SHARED, &format); 629 AUDCLNT_SHAREMODE_SHARED, &format);
653 } 630 }
654 631
655 HRESULT CoreAudioUtil::GetDevicePeriod(IAudioClient* client, 632 HRESULT CoreAudioUtil::GetDevicePeriod(IAudioClient* client,
656 AUDCLNT_SHAREMODE share_mode, 633 AUDCLNT_SHAREMODE share_mode,
657 REFERENCE_TIME* device_period) { 634 REFERENCE_TIME* device_period) {
658 DCHECK(IsSupported());
659
660 // Get the period of the engine thread. 635 // Get the period of the engine thread.
661 REFERENCE_TIME default_period = 0; 636 REFERENCE_TIME default_period = 0;
662 REFERENCE_TIME minimum_period = 0; 637 REFERENCE_TIME minimum_period = 0;
663 HRESULT hr = client->GetDevicePeriod(&default_period, &minimum_period); 638 HRESULT hr = client->GetDevicePeriod(&default_period, &minimum_period);
664 if (FAILED(hr)) 639 if (FAILED(hr))
665 return hr; 640 return hr;
666 641
667 *device_period = (share_mode == AUDCLNT_SHAREMODE_SHARED) ? default_period : 642 *device_period = (share_mode == AUDCLNT_SHAREMODE_SHARED) ? default_period :
668 minimum_period; 643 minimum_period;
669 DVLOG(2) << "device_period: " 644 DVLOG(2) << "device_period: "
670 << RefererenceTimeToTimeDelta(*device_period).InMillisecondsF() 645 << RefererenceTimeToTimeDelta(*device_period).InMillisecondsF()
671 << " [ms]"; 646 << " [ms]";
672 return hr; 647 return hr;
673 } 648 }
674 649
675 HRESULT CoreAudioUtil::GetPreferredAudioParameters( 650 HRESULT CoreAudioUtil::GetPreferredAudioParameters(
676 IAudioClient* client, AudioParameters* params) { 651 IAudioClient* client, AudioParameters* params) {
677 DCHECK(IsSupported());
678 WAVEFORMATPCMEX mix_format; 652 WAVEFORMATPCMEX mix_format;
679 HRESULT hr = GetSharedModeMixFormat(client, &mix_format); 653 HRESULT hr = GetSharedModeMixFormat(client, &mix_format);
680 if (FAILED(hr)) 654 if (FAILED(hr))
681 return hr; 655 return hr;
682 656
683 REFERENCE_TIME default_period = 0; 657 REFERENCE_TIME default_period = 0;
684 hr = GetDevicePeriod(client, AUDCLNT_SHAREMODE_SHARED, &default_period); 658 hr = GetDevicePeriod(client, AUDCLNT_SHAREMODE_SHARED, &default_period);
685 if (FAILED(hr)) 659 if (FAILED(hr))
686 return hr; 660 return hr;
687 661
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 bits_per_sample, 708 bits_per_sample,
735 frames_per_buffer); 709 frames_per_buffer);
736 710
737 *params = audio_params; 711 *params = audio_params;
738 return hr; 712 return hr;
739 } 713 }
740 714
741 HRESULT CoreAudioUtil::GetPreferredAudioParameters(const std::string& device_id, 715 HRESULT CoreAudioUtil::GetPreferredAudioParameters(const std::string& device_id,
742 bool is_output_device, 716 bool is_output_device,
743 AudioParameters* params) { 717 AudioParameters* params) {
744 DCHECK(IsSupported());
745
746 ScopedComPtr<IMMDevice> device; 718 ScopedComPtr<IMMDevice> device;
747 if (device_id == AudioDeviceDescription::kDefaultDeviceId) { 719 if (device_id == AudioDeviceDescription::kDefaultDeviceId) {
748 device = CoreAudioUtil::CreateDefaultDevice( 720 device = CoreAudioUtil::CreateDefaultDevice(
749 is_output_device ? eRender : eCapture, eConsole); 721 is_output_device ? eRender : eCapture, eConsole);
750 } else if (device_id == AudioDeviceDescription::kLoopbackInputDeviceId || 722 } else if (device_id == AudioDeviceDescription::kLoopbackInputDeviceId ||
751 device_id == AudioDeviceDescription::kLoopbackWithMuteDeviceId) { 723 device_id == AudioDeviceDescription::kLoopbackWithMuteDeviceId) {
752 DCHECK(!is_output_device); 724 DCHECK(!is_output_device);
753 device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); 725 device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole);
754 } else if (device_id == AudioDeviceDescription::kCommunicationsDeviceId) { 726 } else if (device_id == AudioDeviceDescription::kCommunicationsDeviceId) {
755 device = CoreAudioUtil::CreateDefaultDevice( 727 device = CoreAudioUtil::CreateDefaultDevice(
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 return 0; 771 return 0;
800 772
801 return static_cast<ChannelConfig>(format.dwChannelMask); 773 return static_cast<ChannelConfig>(format.dwChannelMask);
802 } 774 }
803 775
804 HRESULT CoreAudioUtil::SharedModeInitialize(IAudioClient* client, 776 HRESULT CoreAudioUtil::SharedModeInitialize(IAudioClient* client,
805 const WAVEFORMATPCMEX* format, 777 const WAVEFORMATPCMEX* format,
806 HANDLE event_handle, 778 HANDLE event_handle,
807 uint32_t* endpoint_buffer_size, 779 uint32_t* endpoint_buffer_size,
808 const GUID* session_guid) { 780 const GUID* session_guid) {
809 DCHECK(IsSupported());
810
811 // Use default flags (i.e, dont set AUDCLNT_STREAMFLAGS_NOPERSIST) to 781 // Use default flags (i.e, dont set AUDCLNT_STREAMFLAGS_NOPERSIST) to
812 // ensure that the volume level and muting state for a rendering session 782 // ensure that the volume level and muting state for a rendering session
813 // are persistent across system restarts. The volume level and muting 783 // are persistent across system restarts. The volume level and muting
814 // state for a capture session are never persistent. 784 // state for a capture session are never persistent.
815 DWORD stream_flags = 0; 785 DWORD stream_flags = 0;
816 786
817 // Enable event-driven streaming if a valid event handle is provided. 787 // Enable event-driven streaming if a valid event handle is provided.
818 // After the stream starts, the audio engine will signal the event handle 788 // After the stream starts, the audio engine will signal the event handle
819 // to notify the client each time a buffer becomes ready to process. 789 // to notify the client each time a buffer becomes ready to process.
820 // Event-driven buffering is supported for both rendering and capturing. 790 // Event-driven buffering is supported for both rendering and capturing.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 // TODO(henrika): utilize when delay measurements are added. 828 // TODO(henrika): utilize when delay measurements are added.
859 REFERENCE_TIME latency = 0; 829 REFERENCE_TIME latency = 0;
860 hr = client->GetStreamLatency(&latency); 830 hr = client->GetStreamLatency(&latency);
861 DVLOG(2) << "stream latency: " 831 DVLOG(2) << "stream latency: "
862 << RefererenceTimeToTimeDelta(latency).InMillisecondsF() << " [ms]"; 832 << RefererenceTimeToTimeDelta(latency).InMillisecondsF() << " [ms]";
863 return hr; 833 return hr;
864 } 834 }
865 835
866 ScopedComPtr<IAudioRenderClient> CoreAudioUtil::CreateRenderClient( 836 ScopedComPtr<IAudioRenderClient> CoreAudioUtil::CreateRenderClient(
867 IAudioClient* client) { 837 IAudioClient* client) {
868 DCHECK(IsSupported());
869
870 // Get access to the IAudioRenderClient interface. This interface 838 // Get access to the IAudioRenderClient interface. This interface
871 // enables us to write output data to a rendering endpoint buffer. 839 // enables us to write output data to a rendering endpoint buffer.
872 ScopedComPtr<IAudioRenderClient> audio_render_client; 840 ScopedComPtr<IAudioRenderClient> audio_render_client;
873 HRESULT hr = client->GetService(__uuidof(IAudioRenderClient), 841 HRESULT hr = client->GetService(__uuidof(IAudioRenderClient),
874 audio_render_client.ReceiveVoid()); 842 audio_render_client.ReceiveVoid());
875 if (FAILED(hr)) { 843 if (FAILED(hr)) {
876 DVLOG(1) << "IAudioClient::GetService: " << std::hex << hr; 844 DVLOG(1) << "IAudioClient::GetService: " << std::hex << hr;
877 return ScopedComPtr<IAudioRenderClient>(); 845 return ScopedComPtr<IAudioRenderClient>();
878 } 846 }
879 return audio_render_client; 847 return audio_render_client;
880 } 848 }
881 849
882 ScopedComPtr<IAudioCaptureClient> CoreAudioUtil::CreateCaptureClient( 850 ScopedComPtr<IAudioCaptureClient> CoreAudioUtil::CreateCaptureClient(
883 IAudioClient* client) { 851 IAudioClient* client) {
884 DCHECK(IsSupported());
885
886 // Get access to the IAudioCaptureClient interface. This interface 852 // Get access to the IAudioCaptureClient interface. This interface
887 // enables us to read input data from a capturing endpoint buffer. 853 // enables us to read input data from a capturing endpoint buffer.
888 ScopedComPtr<IAudioCaptureClient> audio_capture_client; 854 ScopedComPtr<IAudioCaptureClient> audio_capture_client;
889 HRESULT hr = client->GetService(__uuidof(IAudioCaptureClient), 855 HRESULT hr = client->GetService(__uuidof(IAudioCaptureClient),
890 audio_capture_client.ReceiveVoid()); 856 audio_capture_client.ReceiveVoid());
891 if (FAILED(hr)) { 857 if (FAILED(hr)) {
892 DVLOG(1) << "IAudioClient::GetService: " << std::hex << hr; 858 DVLOG(1) << "IAudioClient::GetService: " << std::hex << hr;
893 return ScopedComPtr<IAudioCaptureClient>(); 859 return ScopedComPtr<IAudioCaptureClient>();
894 } 860 }
895 return audio_capture_client; 861 return audio_capture_client;
896 } 862 }
897 863
898 bool CoreAudioUtil::FillRenderEndpointBufferWithSilence( 864 bool CoreAudioUtil::FillRenderEndpointBufferWithSilence(
899 IAudioClient* client, IAudioRenderClient* render_client) { 865 IAudioClient* client, IAudioRenderClient* render_client) {
900 DCHECK(IsSupported());
901
902 UINT32 endpoint_buffer_size = 0; 866 UINT32 endpoint_buffer_size = 0;
903 if (FAILED(client->GetBufferSize(&endpoint_buffer_size))) 867 if (FAILED(client->GetBufferSize(&endpoint_buffer_size)))
904 return false; 868 return false;
905 869
906 UINT32 num_queued_frames = 0; 870 UINT32 num_queued_frames = 0;
907 if (FAILED(client->GetCurrentPadding(&num_queued_frames))) 871 if (FAILED(client->GetCurrentPadding(&num_queued_frames)))
908 return false; 872 return false;
909 873
910 BYTE* data = NULL; 874 BYTE* data = NULL;
911 int num_frames_to_fill = endpoint_buffer_size - num_queued_frames; 875 int num_frames_to_fill = endpoint_buffer_size - num_queued_frames;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
965 929
966 if (variant.type() == VT_BSTR && variant.ptr()->bstrVal) { 930 if (variant.type() == VT_BSTR && variant.ptr()->bstrVal) {
967 base::WideToUTF8(variant.ptr()->bstrVal, wcslen(variant.ptr()->bstrVal), 931 base::WideToUTF8(variant.ptr()->bstrVal, wcslen(variant.ptr()->bstrVal),
968 driver_version); 932 driver_version);
969 } 933 }
970 934
971 return true; 935 return true;
972 } 936 }
973 937
974 } // namespace media 938 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/win/audio_manager_win.cc ('k') | media/audio/win/device_enumeration_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698