diff options
author | davej@chromium.org <davej@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-14 23:34:00 +0000 |
---|---|---|
committer | davej@chromium.org <davej@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-14 23:34:00 +0000 |
commit | 4841a4bde07696cad73224a0c7e28ea9343c9e1c (patch) | |
tree | 5750fda34ee1ed66d1a17b5e78bed0cf0630ba22 /media/base | |
parent | fb930c854c9d3d984411eb6be45242af793943b3 (diff) | |
download | chromium_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.cc | 17 | ||||
-rw-r--r-- | media/base/pipeline_impl.h | 6 |
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. |