From a3b6d648f9d318e18df83795bac9418e11d1f50b Mon Sep 17 00:00:00 2001 From: "dalecurtis@chromium.org" Date: Tue, 9 Oct 2012 01:12:04 +0000 Subject: Prevent AudioLowLatencyInputMac from changing frame sizes. Otherwise we'll hit a CHECK() later since the shared memory isn't configured for the new frame size. BUG=154352 TEST=mac build no longer crashes. Review URL: https://chromiumcodereview.appspot.com/11086009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@160759 0039d316-1c4b-4281-b951-d872f2087c98 --- media/audio/mac/audio_low_latency_input_mac.cc | 17 +++++++++++++ media/audio/mac/audio_low_latency_output_mac.cc | 34 +++++++++++++++---------- 2 files changed, 37 insertions(+), 14 deletions(-) (limited to 'media/audio') diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc index dc9bd8a..276f3e7 100644 --- a/media/audio/mac/audio_low_latency_input_mac.cc +++ b/media/audio/mac/audio_low_latency_input_mac.cc @@ -195,6 +195,11 @@ bool AUAudioInputStream::Open() { } // Set the desired number of frames in the IO buffer (output scope). + // WARNING: Setting this value changes the frame size for all audio units in + // the current process. It's imperative that the input and output frame sizes + // be the same as audio_util::GetAudioHardwareBufferSize(). + // TODO(henrika): Due to http://crrev.com/159666 this is currently not true + // and should be fixed, a CHECK() should be added at that time. result = AudioUnitSetProperty(audio_unit_, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Output, @@ -460,6 +465,18 @@ OSStatus AUAudioInputStream::Provide(UInt32 number_of_frames, if (!audio_data) return kAudioUnitErr_InvalidElement; + // Unfortunately AUAudioInputStream and AUAudioOutputStream share the frame + // size set by kAudioDevicePropertyBufferFrameSize above on a per process + // basis. What this means is that the |number_of_frames| value may be larger + // or smaller than the value set during Configure(). In this case either + // audio input or audio output will be broken, so just do nothing. + // TODO(henrika): This should never happen so long as we're always using the + // hardware sample rate and the input/output streams configure the same frame + // size. This is currently not true. See http://crbug.com/154352. Once + // fixed, a CHECK() should be added and this wall of text removed. + if (number_of_frames != static_cast(number_of_frames_)) + return noErr; + // Deliver data packet, delay estimation and volume level to the user. sink_->OnData(this, audio_data, diff --git a/media/audio/mac/audio_low_latency_output_mac.cc b/media/audio/mac/audio_low_latency_output_mac.cc index 0327db0..ea0d04d 100644 --- a/media/audio/mac/audio_low_latency_output_mac.cc +++ b/media/audio/mac/audio_low_latency_output_mac.cc @@ -154,6 +154,11 @@ bool AUAudioOutputStream::Configure() { return false; // Set the buffer frame size. + // WARNING: Setting this value changes the frame size for all audio units in + // the current process. It's imperative that the input and output frame sizes + // be the same as audio_util::GetAudioHardwareBufferSize(). + // TODO(henrika): Due to http://crrev.com/159666 this is currently not true + // and should be fixed, a CHECK() should be added at that time. UInt32 buffer_size = number_of_frames_; result = AudioUnitSetProperty( output_unit_, @@ -222,10 +227,6 @@ void AUAudioOutputStream::GetVolume(double* volume) { OSStatus AUAudioOutputStream::Render(UInt32 number_of_frames, AudioBufferList* io_data, const AudioTimeStamp* output_time_stamp) { - static const bool kDisableAudioOutputResampler = - CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableAudioOutputResampler); - // Update the playout latency. double playout_latency_frames = GetPlayoutLatency(output_time_stamp); @@ -234,18 +235,23 @@ OSStatus AUAudioOutputStream::Render(UInt32 number_of_frames, uint32 hardware_pending_bytes = static_cast ((playout_latency_frames + 0.5) * format_.mBytesPerFrame); - // If we specify a buffer size which is too low, the OS will ask for more data - // to fulfill the hardware request, so resize the AudioBus as appropriate. - // This change requires AudioOutputResampler to prevent buffer size mismatches - // downstream, so glitch if it's not enabled. - if (!kDisableAudioOutputResampler && - static_cast(audio_bus_->frames()) != number_of_frames) { - audio_bus_ = AudioBus::Create(audio_bus_->channels(), number_of_frames); + // Unfortunately AUAudioInputStream and AUAudioOutputStream share the frame + // size set by kAudioDevicePropertyBufferFrameSize above on a per process + // basis. What this means is that the |number_of_frames| value may be larger + // or smaller than the value set during Configure(). In this case either + // audio input or audio output will be broken, so just output silence. + // TODO(henrika): This should never happen so long as we're always using the + // hardware sample rate and the input/output streams configure the same frame + // size. This is currently not true. See http://crbug.com/154352. Once + // fixed, a CHECK() should be added and this wall of text removed. + if (number_of_frames != static_cast(audio_bus_->frames())) { + memset(audio_data, 0, number_of_frames * format_.mBytesPerFrame); + return noErr; } - int frames_filled = std::min(source_->OnMoreData( - audio_bus_.get(), AudioBuffersState(0, hardware_pending_bytes)), - static_cast(number_of_frames)); + int frames_filled = source_->OnMoreData( + audio_bus_.get(), AudioBuffersState(0, hardware_pending_bytes)); + // Note: If this ever changes to output raw float the data must be clipped and // sanitized since it may come from an untrusted source such as NaCl. audio_bus_->ToInterleaved( -- cgit v1.1