diff options
author | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-08 23:28:35 +0000 |
---|---|---|
committer | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-08 23:28:35 +0000 |
commit | 55d448fc1913406a9d94dce5550d22d7b180a0e8 (patch) | |
tree | 6664cc3a56add99e604a589f491defd21cf4a1cf /media | |
parent | b35d68d66741c6adc8a5f2aac75c3323a5e2c86c (diff) | |
download | chromium_src-55d448fc1913406a9d94dce5550d22d7b180a0e8.zip chromium_src-55d448fc1913406a9d94dce5550d22d7b180a0e8.tar.gz chromium_src-55d448fc1913406a9d94dce5550d22d7b180a0e8.tar.bz2 |
Fix a couple bugs with OSX audio buffer size selection.
1. Device changes may cause an already in process stream creation
to use the wrong buffer size => CHECK() failure.
2. Low latency stream Open() failure causes AudioOutputResampler
to fall back to a high latency buffer size, which will cause a
stream to be created with the wrong buffer size => CHECK() failure.
Fixing 2 has the added advantage of removing an extra useless hop
between stream Open() failure and switching to a fake audio output
device.
BUG=225249
TEST=audio works.
Review URL: https://chromiumcodereview.appspot.com/13390010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192946 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/audio/audio_output_proxy_unittest.cc | 18 | ||||
-rw-r--r-- | media/audio/audio_output_resampler.cc | 15 | ||||
-rw-r--r-- | media/audio/mac/audio_low_latency_output_mac.cc | 25 |
3 files changed, 42 insertions, 16 deletions
diff --git a/media/audio/audio_output_proxy_unittest.cc b/media/audio/audio_output_proxy_unittest.cc index cb20bd0..224bbf5 100644 --- a/media/audio/audio_output_proxy_unittest.cc +++ b/media/audio/audio_output_proxy_unittest.cc @@ -628,8 +628,15 @@ TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) { TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) { MockAudioOutputStream okay_stream(&manager_, params_); +// Only Windows has a high latency output driver that is not the same as the low +// latency path. +#if defined(OS_WIN) + static const int kFallbackCount = 2; +#else + static const int kFallbackCount = 1; +#endif EXPECT_CALL(manager(), MakeAudioOutputStream(_)) - .Times(2) + .Times(kFallbackCount) .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); // To prevent shared memory issues the sample rate and buffer size should @@ -656,8 +663,15 @@ TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) { // stream, and the fake audio output stream and ensure AudioOutputResampler // terminates normally. TEST_F(AudioOutputResamplerTest, AllFallbackFailed) { +// Only Windows has a high latency output driver that is not the same as the low +// latency path. +#if defined(OS_WIN) + static const int kFallbackCount = 3; +#else + static const int kFallbackCount = 2; +#endif EXPECT_CALL(manager(), MakeAudioOutputStream(_)) - .Times(3) + .Times(kFallbackCount) .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); diff --git a/media/audio/audio_output_resampler.cc b/media/audio/audio_output_resampler.cc index 5abea0a..26d83f8 100644 --- a/media/audio/audio_output_resampler.cc +++ b/media/audio/audio_output_resampler.cc @@ -124,6 +124,9 @@ static void RecordFallbackStats(const AudioParameters& output_params) { } } +// Only Windows has a high latency output driver that is not the same as the low +// latency path. +#if defined(OS_WIN) // Converts low latency based |output_params| into high latency appropriate // output parameters in error situations. static AudioParameters SetupFallbackParams( @@ -142,6 +145,7 @@ static AudioParameters SetupFallbackParams( input_params.sample_rate(), input_params.bits_per_sample(), frames_per_buffer); } +#endif AudioOutputResampler::AudioOutputResampler(AudioManager* audio_manager, const AudioParameters& input_params, @@ -202,18 +206,23 @@ bool AudioOutputResampler::OpenStream() { return false; } - DLOG(ERROR) << "Unable to open audio device in low latency mode. Falling " - << "back to high latency audio output."; - // Record UMA statistics about the hardware which triggered the failure so // we can debug and triage later. RecordFallbackStats(output_params_); + + // Only Windows has a high latency output driver that is not the same as the + // low latency path. +#if defined(OS_WIN) + DLOG(ERROR) << "Unable to open audio device in low latency mode. Falling " + << "back to high latency audio output."; + output_params_ = SetupFallbackParams(params_, output_params_); Initialize(); if (dispatcher_->OpenStream()) { streams_opened_ = true; return true; } +#endif DLOG(ERROR) << "Unable to open audio device in high latency mode. Falling " << "back to fake audio output."; diff --git a/media/audio/mac/audio_low_latency_output_mac.cc b/media/audio/mac/audio_low_latency_output_mac.cc index 592a6a1..afa480a 100644 --- a/media/audio/mac/audio_low_latency_output_mac.cc +++ b/media/audio/mac/audio_low_latency_output_mac.cc @@ -78,12 +78,8 @@ AUAudioOutputStream::AUAudioOutputStream( DVLOG(1) << "Desired ouput format: " << format_; // Calculate the number of sample frames per callback. - number_of_frames_ = params.GetBytesPerBuffer() / format_.mBytesPerPacket; + number_of_frames_ = params.frames_per_buffer(); DVLOG(1) << "Number of frames per callback: " << number_of_frames_; - const AudioParameters parameters = - manager_->GetDefaultOutputStreamParameters(); - CHECK_EQ(number_of_frames_, - static_cast<size_t>(parameters.frames_per_buffer())); } AUAudioOutputStream::~AUAudioOutputStream() { @@ -99,7 +95,7 @@ bool AUAudioOutputStream::Open() { &size, &output_device_id_); if (result != noErr || output_device_id_ == kAudioObjectUnknown) { - OSSTATUS_DLOG(WARNING, result) + OSSTATUS_DLOG(ERROR, result) << "Could not get default audio output device."; return false; } @@ -119,13 +115,13 @@ bool AUAudioOutputStream::Open() { result = AudioComponentInstanceNew(comp, &output_unit_); if (result != noErr) { - OSSTATUS_DLOG(WARNING, result) << "AudioComponentInstanceNew() failed."; + OSSTATUS_DLOG(ERROR, result) << "AudioComponentInstanceNew() failed."; return false; } result = AudioUnitInitialize(output_unit_); if (result != noErr) { - OSSTATUS_DLOG(WARNING, result) << "AudioUnitInitialize() failed."; + OSSTATUS_DLOG(ERROR, result) << "AudioUnitInitialize() failed."; return false; } @@ -147,7 +143,7 @@ bool AUAudioOutputStream::Configure() { &input, sizeof(input)); if (result != noErr) { - OSSTATUS_DLOG(WARNING, result) + OSSTATUS_DLOG(ERROR, result) << "AudioUnitSetProperty(kAudioUnitProperty_SetRenderCallback) failed."; return false; } @@ -161,7 +157,7 @@ bool AUAudioOutputStream::Configure() { &format_, sizeof(format_)); if (result != noErr) { - OSSTATUS_DLOG(WARNING, result) + OSSTATUS_DLOG(ERROR, result) << "AudioUnitSetProperty(kAudioUnitProperty_StreamFormat) failed."; return false; } @@ -172,6 +168,13 @@ bool AUAudioOutputStream::Configure() { // be the same as the frames_per_buffer() returned by // GetDefaultOutputStreamParameters. // See http://crbug.com/154352 for details. + const AudioParameters hw_params = + manager_->GetDefaultOutputStreamParameters(); + if (number_of_frames_ != static_cast<size_t>(hw_params.frames_per_buffer())) { + DLOG(ERROR) << "Audio buffer size does not match hardware buffer size."; + return false; + } + UInt32 buffer_size = number_of_frames_; result = AudioUnitSetProperty( output_unit_, @@ -181,7 +184,7 @@ bool AUAudioOutputStream::Configure() { &buffer_size, sizeof(buffer_size)); if (result != noErr) { - OSSTATUS_DLOG(WARNING, result) + OSSTATUS_DLOG(ERROR, result) << "AudioUnitSetProperty(kAudioDevicePropertyBufferFrameSize) failed."; return false; } |