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

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

Issue 1903753002: Restores larger output buffer size when output stream requiring smaller size is closed (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: One more round based on feedback from olka@ Created 4 years, 8 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
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 "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 26 matching lines...) Expand all
37 bus->set_frames(frames); 37 bus->set_frames(frames);
38 } 38 }
39 39
40 AUHALStream::AUHALStream(AudioManagerMac* manager, 40 AUHALStream::AUHALStream(AudioManagerMac* manager,
41 const AudioParameters& params, 41 const AudioParameters& params,
42 AudioDeviceID device) 42 AudioDeviceID device)
43 : manager_(manager), 43 : manager_(manager),
44 params_(params), 44 params_(params),
45 output_channels_(params_.channels()), 45 output_channels_(params_.channels()),
46 number_of_frames_(params_.frames_per_buffer()), 46 number_of_frames_(params_.frames_per_buffer()),
47 actual_io_buffer_frame_size_(0),
47 number_of_frames_requested_(0), 48 number_of_frames_requested_(0),
48 source_(NULL), 49 source_(NULL),
49 device_(device), 50 device_(device),
50 audio_unit_(0), 51 audio_unit_(0),
51 volume_(1), 52 volume_(1),
52 hardware_latency_frames_(0), 53 hardware_latency_frames_(0),
53 stopped_(true), 54 stopped_(true),
54 current_hardware_pending_bytes_(0), 55 current_hardware_pending_bytes_(0),
55 current_lost_frames_(0), 56 current_lost_frames_(0),
56 last_sample_time_(0.0), 57 last_sample_time_(0.0),
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 109
109 // The output bus will wrap the AudioBufferList given to us in 110 // The output bus will wrap the AudioBufferList given to us in
110 // the Render() callback. 111 // the Render() callback.
111 DCHECK_GT(output_channels_, 0); 112 DCHECK_GT(output_channels_, 0);
112 output_bus_ = AudioBus::CreateWrapper(output_channels_); 113 output_bus_ = AudioBus::CreateWrapper(output_channels_);
113 114
114 bool configured = ConfigureAUHAL(); 115 bool configured = ConfigureAUHAL();
115 if (configured) 116 if (configured)
116 hardware_latency_frames_ = GetHardwareLatency(); 117 hardware_latency_frames_ = GetHardwareLatency();
117 118
119 #if !defined(NDEBUG)
120 // Print a list of all existing output streams and there current buffer size
121 // state (required and actual). Does nothing in Release builds.
122 manager_->PrintOutputBufferSizes();
123 #endif
124
118 return configured; 125 return configured;
119 } 126 }
120 127
121 void AUHALStream::Close() { 128 void AUHALStream::Close() {
122 DCHECK(thread_checker_.CalledOnValidThread()); 129 DCHECK(thread_checker_.CalledOnValidThread());
123 DVLOG(1) << "Close"; 130 DVLOG(1) << "Close";
124 CloseAudioUnit(); 131 CloseAudioUnit();
125 // Inform the audio manager that we have been closed. This will cause our 132 // Inform the audio manager that we have been closed. This will cause our
126 // destruction. 133 // destruction.
127 manager_->ReleaseOutputStream(this); 134 manager_->ReleaseOutputStream(this);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 OSSTATUS_DLOG(ERROR, result) << "AudioOutputUnitStart() failed."; 175 OSSTATUS_DLOG(ERROR, result) << "AudioOutputUnitStart() failed.";
169 callback->OnError(this); 176 callback->OnError(this);
170 } 177 }
171 178
172 void AUHALStream::Stop() { 179 void AUHALStream::Stop() {
173 DCHECK(thread_checker_.CalledOnValidThread()); 180 DCHECK(thread_checker_.CalledOnValidThread());
174 deferred_start_cb_.Cancel(); 181 deferred_start_cb_.Cancel();
175 if (stopped_) 182 if (stopped_)
176 return; 183 return;
177 DVLOG(1) << "Stop"; 184 DVLOG(1) << "Stop";
185 DVLOG(2) << "number_of_frames: " << number_of_frames_;
178 OSStatus result = AudioOutputUnitStop(audio_unit_); 186 OSStatus result = AudioOutputUnitStop(audio_unit_);
179 OSSTATUS_DLOG_IF(ERROR, result != noErr, result) 187 OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
180 << "AudioOutputUnitStop() failed."; 188 << "AudioOutputUnitStop() failed.";
181 if (result != noErr) 189 if (result != noErr)
182 source_->OnError(this); 190 source_->OnError(this);
183 ReportAndResetStats(); 191 ReportAndResetStats();
184 base::AutoLock auto_lock(source_lock_); 192 base::AutoLock auto_lock(source_lock_);
185 source_ = NULL; 193 source_ = NULL;
186 stopped_ = true; 194 stopped_ = true;
187 } 195 }
(...skipping 22 matching lines...) Expand all
210 218
211 // If the stream parameters change for any reason, we need to insert a FIFO 219 // If the stream parameters change for any reason, we need to insert a FIFO
212 // since the OnMoreData() pipeline can't handle frame size changes. 220 // since the OnMoreData() pipeline can't handle frame size changes.
213 if (number_of_frames != number_of_frames_) { 221 if (number_of_frames != number_of_frames_) {
214 // Create a FIFO on the fly to handle any discrepancies in callback rates. 222 // Create a FIFO on the fly to handle any discrepancies in callback rates.
215 if (!audio_fifo_) { 223 if (!audio_fifo_) {
216 // TODO(grunell): We'll only care about the first buffer size change, 224 // TODO(grunell): We'll only care about the first buffer size change,
217 // any further changes will be ignored. It would be nice to have all 225 // any further changes will be ignored. It would be nice to have all
218 // changes reflected in UMA stats. 226 // changes reflected in UMA stats.
219 number_of_frames_requested_ = number_of_frames; 227 number_of_frames_requested_ = number_of_frames;
228 actual_io_buffer_frame_size_ = number_of_frames;
Henrik Grunell 2016/04/27 08:59:28 Is the intention that only the first time the requ
henrika (OOO until Aug 14) 2016/04/27 12:12:30 Good point. I can move it up one scope instead. Th
220 DVLOG(1) << "Audio frame size changed from " << number_of_frames_ 229 DVLOG(1) << "Audio frame size changed from " << number_of_frames_
221 << " to " << number_of_frames 230 << " to " << number_of_frames << " adding FIFO to compensate.";
222 << "; adding FIFO to compensate.";
223 audio_fifo_.reset(new AudioPullFifo( 231 audio_fifo_.reset(new AudioPullFifo(
224 output_channels_, 232 output_channels_,
225 number_of_frames_, 233 number_of_frames_,
226 base::Bind(&AUHALStream::ProvideInput, base::Unretained(this)))); 234 base::Bind(&AUHALStream::ProvideInput, base::Unretained(this))));
235 #if !defined(NDEBUG)
236 manager_->PrintOutputBufferSizes();
237 #endif
227 } 238 }
228 } 239 }
229 240
230 // Make |output_bus_| wrap the output AudioBufferList. 241 // Make |output_bus_| wrap the output AudioBufferList.
231 WrapBufferList(data, output_bus_.get(), number_of_frames); 242 WrapBufferList(data, output_bus_.get(), number_of_frames);
232 243
233 // Update the playout latency. 244 // Update the playout latency.
234 const double playout_latency_frames = GetPlayoutLatency(output_time_stamp); 245 const double playout_latency_frames = GetPlayoutLatency(output_time_stamp);
235 current_hardware_pending_bytes_ = static_cast<uint32_t>( 246 current_hardware_pending_bytes_ = static_cast<uint32_t>(
236 (playout_latency_frames + 0.5) * params_.GetBytesPerFrame()); 247 (playout_latency_frames + 0.5) * params_.GetBytesPerFrame());
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 516
506 bool size_was_changed = false; 517 bool size_was_changed = false;
507 size_t io_buffer_frame_size = 0; 518 size_t io_buffer_frame_size = 0;
508 if (!manager_->MaybeChangeBufferSize(device_, audio_unit_, 0, 519 if (!manager_->MaybeChangeBufferSize(device_, audio_unit_, 0,
509 number_of_frames_, &size_was_changed, 520 number_of_frames_, &size_was_changed,
510 &io_buffer_frame_size)) { 521 &io_buffer_frame_size)) {
511 CloseAudioUnit(); 522 CloseAudioUnit();
512 return false; 523 return false;
513 } 524 }
514 525
526 // Get the actual number of frames in the IO buffers after the audio manager
527 // has tried to set the requested size. We could use |io_buffer_frame_size|
528 // here instead of doing these extra steps but I prefer to play it safe and
529 // to ensure that the change done by the audio manager is really active.
530 // TODO(henrika): it might be possible to remove this part.
531 UInt32 actual_io_buffer_frame_size;
532 UInt32 property_size = sizeof(actual_io_buffer_frame_size);
533 result = AudioUnitGetProperty(
534 audio_unit_, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global,
535 0, &actual_io_buffer_frame_size, &property_size);
536 LOG_IF(WARNING, result != noErr)
537 << "Failed to get the actual I/O buffer size";
538 if (result == noErr) {
539 actual_io_buffer_frame_size_ = actual_io_buffer_frame_size;
540 DVLOG(1) << "actual_io_buffer_frame_size: " << actual_io_buffer_frame_size_;
541 }
542 LOG_IF(WARNING, actual_io_buffer_frame_size_ != number_of_frames_)
543 << "Failed to set the requested buffer frame size exactly";
544 DCHECK_EQ(io_buffer_frame_size, actual_io_buffer_frame_size);
545
515 // Setup callback. 546 // Setup callback.
516 AURenderCallbackStruct callback; 547 AURenderCallbackStruct callback;
517 callback.inputProc = InputProc; 548 callback.inputProc = InputProc;
518 callback.inputProcRefCon = this; 549 callback.inputProcRefCon = this;
519 result = AudioUnitSetProperty( 550 result = AudioUnitSetProperty(
520 audio_unit_, 551 audio_unit_,
521 kAudioUnitProperty_SetRenderCallback, 552 kAudioUnitProperty_SetRenderCallback,
522 kAudioUnitScope_Input, 553 kAudioUnitScope_Input,
523 0, 554 0,
524 &callback, 555 &callback,
(...skipping 21 matching lines...) Expand all
546 OSStatus result = AudioUnitUninitialize(audio_unit_); 577 OSStatus result = AudioUnitUninitialize(audio_unit_);
547 OSSTATUS_DLOG_IF(ERROR, result != noErr, result) 578 OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
548 << "AudioUnitUninitialize() failed."; 579 << "AudioUnitUninitialize() failed.";
549 result = AudioComponentInstanceDispose(audio_unit_); 580 result = AudioComponentInstanceDispose(audio_unit_);
550 OSSTATUS_DLOG_IF(ERROR, result != noErr, result) 581 OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
551 << "AudioComponentInstanceDispose() failed."; 582 << "AudioComponentInstanceDispose() failed.";
552 audio_unit_ = 0; 583 audio_unit_ = 0;
553 } 584 }
554 585
555 } // namespace media 586 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698