diff options
author | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-19 04:12:47 +0000 |
---|---|---|
committer | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-19 04:12:47 +0000 |
commit | e985058189e86db1284b43d1526a95c5f8d8d61a (patch) | |
tree | dc61202b85483268782d6bfd1726d9bbb25b19a1 /media/audio/audio_output_resampler.cc | |
parent | 4985961c9f74dadfd5c5119d6d8096346e80c351 (diff) | |
download | chromium_src-e985058189e86db1284b43d1526a95c5f8d8d61a.zip chromium_src-e985058189e86db1284b43d1526a95c5f8d8d61a.tar.gz chromium_src-e985058189e86db1284b43d1526a95c5f8d8d61a.tar.bz2 |
Reset callback used by OnMoreDataResampler on StartStream.
If an AudioOutputProxy ended up being reused, we end up with
an audio dropout since the callback was cleared during the
last call to StopStream().
BUG=150702
TEST=none
Review URL: https://chromiumcodereview.appspot.com/10941026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157501 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/audio_output_resampler.cc')
-rw-r--r-- | media/audio/audio_output_resampler.cc | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/media/audio/audio_output_resampler.cc b/media/audio/audio_output_resampler.cc index 73765cd..f6cc2cf 100644 --- a/media/audio/audio_output_resampler.cc +++ b/media/audio/audio_output_resampler.cc @@ -27,8 +27,7 @@ class OnMoreDataResampler : public AudioOutputStream::AudioSourceCallback { public: OnMoreDataResampler(double io_ratio, const AudioParameters& input_params, - const AudioParameters& output_params, - AudioOutputStream::AudioSourceCallback* callback); + const AudioParameters& output_params); virtual ~OnMoreDataResampler(); // AudioSourceCallback interface. @@ -40,6 +39,10 @@ class OnMoreDataResampler : public AudioOutputStream::AudioSourceCallback { virtual void OnError(AudioOutputStream* stream, int code) OVERRIDE; virtual void WaitTillDataReady() OVERRIDE; + // Sets |source_callback_|. If this is not a new object, then Stop() must be + // called before Start(). + void Start(AudioOutputStream::AudioSourceCallback* callback); + // Clears |source_callback_| and flushes the resampler. void Stop(); @@ -279,11 +282,12 @@ bool AudioOutputResampler::StartStream( CallbackMap::iterator it = callbacks_.find(stream_proxy); if (it == callbacks_.end()) { resampler_callback = new OnMoreDataResampler( - io_ratio_, params_, output_params_, callback); + 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); } @@ -293,27 +297,33 @@ void AudioOutputResampler::StreamVolumeSet(AudioOutputProxy* stream_proxy, dispatcher_->StreamVolumeSet(stream_proxy, volume); } -void AudioOutputResampler::Reset(AudioOutputProxy* stream_proxy, - bool delete_callback) { - base::AutoLock auto_lock(callbacks_lock_); - CallbackMap::iterator it = callbacks_.find(stream_proxy); - if (it != callbacks_.end()) { - it->second->Stop(); - if (delete_callback) { - delete it->second; - callbacks_.erase(it); - } - } -} - void AudioOutputResampler::StopStream(AudioOutputProxy* stream_proxy) { dispatcher_->StopStream(stream_proxy); - Reset(stream_proxy, false); + + // 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(); + } } void AudioOutputResampler::CloseStream(AudioOutputProxy* stream_proxy) { dispatcher_->CloseStream(stream_proxy); - Reset(stream_proxy, true); + + // 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); + } + } } void AudioOutputResampler::Shutdown() { @@ -323,10 +333,9 @@ void AudioOutputResampler::Shutdown() { OnMoreDataResampler::OnMoreDataResampler( double io_ratio, const AudioParameters& input_params, - const AudioParameters& output_params, - AudioOutputStream::AudioSourceCallback* callback) + const AudioParameters& output_params) : io_ratio_(io_ratio), - source_callback_(callback), + source_callback_(NULL), outstanding_audio_bytes_(0), output_bytes_per_frame_(output_params.GetBytesPerFrame()), input_bytes_per_frame_(input_params.GetBytesPerFrame()) { @@ -357,8 +366,16 @@ OnMoreDataResampler::OnMoreDataResampler( OnMoreDataResampler::~OnMoreDataResampler() {} +void OnMoreDataResampler::Start( + AudioOutputStream::AudioSourceCallback* callback) { + base::AutoLock auto_lock(source_lock_); + DCHECK(!source_callback_); + source_callback_ = callback; +} + void OnMoreDataResampler::Stop() { base::AutoLock auto_lock(source_lock_); + DCHECK(source_callback_); source_callback_ = NULL; outstanding_audio_bytes_ = 0; if (audio_fifo_.get()) |