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

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

Issue 9235084: Add OSSTATUS_LOG API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 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/logging.h" 10 #include "base/logging.h"
11 #include "base/mac/mac_logging.h"
11 #include "media/audio/audio_util.h" 12 #include "media/audio/audio_util.h"
12 #include "media/audio/mac/audio_manager_mac.h" 13 #include "media/audio/mac/audio_manager_mac.h"
13 14
14 // Reorder PCM from AAC layout to Core Audio 5.1 layout. 15 // Reorder PCM from AAC layout to Core Audio 5.1 layout.
15 // TODO(fbarchard): Switch layout when ffmpeg is updated. 16 // TODO(fbarchard): Switch layout when ffmpeg is updated.
16 template<class Format> 17 template<class Format>
17 static void SwizzleCoreAudioLayout5_1(Format* b, uint32 filled) { 18 static void SwizzleCoreAudioLayout5_1(Format* b, uint32 filled) {
18 static const int kNumSurroundChannels = 6; 19 static const int kNumSurroundChannels = 6;
19 Format aac[kNumSurroundChannels]; 20 Format aac[kNumSurroundChannels];
20 for (uint32 i = 0; i < filled; i += sizeof(aac), b += kNumSurroundChannels) { 21 for (uint32 i = 0; i < filled; i += sizeof(aac), b += kNumSurroundChannels) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 kAudioHardwarePropertyDefaultOutputDevice, 81 kAudioHardwarePropertyDefaultOutputDevice,
81 kAudioObjectPropertyScopeGlobal, 82 kAudioObjectPropertyScopeGlobal,
82 kAudioObjectPropertyElementMaster 83 kAudioObjectPropertyElementMaster
83 }; 84 };
84 OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, 85 OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
85 &default_output_device_address, 86 &default_output_device_address,
86 0, 87 0,
87 0, 88 0,
88 &size, 89 &size,
89 &output_device_id_); 90 &output_device_id_);
90 DCHECK_EQ(result, 0); 91 OSSTATUS_DCHECK(result == noErr, result);
91 if (result) 92 if (result)
92 return false; 93 return false;
93 94
94 // Open and initialize the DefaultOutputUnit. 95 // Open and initialize the DefaultOutputUnit.
95 Component comp; 96 Component comp;
96 ComponentDescription desc; 97 ComponentDescription desc;
97 98
98 desc.componentType = kAudioUnitType_Output; 99 desc.componentType = kAudioUnitType_Output;
99 desc.componentSubType = kAudioUnitSubType_DefaultOutput; 100 desc.componentSubType = kAudioUnitSubType_DefaultOutput;
100 desc.componentManufacturer = kAudioUnitManufacturer_Apple; 101 desc.componentManufacturer = kAudioUnitManufacturer_Apple;
101 desc.componentFlags = 0; 102 desc.componentFlags = 0;
102 desc.componentFlagsMask = 0; 103 desc.componentFlagsMask = 0;
103 comp = FindNextComponent(0, &desc); 104 comp = FindNextComponent(0, &desc);
104 DCHECK(comp); 105 DCHECK(comp);
105 106
106 result = OpenAComponent(comp, &output_unit_); 107 result = OpenAComponent(comp, &output_unit_);
107 DCHECK_EQ(result, 0); 108 OSSTATUS_DCHECK(result == noErr, result);
108 if (result) 109 if (result)
109 return false; 110 return false;
110 111
111 result = AudioUnitInitialize(output_unit_); 112 result = AudioUnitInitialize(output_unit_);
112 113 OSSTATUS_DCHECK(result == noErr, result);
113 DCHECK_EQ(result, 0);
114 if (result) 114 if (result)
115 return false; 115 return false;
116 116
117 hardware_latency_frames_ = GetHardwareLatency(); 117 hardware_latency_frames_ = GetHardwareLatency();
118 118
119 return Configure(); 119 return Configure();
120 } 120 }
121 121
122 bool AUAudioOutputStream::Configure() { 122 bool AUAudioOutputStream::Configure() {
123 // Set the render callback. 123 // Set the render callback.
124 AURenderCallbackStruct input; 124 AURenderCallbackStruct input;
125 input.inputProc = InputProc; 125 input.inputProc = InputProc;
126 input.inputProcRefCon = this; 126 input.inputProcRefCon = this;
127 OSStatus result = AudioUnitSetProperty( 127 OSStatus result = AudioUnitSetProperty(
128 output_unit_, 128 output_unit_,
129 kAudioUnitProperty_SetRenderCallback, 129 kAudioUnitProperty_SetRenderCallback,
130 kAudioUnitScope_Global, 130 kAudioUnitScope_Global,
131 0, 131 0,
132 &input, 132 &input,
133 sizeof(input)); 133 sizeof(input));
134 134 OSSTATUS_DCHECK(result == noErr, result);
135 DCHECK_EQ(result, 0);
136 if (result) 135 if (result)
137 return false; 136 return false;
138 137
139 // Set the stream format. 138 // Set the stream format.
140 result = AudioUnitSetProperty( 139 result = AudioUnitSetProperty(
141 output_unit_, 140 output_unit_,
142 kAudioUnitProperty_StreamFormat, 141 kAudioUnitProperty_StreamFormat,
143 kAudioUnitScope_Input, 142 kAudioUnitScope_Input,
144 0, 143 0,
145 &format_, 144 &format_,
146 sizeof(format_)); 145 sizeof(format_));
147 DCHECK_EQ(result, 0); 146 OSSTATUS_DCHECK(result == noErr, result);
148 if (result) 147 if (result)
149 return false; 148 return false;
150 149
151 // Set the buffer frame size. 150 // Set the buffer frame size.
152 UInt32 buffer_size = number_of_frames_; 151 UInt32 buffer_size = number_of_frames_;
153 result = AudioUnitSetProperty( 152 result = AudioUnitSetProperty(
154 output_unit_, 153 output_unit_,
155 kAudioDevicePropertyBufferFrameSize, 154 kAudioDevicePropertyBufferFrameSize,
156 kAudioUnitScope_Output, 155 kAudioUnitScope_Output,
157 0, 156 0,
158 &buffer_size, 157 &buffer_size,
159 sizeof(buffer_size)); 158 sizeof(buffer_size));
160 DCHECK_EQ(result, 0); 159 OSSTATUS_DCHECK(result == noErr, result);
161 if (result) 160 if (result)
162 return false; 161 return false;
163 162
164 return true; 163 return true;
165 } 164 }
166 165
167 void AUAudioOutputStream::Close() { 166 void AUAudioOutputStream::Close() {
168 if (output_unit_) 167 if (output_unit_)
169 CloseComponent(output_unit_); 168 CloseComponent(output_unit_);
170 169
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 kAudioHardwarePropertyDefaultOutputDevice, 261 kAudioHardwarePropertyDefaultOutputDevice,
263 kAudioObjectPropertyScopeGlobal, 262 kAudioObjectPropertyScopeGlobal,
264 kAudioObjectPropertyElementMaster 263 kAudioObjectPropertyElementMaster
265 }; 264 };
266 OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, 265 OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
267 &default_output_device_address, 266 &default_output_device_address,
268 0, 267 0,
269 0, 268 0,
270 &info_size, 269 &info_size,
271 &device_id); 270 &device_id);
272 DCHECK_EQ(result, 0); 271 OSSTATUS_DCHECK(result == noErr, result);
273 if (result) 272 if (result)
274 return 0.0; // error 273 return 0.0; // error
275 274
276 Float64 nominal_sample_rate; 275 Float64 nominal_sample_rate;
277 info_size = sizeof(nominal_sample_rate); 276 info_size = sizeof(nominal_sample_rate);
278 277
279 AudioObjectPropertyAddress nominal_sample_rate_address = { 278 AudioObjectPropertyAddress nominal_sample_rate_address = {
280 kAudioDevicePropertyNominalSampleRate, 279 kAudioDevicePropertyNominalSampleRate,
281 kAudioObjectPropertyScopeGlobal, 280 kAudioObjectPropertyScopeGlobal,
282 kAudioObjectPropertyElementMaster 281 kAudioObjectPropertyElementMaster
283 }; 282 };
284 result = AudioObjectGetPropertyData(device_id, 283 result = AudioObjectGetPropertyData(device_id,
285 &nominal_sample_rate_address, 284 &nominal_sample_rate_address,
286 0, 285 0,
287 0, 286 0,
288 &info_size, 287 &info_size,
289 &nominal_sample_rate); 288 &nominal_sample_rate);
290 DCHECK_EQ(result, 0); 289 OSSTATUS_DCHECK(result == noErr, result);
291 if (result) 290 if (result)
292 return 0.0; // error 291 return 0.0; // error
293 292
294 return nominal_sample_rate; 293 return nominal_sample_rate;
295 } 294 }
296 295
297 double AUAudioOutputStream::GetHardwareLatency() { 296 double AUAudioOutputStream::GetHardwareLatency() {
298 if (!output_unit_ || output_device_id_ == kAudioObjectUnknown) { 297 if (!output_unit_ || output_device_id_ == kAudioObjectUnknown) {
299 DLOG(WARNING) << "Audio unit object is NULL or device ID is unknown"; 298 DLOG(WARNING) << "Audio unit object is NULL or device ID is unknown";
300 return 0.0; 299 return 0.0;
301 } 300 }
302 301
303 // Get audio unit latency. 302 // Get audio unit latency.
304 Float64 audio_unit_latency_sec = 0.0; 303 Float64 audio_unit_latency_sec = 0.0;
305 UInt32 size = sizeof(audio_unit_latency_sec); 304 UInt32 size = sizeof(audio_unit_latency_sec);
306 OSStatus result = AudioUnitGetProperty(output_unit_, 305 OSStatus result = AudioUnitGetProperty(output_unit_,
307 kAudioUnitProperty_Latency, 306 kAudioUnitProperty_Latency,
308 kAudioUnitScope_Global, 307 kAudioUnitScope_Global,
309 0, 308 0,
310 &audio_unit_latency_sec, 309 &audio_unit_latency_sec,
311 &size); 310 &size);
312 DLOG_IF(WARNING, result != noErr) << "Could not get audio unit latency."; 311 OSSTATUS_DLOG_IF(WARNING, result != noErr, result)
312 << "Could not get audio unit latency";
313 313
314 // Get output audio device latency. 314 // Get output audio device latency.
315 AudioObjectPropertyAddress property_address = { 315 AudioObjectPropertyAddress property_address = {
316 kAudioDevicePropertyLatency, 316 kAudioDevicePropertyLatency,
317 kAudioDevicePropertyScopeOutput, 317 kAudioDevicePropertyScopeOutput,
318 kAudioObjectPropertyElementMaster 318 kAudioObjectPropertyElementMaster
319 }; 319 };
320 UInt32 device_latency_frames = 0; 320 UInt32 device_latency_frames = 0;
321 size = sizeof(device_latency_frames); 321 size = sizeof(device_latency_frames);
322 result = AudioObjectGetPropertyData(output_device_id_, 322 result = AudioObjectGetPropertyData(output_device_id_,
323 &property_address, 323 &property_address,
324 0, 324 0,
325 NULL, 325 NULL,
326 &size, 326 &size,
327 &device_latency_frames); 327 &device_latency_frames);
328 DLOG_IF(WARNING, result != noErr) << "Could not get audio device latency."; 328 OSSTATUS_DLOG_IF(WARNING, result != noErr, result)
329 << "Could not get audio device latency";
329 330
330 // Get the stream latency. 331 // Get the stream latency.
331 property_address.mSelector = kAudioDevicePropertyStreams; 332 property_address.mSelector = kAudioDevicePropertyStreams;
332 UInt32 stream_latency_frames = 0; 333 UInt32 stream_latency_frames = 0;
333 result = AudioObjectGetPropertyDataSize(output_device_id_, 334 result = AudioObjectGetPropertyDataSize(output_device_id_,
334 &property_address, 335 &property_address,
335 0, 336 0,
336 NULL, 337 NULL,
337 &size); 338 &size);
338 if (!result) { 339 if (!result) {
339 scoped_ptr_malloc<AudioStreamID> 340 scoped_ptr_malloc<AudioStreamID>
340 streams(reinterpret_cast<AudioStreamID*>(malloc(size))); 341 streams(reinterpret_cast<AudioStreamID*>(malloc(size)));
341 AudioStreamID* stream_ids = streams.get(); 342 AudioStreamID* stream_ids = streams.get();
342 result = AudioObjectGetPropertyData(output_device_id_, 343 result = AudioObjectGetPropertyData(output_device_id_,
343 &property_address, 344 &property_address,
344 0, 345 0,
345 NULL, 346 NULL,
346 &size, 347 &size,
347 stream_ids); 348 stream_ids);
348 if (!result) { 349 if (!result) {
349 property_address.mSelector = kAudioStreamPropertyLatency; 350 property_address.mSelector = kAudioStreamPropertyLatency;
350 result = AudioObjectGetPropertyData(stream_ids[0], 351 result = AudioObjectGetPropertyData(stream_ids[0],
351 &property_address, 352 &property_address,
352 0, 353 0,
353 NULL, 354 NULL,
354 &size, 355 &size,
355 &stream_latency_frames); 356 &stream_latency_frames);
356 } 357 }
357 } 358 }
358 DLOG_IF(WARNING, result != noErr) << "Could not get audio stream latency."; 359 OSSTATUS_DLOG_IF(WARNING, result != noErr, result)
360 << "Could not get audio stream latency";
359 361
360 return static_cast<double>((audio_unit_latency_sec * 362 return static_cast<double>((audio_unit_latency_sec *
361 format_.mSampleRate) + device_latency_frames + stream_latency_frames); 363 format_.mSampleRate) + device_latency_frames + stream_latency_frames);
362 } 364 }
363 365
364 double AUAudioOutputStream::GetPlayoutLatency( 366 double AUAudioOutputStream::GetPlayoutLatency(
365 const AudioTimeStamp* output_time_stamp) { 367 const AudioTimeStamp* output_time_stamp) {
366 // Get the delay between the moment getting the callback and the scheduled 368 // Get the delay between the moment getting the callback and the scheduled
367 // time stamp that tells when the data is going to be played out. 369 // time stamp that tells when the data is going to be played out.
368 UInt64 output_time_ns = AudioConvertHostTimeToNanos( 370 UInt64 output_time_ns = AudioConvertHostTimeToNanos(
369 output_time_stamp->mHostTime); 371 output_time_stamp->mHostTime);
370 UInt64 now_ns = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); 372 UInt64 now_ns = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
371 double delay_frames = static_cast<double> 373 double delay_frames = static_cast<double>
372 (1e-9 * (output_time_ns - now_ns) * format_.mSampleRate); 374 (1e-9 * (output_time_ns - now_ns) * format_.mSampleRate);
373 375
374 return (delay_frames + hardware_latency_frames_); 376 return (delay_frames + hardware_latency_frames_);
375 } 377 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698