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

Unified Diff: content/renderer/media/audio_renderer_impl.cc

Issue 9347029: Decouple 'give me more data' and 'rendered end of stream' audio callbacks. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 years, 10 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: content/renderer/media/audio_renderer_impl.cc
===================================================================
--- content/renderer/media/audio_renderer_impl.cc (revision 122285)
+++ content/renderer/media/audio_renderer_impl.cc (working copy)
@@ -39,12 +39,15 @@
AudioRendererImpl::AudioRendererImpl(media::AudioRendererSink* sink)
: AudioRendererBase(),
bytes_per_second_(0),
- stopped_(false),
+ state_(NOT_PLAYING),
sink_(sink),
is_initialized_(false) {
}
AudioRendererImpl::~AudioRendererImpl() {
+ DCHECK(signal_end_of_stream_callback_.IsCancelled());
+ if (!signal_end_of_stream_callback_.IsCancelled())
+ signal_end_of_stream_callback_.Cancel();
}
base::TimeDelta AudioRendererImpl::ConvertToDuration(int bytes) {
@@ -66,9 +69,10 @@
static_cast<int64>(ceil(predicted_play_time.InMicroseconds() *
playback_rate)));
}
- earliest_end_time_ =
+ base::AutoLock auto_lock(audio_renderer_impl_lock_);
+ set_earliest_end_time(
std::max(earliest_end_time_,
- time_now + request_delay + predicted_play_time);
+ time_now + request_delay + predicted_play_time));
}
}
@@ -106,20 +110,20 @@
}
void AudioRendererImpl::OnStop() {
- if (stopped_)
+ base::AutoLock auto_lock(audio_renderer_impl_lock_);
+ if (state_ == STOPPED)
return;
-
+ signal_end_of_stream_callback_.Cancel();
DCHECK(sink_.get());
sink_->Stop();
-
- stopped_ = true;
+ state_ = STOPPED;
}
void AudioRendererImpl::SetPlaybackRate(float rate) {
DCHECK_LE(0.0f, rate);
// Handle the case where we stopped due to IO message loop dying.
- if (stopped_) {
+ if (stopped()) {
AudioRendererBase::SetPlaybackRate(rate);
return;
}
@@ -138,7 +142,7 @@
void AudioRendererImpl::Pause(const base::Closure& callback) {
AudioRendererBase::Pause(callback);
- if (stopped_)
+ if (stopped())
return;
DoPause();
@@ -147,7 +151,7 @@
void AudioRendererImpl::Seek(base::TimeDelta time,
const media::FilterStatusCB& cb) {
AudioRendererBase::Seek(time, cb);
- if (stopped_)
+ if (stopped())
return;
DoSeek();
@@ -155,7 +159,7 @@
void AudioRendererImpl::Play(const base::Closure& callback) {
AudioRendererBase::Play(callback);
- if (stopped_)
+ if (stopped())
return;
if (GetPlaybackRate() != 0.0f) {
@@ -166,25 +170,47 @@
}
void AudioRendererImpl::SetVolume(float volume) {
- if (stopped_)
+ if (stopped())
return;
+
DCHECK(sink_.get());
sink_->SetVolume(volume);
}
+void AudioRendererImpl::DoSetOrCheckMessageLoopProxy() {
+ if (pipeline_message_loop_proxy_.get() == NULL) {
+ pipeline_message_loop_proxy_ = current_message_loop_proxy();
+ } else {
+ DCHECK_EQ(pipeline_message_loop_proxy_.get(), current_message_loop_proxy());
+ }
+}
+
void AudioRendererImpl::DoPlay() {
- earliest_end_time_ = base::Time::Now();
+ DoSetOrCheckMessageLoopProxy();
+ base::AutoLock auto_lock(audio_renderer_impl_lock_);
+ set_earliest_end_time(base::Time::Now());
+ signal_end_of_stream_callback_.Reset(
+ base::Bind(&AudioRendererImpl::DoSignalEndOfStream, AsWeakPtr()));
scherkus (not reviewing) 2012/03/03 02:24:32 are weak pointers enforced by cancellable callback
+ state_ = PLAYING;
DCHECK(sink_.get());
sink_->Play();
}
void AudioRendererImpl::DoPause() {
+ DoSetOrCheckMessageLoopProxy();
scherkus (not reviewing) 2012/03/03 02:24:32 I would strongly prefer having pipeline set the me
+ base::AutoLock auto_lock(audio_renderer_impl_lock_);
+ signal_end_of_stream_callback_.Cancel();
+ state_ = NOT_PLAYING;
DCHECK(sink_.get());
sink_->Pause(false);
}
void AudioRendererImpl::DoSeek() {
- earliest_end_time_ = base::Time::Now();
+ DoSetOrCheckMessageLoopProxy();
+ base::AutoLock auto_lock(audio_renderer_impl_lock_);
+ signal_end_of_stream_callback_.Cancel();
+ state_ = NOT_PLAYING;
+ set_earliest_end_time(base::Time::Now());
// Pause and flush the stream when we seek to a new location.
DCHECK(sink_.get());
@@ -194,10 +220,10 @@
size_t AudioRendererImpl::Render(const std::vector<float*>& audio_data,
size_t number_of_frames,
size_t audio_delay_milliseconds) {
- if (stopped_ || GetPlaybackRate() == 0.0f) {
+ if (state_ == STOPPED || GetPlaybackRate() == 0.0f) {
// Output silence if stopped.
for (size_t i = 0; i < audio_data.size(); ++i)
- memset(audio_data[i], 0, sizeof(float) * number_of_frames);
+ memset(audio_data[i], 0, sizeof(audio_data[i][0]) * number_of_frames);
return 0;
}
@@ -239,7 +265,7 @@
int frames_to_zero = number_of_frames - filled_frames;
memset(audio_data[channel_index] + filled_frames,
0,
- sizeof(float) * frames_to_zero);
+ sizeof(audio_data[channel_index][0]) * frames_to_zero);
}
}
return filled_frames;
@@ -249,8 +275,31 @@
host()->DisableAudioRenderer();
}
+int64 AudioRendererImpl::OnRenderEndOfStreamDelay() {
+ audio_renderer_impl_lock_.AssertAcquired();
+ return (earliest_end_time() - base::Time::Now()).InMilliseconds();
+}
+
void AudioRendererImpl::OnRenderEndOfStream() {
- // TODO(enal): schedule callback instead of polling.
- if (base::Time::Now() >= earliest_end_time_)
- SignalEndOfStream();
+ base::AutoLock auto_lock(audio_renderer_impl_lock_);
+ if (state_ == PLAYING) {
+ state_ = ENDED_EVENT_SCHEDULED;
+ int64 delay_ms = OnRenderEndOfStreamDelay();
+ if (delay_ms <= 0) {
scherkus (not reviewing) 2012/03/03 02:24:32 if the delay time was calculated to be <=0 wouldn'
+ pipeline_message_loop_proxy_->PostTask(
+ FROM_HERE,
+ signal_end_of_stream_callback_.callback());
+ } else {
+ pipeline_message_loop_proxy_->PostDelayedTask(
+ FROM_HERE,
+ signal_end_of_stream_callback_.callback(),
+ delay_ms);
+ }
+ }
}
+
+void AudioRendererImpl::DoSignalEndOfStream() {
+ DCHECK_EQ(pipeline_message_loop_proxy_.get(), current_message_loop_proxy());
+ SignalEndOfStream();
+ signal_end_of_stream_callback_.Cancel();
+}

Powered by Google App Engine
This is Rietveld 408576698