summaryrefslogtreecommitdiffstats
path: root/media/base
diff options
context:
space:
mode:
authordavej@chromium.org <davej@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-14 23:34:00 +0000
committerdavej@chromium.org <davej@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-14 23:34:00 +0000
commit4841a4bde07696cad73224a0c7e28ea9343c9e1c (patch)
tree5750fda34ee1ed66d1a17b5e78bed0cf0630ba22 /media/base
parentfb930c854c9d3d984411eb6be45242af793943b3 (diff)
downloadchromium_src-4841a4bde07696cad73224a0c7e28ea9343c9e1c.zip
chromium_src-4841a4bde07696cad73224a0c7e28ea9343c9e1c.tar.gz
chromium_src-4841a4bde07696cad73224a0c7e28ea9343c9e1c.tar.bz2
Fix erratic HTML5 audio playback
This was affecting all platforms. The major issue was that he SetPlaybackRate(1) which is used to start playback was being done in the middle of the series of Seek operations. So doing Seek() followed by SetPlaybackRate(1) was done, the Seek could immediately stop the playback. To fix, Seek() was made atomic with regards to SetPlaybackRate() by delaying the execution of SetPlaybackRate until after the Seek sequence has completely finished. To make things run even smoother, a short delay was added before recyclilng a used audio stream in the Dispatcher. This gives the stream time to 'power down' before being reused. Tested on Linux, Chrome-OS (Cr48) and Mac with great results, making HTML5 audio much more usable for games. BUG=73045,59369,59370,65618 TEST=Manual, Quickly playing/stopping HTML5 audio should play cleanly. Review URL: http://codereview.chromium.org/6822019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81670 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base')
-rw-r--r--media/base/pipeline_impl.cc17
-rw-r--r--media/base/pipeline_impl.h6
2 files changed, 23 insertions, 0 deletions
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index f574b85..25bdf47 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -358,6 +358,7 @@ void PipelineImpl::ResetState() {
seek_pending_ = false;
tearing_down_ = false;
error_caused_teardown_ = false;
+ playback_rate_change_pending_ = false;
duration_ = kZero;
buffered_time_ = kZero;
buffered_bytes_ = 0;
@@ -369,6 +370,7 @@ void PipelineImpl::ResetState() {
volume_ = 1.0f;
preload_ = AUTO;
playback_rate_ = 0.0f;
+ pending_playback_rate_ = 0.0f;
status_ = PIPELINE_OK;
has_audio_ = false;
has_video_ = false;
@@ -780,6 +782,14 @@ void PipelineImpl::ErrorChangedTask(PipelineStatus error) {
void PipelineImpl::PlaybackRateChangedTask(float playback_rate) {
DCHECK_EQ(MessageLoop::current(), message_loop_);
+
+ // Suppress rate change until after seeking.
+ if (IsPipelineSeeking()) {
+ pending_playback_rate_ = playback_rate;
+ playback_rate_change_pending_ = true;
+ return;
+ }
+
{
base::AutoLock auto_lock(lock_);
clock_->SetPlaybackRate(playback_rate);
@@ -959,6 +969,13 @@ void PipelineImpl::FilterStateTransitionTask() {
seek_timestamp_ = base::TimeDelta();
seek_pending_ = false;
+ // If a playback rate change was requested during a seek, do it now that
+ // the seek has compelted.
+ if (playback_rate_change_pending_) {
+ playback_rate_change_pending_ = false;
+ PlaybackRateChangedTask(pending_playback_rate_);
+ }
+
base::AutoLock auto_lock(lock_);
// We use audio stream to update the clock. So if there is such a stream,
// we pause the clock until we receive a valid timestamp.
diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h
index 5dcbcea..7b5fe4a 100644
--- a/media/base/pipeline_impl.h
+++ b/media/base/pipeline_impl.h
@@ -330,6 +330,9 @@ class PipelineImpl : public Pipeline, public FilterHost {
// Whether or not an error triggered the teardown.
bool error_caused_teardown_;
+ // Whether or not a playback rate change should be done once seeking is done.
+ bool playback_rate_change_pending_;
+
// Duration of the media in microseconds. Set by filters.
base::TimeDelta duration_;
@@ -372,6 +375,9 @@ class PipelineImpl : public Pipeline, public FilterHost {
// the filters.
float playback_rate_;
+ // Playback rate to set when the current seek has finished.
+ float pending_playback_rate_;
+
// Reference clock. Keeps track of current playback time. Uses system
// clock and linear interpolation, but can have its time manually set
// by filters.