summaryrefslogtreecommitdiffstats
path: root/media/audio/audio_output_resampler.cc
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-19 04:12:47 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-19 04:12:47 +0000
commite985058189e86db1284b43d1526a95c5f8d8d61a (patch)
treedc61202b85483268782d6bfd1726d9bbb25b19a1 /media/audio/audio_output_resampler.cc
parent4985961c9f74dadfd5c5119d6d8096346e80c351 (diff)
downloadchromium_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.cc59
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())