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

Unified Diff: media/audio/audio_output_resampler.cc

Issue 10958020: Don't fallback if we've successfully opened a stream previously. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Revert double-stop() change. Created 8 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: media/audio/audio_output_resampler.cc
diff --git a/media/audio/audio_output_resampler.cc b/media/audio/audio_output_resampler.cc
index 40c84a9e21469872102724bfdde1002d241cdaa2..11da5f8ed03721bd255a0e3bb492e08516d6c5bb 100644
--- a/media/audio/audio_output_resampler.cc
+++ b/media/audio/audio_output_resampler.cc
@@ -174,7 +174,8 @@ AudioOutputResampler::AudioOutputResampler(AudioManager* audio_manager,
: AudioOutputDispatcher(audio_manager, input_params),
io_ratio_(1),
close_delay_(close_delay),
- output_params_(output_params) {
+ output_params_(output_params),
+ streams_opened_(false) {
DCHECK_EQ(output_params_.format(), AudioParameters::AUDIO_PCM_LOW_LATENCY);
// Record UMA statistics for the hardware configuration.
@@ -197,7 +198,9 @@ AudioOutputResampler::AudioOutputResampler(AudioManager* audio_manager,
Initialize();
}
-AudioOutputResampler::~AudioOutputResampler() {}
+AudioOutputResampler::~AudioOutputResampler() {
+ DCHECK(callbacks_.empty());
+}
void AudioOutputResampler::Initialize() {
io_ratio_ = 1;
@@ -237,17 +240,25 @@ void AudioOutputResampler::Initialize() {
}
bool AudioOutputResampler::OpenStream() {
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
+
if (dispatcher_->OpenStream()) {
scherkus (not reviewing) 2012/09/21 01:24:18 I'm not a fan of the implicit stateness in this cl
DaleCurtis 2012/09/21 02:57:27 I'm not sure it's any more readable, but I've uplo
+ streams_opened_ = true;
// Only record the UMA statistic if we didn't fallback during construction.
if (output_params_.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY)
UMA_HISTOGRAM_BOOLEAN("Media.FallbackToHighLatencyAudioPath", false);
return true;
}
- // If we've already tried to open the stream in high latency mode, there's
- // nothing more to be done.
- if (output_params_.format() == AudioParameters::AUDIO_PCM_LINEAR)
+ // If we've already tried to open the stream in high latency mode or we've
+ // successfully opened a stream previously, there's nothing more to be done.
+ if (output_params_.format() == AudioParameters::AUDIO_PCM_LINEAR ||
+ streams_opened_ || !callbacks_.empty()) {
return false;
+ }
+
+ DCHECK(!streams_opened_);
+ DCHECK(callbacks_.empty());
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableAudioFallback)) {
@@ -256,10 +267,6 @@ bool AudioOutputResampler::OpenStream() {
return false;
}
- // TODO(dalecurtis): Is it better to recreate the whole |dispatcher_| ? See
- // http://crbug.com/149815
- dispatcher_->CloseStream(NULL);
-
DLOG(ERROR) << "Unable to open audio device in low latency mode. Falling "
<< "back to high latency audio output.";
@@ -276,63 +283,59 @@ bool AudioOutputResampler::OpenStream() {
bool AudioOutputResampler::StartStream(
AudioOutputStream::AudioSourceCallback* callback,
AudioOutputProxy* stream_proxy) {
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
+
OnMoreDataResampler* resampler_callback = NULL;
- {
- base::AutoLock auto_lock(callbacks_lock_);
- CallbackMap::iterator it = callbacks_.find(stream_proxy);
- if (it == callbacks_.end()) {
- resampler_callback = new OnMoreDataResampler(
- io_ratio_, params_, output_params_);
- callbacks_[stream_proxy] = resampler_callback;
- } else {
- resampler_callback = it->second;
- }
- resampler_callback->Start(callback);
+ CallbackMap::iterator it = callbacks_.find(stream_proxy);
+ if (it == callbacks_.end()) {
+ resampler_callback = new OnMoreDataResampler(
+ io_ratio_, params_, output_params_);
+ callbacks_[stream_proxy] = resampler_callback;
+ } else {
+ resampler_callback = it->second;
}
+ resampler_callback->Start(callback);
return dispatcher_->StartStream(resampler_callback, stream_proxy);
}
void AudioOutputResampler::StreamVolumeSet(AudioOutputProxy* stream_proxy,
double volume) {
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
dispatcher_->StreamVolumeSet(stream_proxy, volume);
}
void AudioOutputResampler::StopStream(AudioOutputProxy* stream_proxy) {
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
dispatcher_->StopStream(stream_proxy);
// Now that StopStream() has completed the underlying physical stream should
// be stopped and no longer calling OnMoreData(), making it safe to Stop() the
// OnMoreDataResampler.
- {
- base::AutoLock auto_lock(callbacks_lock_);
- CallbackMap::iterator it = callbacks_.find(stream_proxy);
- if (it != callbacks_.end())
- it->second->Stop();
- }
+ CallbackMap::iterator it = callbacks_.find(stream_proxy);
+ if (it != callbacks_.end())
+ it->second->Stop();
}
void AudioOutputResampler::CloseStream(AudioOutputProxy* stream_proxy) {
scherkus (not reviewing) 2012/09/21 01:24:18 to confirm.. we never have to reset streams_opened
DaleCurtis 2012/09/21 02:57:27 Nope, especially since AudioOutputDispatcherImpl m
- // Force StopStream() before CloseStream().
- // TODO(dalecurtis): This shouldn't be necessary, but somewhere in the chain
- // CloseStream() is occurring without a StopStream() which causes the callback
- // provided by OnMoreDataResampler to go away before the output stream is
- // ready. http://crbug.com/150619
- StopStream(stream_proxy);
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
dispatcher_->CloseStream(stream_proxy);
// We assume that StopStream() is always called prior to CloseStream(), so
// that it is safe to delete the OnMoreDataResampler here.
- {
- base::AutoLock auto_lock(callbacks_lock_);
- CallbackMap::iterator it = callbacks_.find(stream_proxy);
- if (it != callbacks_.end()) {
- delete it->second;
- callbacks_.erase(it);
- }
+ CallbackMap::iterator it = callbacks_.find(stream_proxy);
+ if (it != callbacks_.end()) {
+ delete it->second;
+ callbacks_.erase(it);
}
}
void AudioOutputResampler::Shutdown() {
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
+
+ // No AudioOutputProxy objects should hold a reference to us when we get
+ // to this stage.
+ DCHECK(HasOneRef()) << "Only the AudioManager should hold a reference";
scherkus (not reviewing) 2012/09/21 01:24:18 did this end up firing?
DaleCurtis 2012/09/21 02:57:27 During testing when I messed up the AOP/AOC state
+
dispatcher_->Shutdown();
DCHECK(callbacks_.empty());
}
« media/audio/audio_output_proxy_unittest.cc ('K') | « media/audio/audio_output_resampler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698