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/mac/audio_output_mac.h" | 5 #include "media/audio/mac/audio_output_mac.h" |
6 | 6 |
7 #include <CoreServices/CoreServices.h> | 7 #include <CoreServices/CoreServices.h> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 reinterpret_cast<AudioChannelLayout*>(malloc(core_layout_size))); | 131 reinterpret_cast<AudioChannelLayout*>(malloc(core_layout_size))); |
132 memset(core_channel_layout.get(), 0, core_layout_size); | 132 memset(core_channel_layout.get(), 0, core_layout_size); |
133 err = AudioObjectGetPropertyData(device_id, &property_address, 0, NULL, | 133 err = AudioObjectGetPropertyData(device_id, &property_address, 0, NULL, |
134 &core_layout_size, | 134 &core_layout_size, |
135 core_channel_layout.get()); | 135 core_channel_layout.get()); |
136 if (err != noErr) { | 136 if (err != noErr) { |
137 HandleError(err); | 137 HandleError(err); |
138 return false; | 138 return false; |
139 } | 139 } |
140 | 140 |
141 num_core_channels_ = | 141 num_core_channels_ = std::min( |
142 static_cast<int>(core_channel_layout->mNumberChannelDescriptions); | 142 static_cast<int>(CHANNELS_MAX), |
| 143 static_cast<int>(core_channel_layout->mNumberChannelDescriptions)); |
143 if (num_core_channels_ == 2 && | 144 if (num_core_channels_ == 2 && |
144 ChannelLayoutToChannelCount(source_layout_) > 2) { | 145 ChannelLayoutToChannelCount(source_layout_) > 2) { |
145 should_down_mix_ = true; | 146 should_down_mix_ = true; |
146 format_.mChannelsPerFrame = num_core_channels_; | 147 format_.mChannelsPerFrame = num_core_channels_; |
147 format_.mBytesPerFrame = (format_.mBitsPerChannel >> 3) * | 148 format_.mBytesPerFrame = (format_.mBitsPerChannel >> 3) * |
148 format_.mChannelsPerFrame; | 149 format_.mChannelsPerFrame; |
149 format_.mBytesPerPacket = format_.mBytesPerFrame * format_.mFramesPerPacket; | 150 format_.mBytesPerPacket = format_.mBytesPerFrame * format_.mFramesPerPacket; |
150 } else { | 151 } else { |
151 should_down_mix_ = false; | 152 should_down_mix_ = false; |
152 } | 153 } |
(...skipping 30 matching lines...) Expand all Loading... |
183 for (int i = 0; i < num_core_channels_; ++i) { | 184 for (int i = 0; i < num_core_channels_; ++i) { |
184 AudioChannelLabel label = | 185 AudioChannelLabel label = |
185 core_channel_layout->mChannelDescriptions[i].mChannelLabel; | 186 core_channel_layout->mChannelDescriptions[i].mChannelLabel; |
186 if (label == kAudioChannelLabel_Unknown) { | 187 if (label == kAudioChannelLabel_Unknown) { |
187 continue; | 188 continue; |
188 } | 189 } |
189 all_channels_unknown = false; | 190 all_channels_unknown = false; |
190 switch (label) { | 191 switch (label) { |
191 case kAudioChannelLabel_Left: | 192 case kAudioChannelLabel_Left: |
192 core_channel_orderings_[LEFT] = i; | 193 core_channel_orderings_[LEFT] = i; |
193 channel_remap_[i] = kChannelOrderings[source_layout_][LEFT]; | 194 channel_remap_[i] = ChannelOrder(source_layout_, LEFT); |
194 break; | 195 break; |
195 case kAudioChannelLabel_Right: | 196 case kAudioChannelLabel_Right: |
196 core_channel_orderings_[RIGHT] = i; | 197 core_channel_orderings_[RIGHT] = i; |
197 channel_remap_[i] = kChannelOrderings[source_layout_][RIGHT]; | 198 channel_remap_[i] = ChannelOrder(source_layout_, RIGHT); |
198 break; | 199 break; |
199 case kAudioChannelLabel_Center: | 200 case kAudioChannelLabel_Center: |
200 core_channel_orderings_[CENTER] = i; | 201 core_channel_orderings_[CENTER] = i; |
201 channel_remap_[i] = kChannelOrderings[source_layout_][CENTER]; | 202 channel_remap_[i] = ChannelOrder(source_layout_, CENTER); |
202 break; | 203 break; |
203 case kAudioChannelLabel_LFEScreen: | 204 case kAudioChannelLabel_LFEScreen: |
204 core_channel_orderings_[LFE] = i; | 205 core_channel_orderings_[LFE] = i; |
205 channel_remap_[i] = kChannelOrderings[source_layout_][LFE]; | 206 channel_remap_[i] = ChannelOrder(source_layout_, LFE); |
206 break; | 207 break; |
207 case kAudioChannelLabel_LeftSurround: | 208 case kAudioChannelLabel_LeftSurround: |
208 core_channel_orderings_[SIDE_LEFT] = i; | 209 core_channel_orderings_[SIDE_LEFT] = i; |
209 channel_remap_[i] = kChannelOrderings[source_layout_][SIDE_LEFT]; | 210 channel_remap_[i] = ChannelOrder(source_layout_, SIDE_LEFT); |
210 break; | 211 break; |
211 case kAudioChannelLabel_RightSurround: | 212 case kAudioChannelLabel_RightSurround: |
212 core_channel_orderings_[SIDE_RIGHT] = i; | 213 core_channel_orderings_[SIDE_RIGHT] = i; |
213 channel_remap_[i] = kChannelOrderings[source_layout_][SIDE_RIGHT]; | 214 channel_remap_[i] = ChannelOrder(source_layout_, SIDE_RIGHT); |
214 break; | 215 break; |
215 case kAudioChannelLabel_LeftCenter: | 216 case kAudioChannelLabel_LeftCenter: |
216 core_channel_orderings_[LEFT_OF_CENTER] = i; | 217 core_channel_orderings_[LEFT_OF_CENTER] = i; |
217 channel_remap_[i] = kChannelOrderings[source_layout_][LEFT_OF_CENTER]; | 218 channel_remap_[i] = ChannelOrder(source_layout_, LEFT_OF_CENTER); |
218 break; | 219 break; |
219 case kAudioChannelLabel_RightCenter: | 220 case kAudioChannelLabel_RightCenter: |
220 core_channel_orderings_[RIGHT_OF_CENTER] = i; | 221 core_channel_orderings_[RIGHT_OF_CENTER] = i; |
221 channel_remap_[i] = kChannelOrderings[source_layout_][RIGHT_OF_CENTER]; | 222 channel_remap_[i] = ChannelOrder(source_layout_, RIGHT_OF_CENTER); |
222 break; | 223 break; |
223 case kAudioChannelLabel_CenterSurround: | 224 case kAudioChannelLabel_CenterSurround: |
224 core_channel_orderings_[BACK_CENTER] = i; | 225 core_channel_orderings_[BACK_CENTER] = i; |
225 channel_remap_[i] = kChannelOrderings[source_layout_][BACK_CENTER]; | 226 channel_remap_[i] = ChannelOrder(source_layout_, BACK_CENTER); |
226 break; | 227 break; |
227 case kAudioChannelLabel_RearSurroundLeft: | 228 case kAudioChannelLabel_RearSurroundLeft: |
228 core_channel_orderings_[BACK_LEFT] = i; | 229 core_channel_orderings_[BACK_LEFT] = i; |
229 channel_remap_[i] = kChannelOrderings[source_layout_][BACK_LEFT]; | 230 channel_remap_[i] = ChannelOrder(source_layout_, BACK_LEFT); |
230 break; | 231 break; |
231 case kAudioChannelLabel_RearSurroundRight: | 232 case kAudioChannelLabel_RearSurroundRight: |
232 core_channel_orderings_[BACK_RIGHT] = i; | 233 core_channel_orderings_[BACK_RIGHT] = i; |
233 channel_remap_[i] = kChannelOrderings[source_layout_][BACK_RIGHT]; | 234 channel_remap_[i] = ChannelOrder(source_layout_, BACK_RIGHT); |
234 break; | 235 break; |
235 default: | 236 default: |
236 DLOG(WARNING) << "Channel label not supported"; | 237 DLOG(WARNING) << "Channel label not supported"; |
237 channel_remap_[i] = kEmptyChannel; | 238 channel_remap_[i] = kEmptyChannel; |
238 break; | 239 break; |
239 } | 240 } |
240 } | 241 } |
241 | 242 |
242 if (all_channels_unknown) { | 243 if (all_channels_unknown) { |
243 return true; | 244 return true; |
(...skipping 21 matching lines...) Expand all Loading... |
265 CheckForAdjustedLayout(LEFT_OF_CENTER, SIDE_LEFT); | 266 CheckForAdjustedLayout(LEFT_OF_CENTER, SIDE_LEFT); |
266 // Same for RIGHT_OF_CENTER -> SIDE_RIGHT. | 267 // Same for RIGHT_OF_CENTER -> SIDE_RIGHT. |
267 CheckForAdjustedLayout(RIGHT_OF_CENTER, SIDE_RIGHT); | 268 CheckForAdjustedLayout(RIGHT_OF_CENTER, SIDE_RIGHT); |
268 // For MONO -> STEREO, move audio to LEFT and RIGHT if applicable. | 269 // For MONO -> STEREO, move audio to LEFT and RIGHT if applicable. |
269 CheckForAdjustedLayout(CENTER, LEFT); | 270 CheckForAdjustedLayout(CENTER, LEFT); |
270 CheckForAdjustedLayout(CENTER, RIGHT); | 271 CheckForAdjustedLayout(CENTER, RIGHT); |
271 | 272 |
272 // Check if we will need to swizzle from source to device layout (maybe not!). | 273 // Check if we will need to swizzle from source to device layout (maybe not!). |
273 should_swizzle_ = false; | 274 should_swizzle_ = false; |
274 for (int i = 0; i < num_core_channels_; ++i) { | 275 for (int i = 0; i < num_core_channels_; ++i) { |
275 if (kChannelOrderings[source_layout_][i] != core_channel_orderings_[i]) { | 276 if (ChannelOrder(source_layout_, static_cast<Channels>(i)) != |
| 277 core_channel_orderings_[i]) { |
276 should_swizzle_ = true; | 278 should_swizzle_ = true; |
277 break; | 279 break; |
278 } | 280 } |
279 } | 281 } |
280 | 282 |
281 return true; | 283 return true; |
282 } | 284 } |
283 | 285 |
284 void PCMQueueOutAudioOutputStream::Close() { | 286 void PCMQueueOutAudioOutputStream::Close() { |
285 // It is valid to call Close() before calling Open(), thus audio_queue_ | 287 // It is valid to call Close() before calling Open(), thus audio_queue_ |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 } | 354 } |
353 } | 355 } |
354 } | 356 } |
355 } | 357 } |
356 | 358 |
357 bool PCMQueueOutAudioOutputStream::CheckForAdjustedLayout( | 359 bool PCMQueueOutAudioOutputStream::CheckForAdjustedLayout( |
358 Channels input_channel, | 360 Channels input_channel, |
359 Channels output_channel) { | 361 Channels output_channel) { |
360 if (core_channel_orderings_[output_channel] > kEmptyChannel && | 362 if (core_channel_orderings_[output_channel] > kEmptyChannel && |
361 core_channel_orderings_[input_channel] == kEmptyChannel && | 363 core_channel_orderings_[input_channel] == kEmptyChannel && |
362 kChannelOrderings[source_layout_][input_channel] > kEmptyChannel && | 364 ChannelOrder(source_layout_, input_channel) > kEmptyChannel && |
363 kChannelOrderings[source_layout_][output_channel] == kEmptyChannel) { | 365 ChannelOrder(source_layout_, output_channel) == kEmptyChannel) { |
364 channel_remap_[core_channel_orderings_[output_channel]] = | 366 channel_remap_[core_channel_orderings_[output_channel]] = |
365 kChannelOrderings[source_layout_][input_channel]; | 367 ChannelOrder(source_layout_, input_channel); |
366 return true; | 368 return true; |
367 } | 369 } |
368 return false; | 370 return false; |
369 } | 371 } |
370 | 372 |
371 // Note to future hackers of this function: Do not add locks to this function | 373 // Note to future hackers of this function: Do not add locks to this function |
372 // that are held through any calls made back into AudioQueue APIs, or other | 374 // that are held through any calls made back into AudioQueue APIs, or other |
373 // OS audio functions. This is because the OS dispatch may grab external | 375 // OS audio functions. This is because the OS dispatch may grab external |
374 // locks, or possibly re-enter this function which can lead to a deadlock. | 376 // locks, or possibly re-enter this function which can lead to a deadlock. |
375 void PCMQueueOutAudioOutputStream::RenderCallback(void* p_this, | 377 void PCMQueueOutAudioOutputStream::RenderCallback(void* p_this, |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 source_ = source; | 543 source_ = source; |
542 } | 544 } |
543 | 545 |
544 AudioOutputStream::AudioSourceCallback* | 546 AudioOutputStream::AudioSourceCallback* |
545 PCMQueueOutAudioOutputStream::GetSource() { | 547 PCMQueueOutAudioOutputStream::GetSource() { |
546 base::AutoLock lock(source_lock_); | 548 base::AutoLock lock(source_lock_); |
547 return source_; | 549 return source_; |
548 } | 550 } |
549 | 551 |
550 } // namespace media | 552 } // namespace media |
OLD | NEW |