Chromium Code Reviews| 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_low_latency_output_mac.h" | 5 #include "media/audio/mac/audio_low_latency_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/command_line.h" | |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/mac/mac_logging.h" | 12 #include "base/mac/mac_logging.h" |
| 12 #include "media/audio/audio_util.h" | 13 #include "media/audio/audio_util.h" |
| 13 #include "media/audio/mac/audio_manager_mac.h" | 14 #include "media/audio/mac/audio_manager_mac.h" |
| 15 #include "media/base/media_switches.h" | |
| 14 | 16 |
| 15 namespace media { | 17 namespace media { |
| 16 | 18 |
| 17 // Reorder PCM from AAC layout to Core Audio 5.1 layout. | 19 // Reorder PCM from AAC layout to Core Audio 5.1 layout. |
| 18 // TODO(fbarchard): Switch layout when ffmpeg is updated. | 20 // TODO(fbarchard): Switch layout when ffmpeg is updated. |
| 19 template<class Format> | 21 template<class Format> |
| 20 static void SwizzleCoreAudioLayout5_1(Format* b, uint32 filled) { | 22 static void SwizzleCoreAudioLayout5_1(Format* b, uint32 filled) { |
| 21 static const int kNumSurroundChannels = 6; | 23 static const int kNumSurroundChannels = 6; |
| 22 Format aac[kNumSurroundChannels]; | 24 Format aac[kNumSurroundChannels]; |
| 23 for (uint32 i = 0; i < filled; i += sizeof(aac), b += kNumSurroundChannels) { | 25 for (uint32 i = 0; i < filled; i += sizeof(aac), b += kNumSurroundChannels) { |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 213 return; | 215 return; |
| 214 *volume = volume_; | 216 *volume = volume_; |
| 215 } | 217 } |
| 216 | 218 |
| 217 // Pulls on our provider to get rendered audio stream. | 219 // Pulls on our provider to get rendered audio stream. |
| 218 // Note to future hackers of this function: Do not add locks here because this | 220 // Note to future hackers of this function: Do not add locks here because this |
| 219 // is running on a real-time thread (for low-latency). | 221 // is running on a real-time thread (for low-latency). |
| 220 OSStatus AUAudioOutputStream::Render(UInt32 number_of_frames, | 222 OSStatus AUAudioOutputStream::Render(UInt32 number_of_frames, |
| 221 AudioBufferList* io_data, | 223 AudioBufferList* io_data, |
| 222 const AudioTimeStamp* output_time_stamp) { | 224 const AudioTimeStamp* output_time_stamp) { |
| 225 static const bool kDisableAudioOutputResampler = | |
| 226 CommandLine::ForCurrentProcess()->HasSwitch( | |
| 227 switches::kDisableAudioOutputResampler); | |
| 228 | |
| 223 // Update the playout latency. | 229 // Update the playout latency. |
| 224 double playout_latency_frames = GetPlayoutLatency(output_time_stamp); | 230 double playout_latency_frames = GetPlayoutLatency(output_time_stamp); |
| 225 | 231 |
| 226 AudioBuffer& buffer = io_data->mBuffers[0]; | 232 AudioBuffer& buffer = io_data->mBuffers[0]; |
| 227 uint8* audio_data = reinterpret_cast<uint8*>(buffer.mData); | 233 uint8* audio_data = reinterpret_cast<uint8*>(buffer.mData); |
| 228 uint32 hardware_pending_bytes = static_cast<uint32> | 234 uint32 hardware_pending_bytes = static_cast<uint32> |
| 229 ((playout_latency_frames + 0.5) * format_.mBytesPerFrame); | 235 ((playout_latency_frames + 0.5) * format_.mBytesPerFrame); |
| 230 | 236 |
| 231 DCHECK_EQ(number_of_frames, static_cast<UInt32>(audio_bus_->frames())); | 237 // If we specify a buffer size which is too low, the OS will ask for more data |
| 232 int frames_filled = source_->OnMoreData( | 238 // to fulfill the hardware request, so resize the AudioBus as appropriate. |
| 233 audio_bus_.get(), AudioBuffersState(0, hardware_pending_bytes)); | 239 // This change requires AudioOutputResampler to prevent buffer size mismatches |
| 240 // downstream, so glitch if it's not enabled. | |
| 241 if (!kDisableAudioOutputResampler && | |
| 242 static_cast<UInt32>(audio_bus_->frames()) != number_of_frames) { | |
| 243 audio_bus_ = AudioBus::Create(audio_bus_->channels(), number_of_frames); | |
| 244 } | |
|
Chris Rogers
2012/09/14 17:28:45
I'm not crazy about this change long-term, and I'd
| |
| 245 | |
| 246 int frames_filled = std::min(source_->OnMoreData( | |
| 247 audio_bus_.get(), AudioBuffersState(0, hardware_pending_bytes)), | |
| 248 static_cast<int>(number_of_frames)); | |
| 234 // Note: If this ever changes to output raw float the data must be clipped and | 249 // Note: If this ever changes to output raw float the data must be clipped and |
| 235 // sanitized since it may come from an untrusted source such as NaCl. | 250 // sanitized since it may come from an untrusted source such as NaCl. |
| 236 audio_bus_->ToInterleaved( | 251 audio_bus_->ToInterleaved( |
| 237 frames_filled, format_.mBitsPerChannel / 8, audio_data); | 252 frames_filled, format_.mBitsPerChannel / 8, audio_data); |
| 238 uint32 filled = frames_filled * format_.mBytesPerFrame; | 253 uint32 filled = frames_filled * format_.mBytesPerFrame; |
| 239 | 254 |
| 240 // Handle channel order for 5.1 audio. | 255 // Handle channel order for 5.1 audio. |
| 241 // TODO(dalecurtis): Channel downmixing, upmixing, should be done in mixer; | 256 // TODO(dalecurtis): Channel downmixing, upmixing, should be done in mixer; |
| 242 // volume adjust should use SSE optimized vector_fmul() prior to interleave. | 257 // volume adjust should use SSE optimized vector_fmul() prior to interleave. |
| 243 if (format_.mChannelsPerFrame == 6) { | 258 if (format_.mChannelsPerFrame == 6) { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 UInt64 output_time_ns = AudioConvertHostTimeToNanos( | 371 UInt64 output_time_ns = AudioConvertHostTimeToNanos( |
| 357 output_time_stamp->mHostTime); | 372 output_time_stamp->mHostTime); |
| 358 UInt64 now_ns = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); | 373 UInt64 now_ns = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); |
| 359 double delay_frames = static_cast<double> | 374 double delay_frames = static_cast<double> |
| 360 (1e-9 * (output_time_ns - now_ns) * format_.mSampleRate); | 375 (1e-9 * (output_time_ns - now_ns) * format_.mSampleRate); |
| 361 | 376 |
| 362 return (delay_frames + hardware_latency_frames_); | 377 return (delay_frames + hardware_latency_frames_); |
| 363 } | 378 } |
| 364 | 379 |
| 365 } // namespace media | 380 } // namespace media |
| OLD | NEW |