summaryrefslogtreecommitdiffstats
path: root/media/audio
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-08 23:28:35 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-08 23:28:35 +0000
commit55d448fc1913406a9d94dce5550d22d7b180a0e8 (patch)
tree6664cc3a56add99e604a589f491defd21cf4a1cf /media/audio
parentb35d68d66741c6adc8a5f2aac75c3323a5e2c86c (diff)
downloadchromium_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/audio')
-rw-r--r--media/audio/audio_output_proxy_unittest.cc18
-rw-r--r--media/audio/audio_output_resampler.cc15
-rw-r--r--media/audio/mac/audio_low_latency_output_mac.cc25
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;
}