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

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 121128)
+++ content/renderer/media/audio_renderer_impl.cc (working copy)
@@ -16,6 +16,8 @@
#include "media/audio/audio_util.h"
#include "media/base/filter_host.h"
+using base::subtle::AtomicWord;
+
// We define GetBufferSizeForSampleRate() instead of using
// GetAudioHardwareBufferSize() in audio_util because we're using
// the AUDIO_PCM_LINEAR flag, instead of AUDIO_PCM_LOW_LATENCY,
@@ -41,7 +43,10 @@
bytes_per_second_(0),
stopped_(false),
sink_(sink),
- is_initialized_(false) {
+ is_initialized_(false),
+ ended_event_scheduled_(false),
+ io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()),
+ stream_id_(0) {
}
AudioRendererImpl::~AudioRendererImpl() {
@@ -66,9 +71,9 @@
static_cast<int64>(ceil(predicted_play_time.InMicroseconds() *
playback_rate)));
}
- earliest_end_time_ =
+ set_earliest_end_time(
std::max(earliest_end_time_,
- time_now + request_delay + predicted_play_time);
+ time_now + request_delay + predicted_play_time));
}
}
@@ -173,18 +178,22 @@
}
void AudioRendererImpl::DoPlay() {
- earliest_end_time_ = base::Time::Now();
+ set_earliest_end_time(base::Time::Now());
+ ended_event_scheduled_ = false;
DCHECK(sink_.get());
sink_->Play();
}
void AudioRendererImpl::DoPause() {
+ ++stream_id_;
DCHECK(sink_.get());
sink_->Pause(false);
}
void AudioRendererImpl::DoSeek() {
- earliest_end_time_ = base::Time::Now();
+ set_earliest_end_time(base::Time::Now());
+ ended_event_scheduled_ = false;
+ ++stream_id_;
// Pause and flush the stream when we seek to a new location.
DCHECK(sink_.get());
@@ -197,7 +206,7 @@
if (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 +248,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 +258,28 @@
host()->DisableAudioRenderer();
}
+int64 AudioRendererImpl::OnRenderEndOfStreamDelay() {
+ 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_)
+ if (!ended_event_scheduled_) {
+ ended_event_scheduled_ = true;
+ int64 delay_ms = OnRenderEndOfStreamDelay();
+ if (delay_ms <= 0) {
+ DoSignalEndOfStream(stream_id_);
+ } else {
+ io_message_loop_proxy_->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&AudioRendererImpl::DoSignalEndOfStream, this, stream_id_),
+ delay_ms);
+ }
+ }
+}
+
+void AudioRendererImpl::DoSignalEndOfStream(AtomicWord stream_id) {
+ // There is no way to cancel delayed task if we paused or seeked after task
+ // was scheduled, use stream id to catch such case.
+ if (stream_id == stream_id_)
SignalEndOfStream();
}

Powered by Google App Engine
This is Rietveld 408576698