Index: media/blink/webmediaplayer_impl.cc |
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc |
index 63c66bda9d0c2d07030f6de8c7741a0d00730c79..f272d67efb57e8e123561613db3ee1ad40df691a 100644 |
--- a/media/blink/webmediaplayer_impl.cc |
+++ b/media/blink/webmediaplayer_impl.cc |
@@ -120,7 +120,6 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( |
playback_rate_(0.0), |
ended_(false), |
pending_seek_(false), |
- pending_seek_seconds_(0.0f), |
should_notify_time_changed_(false), |
client_(client), |
delegate_(delegate), |
@@ -290,13 +289,30 @@ void WebMediaPlayerImpl::seek(double seconds) { |
if (ready_state_ > WebMediaPlayer::ReadyStateHaveMetadata) |
SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); |
- base::TimeDelta seek_time = ConvertSecondsToTimestamp(seconds); |
+ base::TimeDelta new_seek_time = ConvertSecondsToTimestamp(seconds); |
if (seeking_) { |
+ if (new_seek_time == seek_time_) { |
+ if (chunk_demuxer_) { |
+ if (!pending_seek_) { |
+ // If using media source demuxer, only suppress redundant seeks if |
+ // there is no pending seek. This enforces that any pending seek that |
+ // results in a demuxer seek is preceded by matching |
+ // CancelPendingSeek() and StartWaitingForSeek() calls. |
+ return; |
+ } |
+ } else { |
+ // Suppress all redundant seeks if unrestricted by media source demuxer |
+ // API. |
+ pending_seek_ = false; |
Srirama
2015/06/09 17:08:42
I think this may not be required, isn't it already
wolenetz
2015/06/09 19:44:28
Consider the following sequence of seeks without a
xhwang
2015/06/09 21:33:57
reset |pending_seek_time_| as well?
wolenetz
2015/06/09 22:09:58
Sure, done. |pending_seek_time_| has no meaning wh
|
+ return; |
+ } |
+ } |
+ |
pending_seek_ = true; |
- pending_seek_seconds_ = seconds; |
+ pending_seek_time_ = new_seek_time; |
if (chunk_demuxer_) |
- chunk_demuxer_->CancelPendingSeek(seek_time); |
+ chunk_demuxer_->CancelPendingSeek(pending_seek_time_); |
return; |
} |
@@ -307,8 +323,8 @@ void WebMediaPlayerImpl::seek(double seconds) { |
// is completed and generate OnPipelineBufferingStateChanged event to |
// eventually fire seeking and seeked events |
if (paused_) { |
- if (paused_time_ != seek_time) { |
- paused_time_ = seek_time; |
+ if (paused_time_ != new_seek_time) { |
+ paused_time_ = new_seek_time; |
} else if (old_state == ReadyStateHaveEnoughData) { |
main_task_runner_->PostTask( |
FROM_HERE, |
@@ -319,14 +335,14 @@ void WebMediaPlayerImpl::seek(double seconds) { |
} |
seeking_ = true; |
+ seek_time_ = new_seek_time; |
if (chunk_demuxer_) |
- chunk_demuxer_->StartWaitingForSeek(seek_time); |
+ chunk_demuxer_->StartWaitingForSeek(seek_time_); |
// Kick off the asynchronous seek! |
- pipeline_.Seek( |
- seek_time, |
- BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, true)); |
+ pipeline_.Seek(seek_time_, BIND_TO_RENDER_LOOP1( |
+ &WebMediaPlayerImpl::OnPipelineSeeked, true)); |
} |
void WebMediaPlayerImpl::setRate(double rate) { |
@@ -443,6 +459,14 @@ double WebMediaPlayerImpl::currentTime() const { |
if (ended_) |
return duration(); |
+ // We know the current seek time better than pipeline: pipeline may processing |
+ // an earlier seek before a pending seek has been started, or it might not yet |
+ // have the current seek time returnable via GetMediaTime(). |
+ if (seeking()) { |
+ return pending_seek_ ? pending_seek_time_.InSecondsF() |
+ : seek_time_.InSecondsF(); |
+ } |
+ |
return (paused_ ? paused_time_ : pipeline_.GetMediaTime()).InSecondsF(); |
} |
@@ -716,7 +740,7 @@ void WebMediaPlayerImpl::OnPipelineSeeked(bool time_changed, |
seeking_ = false; |
if (pending_seek_) { |
pending_seek_ = false; |
- seek(pending_seek_seconds_); |
+ seek(pending_seek_time_.InSecondsF()); |
return; |
} |