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

Side by Side Diff: media/audio/mac/audio_auhal_mac.cc

Issue 2683033003: Tell CoreAudio how to interpret Chrome's channel layout. (Closed)
Patch Set: Address comments. 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/mac/audio_auhal_mac.h ('k') | media/base/channel_layout.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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/mac/audio_auhal_mac.h" 5 #include "media/audio/mac/audio_auhal_mac.h"
6 6
7 #include <CoreServices/CoreServices.h> 7 #include <CoreServices/CoreServices.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cstddef>
10 #include <string> 11 #include <string>
11 12
12 #include "base/bind.h" 13 #include "base/bind.h"
13 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/mac/mac_logging.h" 16 #include "base/mac/mac_logging.h"
16 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
17 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
18 #include "base/trace_event/trace_event.h" 19 #include "base/trace_event/trace_event.h"
19 #include "media/audio/mac/audio_manager_mac.h" 20 #include "media/audio/mac/audio_manager_mac.h"
20 #include "media/base/audio_pull_fifo.h" 21 #include "media/base/audio_pull_fifo.h"
21 #include "media/base/audio_timestamp_helper.h" 22 #include "media/base/audio_timestamp_helper.h"
22 23
23 namespace media { 24 namespace media {
24 25
26 // Mapping from Chrome's channel layout to CoreAudio layout. This must match the
27 // layout of the Channels enum in |channel_layout.h|
28 static const AudioChannelLabel kCoreAudioChannelMapping[] = {
29 kAudioChannelLabel_Left,
30 kAudioChannelLabel_Right,
31 kAudioChannelLabel_Center,
32 kAudioChannelLabel_LFEScreen,
33 kAudioChannelLabel_LeftSurround,
34 kAudioChannelLabel_RightSurround,
35 kAudioChannelLabel_LeftCenter,
36 kAudioChannelLabel_RightCenter,
37 kAudioChannelLabel_CenterSurround,
38 kAudioChannelLabel_LeftSurroundDirect,
39 kAudioChannelLabel_RightSurroundDirect,
40 };
41 static_assert(0 == LEFT && 1 == RIGHT && 2 == CENTER && 3 == LFE &&
42 4 == BACK_LEFT &&
43 5 == BACK_RIGHT &&
44 6 == LEFT_OF_CENTER &&
45 7 == RIGHT_OF_CENTER &&
46 8 == BACK_CENTER &&
47 9 == SIDE_LEFT &&
48 10 == SIDE_RIGHT,
49 "Channel positions must match CoreAudio channel order.");
50
25 static void WrapBufferList(AudioBufferList* buffer_list, 51 static void WrapBufferList(AudioBufferList* buffer_list,
26 AudioBus* bus, 52 AudioBus* bus,
27 int frames) { 53 int frames) {
28 DCHECK(buffer_list); 54 DCHECK(buffer_list);
29 DCHECK(bus); 55 DCHECK(bus);
30 const int channels = bus->channels(); 56 const int channels = bus->channels();
31 const int buffer_list_channels = buffer_list->mNumberBuffers; 57 const int buffer_list_channels = buffer_list->mNumberBuffers;
32 CHECK_EQ(channels, buffer_list_channels); 58 CHECK_EQ(channels, buffer_list_channels);
33 59
34 // Copy pointers from AudioBufferList. 60 // Copy pointers from AudioBufferList.
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 kAudioUnitProperty_SetRenderCallback, 554 kAudioUnitProperty_SetRenderCallback,
529 kAudioUnitScope_Input, 555 kAudioUnitScope_Input,
530 0, 556 0,
531 &callback, 557 &callback,
532 sizeof(callback)); 558 sizeof(callback));
533 if (result != noErr) { 559 if (result != noErr) {
534 CloseAudioUnit(); 560 CloseAudioUnit();
535 return false; 561 return false;
536 } 562 }
537 563
564 SetAudioChannelLayout();
565
538 result = AudioUnitInitialize(audio_unit_); 566 result = AudioUnitInitialize(audio_unit_);
539 if (result != noErr) { 567 if (result != noErr) {
540 OSSTATUS_DLOG(ERROR, result) << "AudioUnitInitialize() failed."; 568 OSSTATUS_DLOG(ERROR, result) << "AudioUnitInitialize() failed.";
541 CloseAudioUnit(); 569 CloseAudioUnit();
542 return false; 570 return false;
543 } 571 }
544 572
545 return true; 573 return true;
546 } 574 }
547 575
548 void AUHALStream::CloseAudioUnit() { 576 void AUHALStream::CloseAudioUnit() {
549 DCHECK(thread_checker_.CalledOnValidThread()); 577 DCHECK(thread_checker_.CalledOnValidThread());
550 if (!audio_unit_) 578 if (!audio_unit_)
551 return; 579 return;
552 580
553 OSStatus result = AudioUnitUninitialize(audio_unit_); 581 OSStatus result = AudioUnitUninitialize(audio_unit_);
554 OSSTATUS_DLOG_IF(ERROR, result != noErr, result) 582 OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
555 << "AudioUnitUninitialize() failed."; 583 << "AudioUnitUninitialize() failed.";
556 result = AudioComponentInstanceDispose(audio_unit_); 584 result = AudioComponentInstanceDispose(audio_unit_);
557 OSSTATUS_DLOG_IF(ERROR, result != noErr, result) 585 OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
558 << "AudioComponentInstanceDispose() failed."; 586 << "AudioComponentInstanceDispose() failed.";
559 audio_unit_ = 0; 587 audio_unit_ = 0;
560 } 588 }
561 589
590 void AUHALStream::SetAudioChannelLayout() {
591 DCHECK(audio_unit_);
592
593 // AudioChannelLayout is structure ending in a variable length array, so we
594 // can't directly allocate one. Instead compute the size and and allocate one
595 // inside of a byte array.
596 //
597 // Code modeled after example from Apple documentation here:
598 // https://developer.apple.com/library/content/qa/qa1627/_index.html
hongchan 2017/02/09 04:10:24 Thanks so much for doing this. That is one convolu
599 const size_t layout_size =
600 offsetof(AudioChannelLayout, mChannelDescriptions[params_.channels()]);
601 std::unique_ptr<uint8_t[]> layout_storage(new uint8_t[layout_size]);
602 memset(layout_storage.get(), 0, layout_size);
603 AudioChannelLayout* channel_layout =
604 reinterpret_cast<AudioChannelLayout*>(layout_storage.get());
605
606 channel_layout->mNumberChannelDescriptions = params_.channels();
607 channel_layout->mChannelLayoutTag =
608 kAudioChannelLayoutTag_UseChannelDescriptions;
609 AudioChannelDescription* descriptions = channel_layout->mChannelDescriptions;
610
611 if (params_.channel_layout() == CHANNEL_LAYOUT_DISCRETE) {
612 // For the discrete case just assume common input mappings.
613 for (int ch = 0; ch <= CHANNELS_MAX; ++ch) {
614 descriptions[ch].mChannelLabel = kCoreAudioChannelMapping[ch];
615 descriptions[ch].mChannelFlags = kAudioChannelFlags_AllOff;
616 }
617 } else if (params_.channel_layout() == CHANNEL_LAYOUT_MONO) {
618 // CoreAudio has a special label for mono.
619 DCHECK_EQ(params_.channels(), 1);
620 descriptions[0].mChannelLabel = kAudioChannelLabel_Mono;
621 descriptions[0].mChannelFlags = kAudioChannelFlags_AllOff;
622 } else {
623 for (int ch = 0; ch <= CHANNELS_MAX; ++ch) {
624 const int order =
625 ChannelOrder(params_.channel_layout(), static_cast<Channels>(ch));
626 if (order == -1)
627 continue;
628 descriptions[order].mChannelLabel = kCoreAudioChannelMapping[ch];
629 descriptions[order].mChannelFlags = kAudioChannelFlags_AllOff;
630 }
631 }
632
633 OSStatus result = AudioUnitSetProperty(
634 audio_unit_, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input,
635 0, channel_layout, layout_size);
636 if (result != noErr) {
637 OSSTATUS_DLOG(ERROR, result)
638 << "Failed to set audio channel layout. Using default layout.";
639 }
640 }
641
562 } // namespace media 642 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/mac/audio_auhal_mac.h ('k') | media/base/channel_layout.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698