Index: media/base/pipeline.cc |
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc |
index 359472f5aa198b950761f02c1271b732ada963c4..0f268c967efeb3f2759af823991d92d0adec412e 100644 |
--- a/media/base/pipeline.cc |
+++ b/media/base/pipeline.cc |
@@ -214,11 +214,7 @@ base::TimeDelta Pipeline::GetCurrentTime() const { |
base::TimeDelta Pipeline::GetCurrentTime_Locked() const { |
lock_.AssertAcquired(); |
- base::TimeDelta elapsed = clock_->Elapsed(); |
- if (elapsed > duration_) |
- return duration_; |
- |
- return elapsed; |
+ return clock_->Elapsed(); |
} |
base::TimeDelta Pipeline::GetBufferedTime() { |
@@ -226,8 +222,8 @@ base::TimeDelta Pipeline::GetBufferedTime() { |
// If media is fully loaded, then return duration. |
if (local_source_ || total_bytes_ == buffered_bytes_) { |
- max_buffered_time_ = duration_; |
- return duration_; |
+ max_buffered_time_ = clock_->Duration(); |
+ return max_buffered_time_; |
} |
base::TimeDelta current_time = GetCurrentTime_Locked(); |
@@ -241,7 +237,8 @@ base::TimeDelta Pipeline::GetBufferedTime() { |
// If buffered time was not set, we use current time, current bytes, and |
// buffered bytes to estimate the buffered time. |
- double estimated_rate = duration_.InMillisecondsF() / total_bytes_; |
+ double estimated_rate = |
+ clock_->Duration().InMillisecondsF() / total_bytes_; |
double estimated_current_time = estimated_rate * current_bytes_; |
DCHECK_GE(buffered_bytes_, current_bytes_); |
base::TimeDelta buffered_time = base::TimeDelta::FromMilliseconds( |
@@ -249,7 +246,7 @@ base::TimeDelta Pipeline::GetBufferedTime() { |
estimated_current_time)); |
// Cap approximated buffered time at the length of the video. |
- buffered_time = std::min(buffered_time, duration_); |
+ buffered_time = std::min(buffered_time, clock_->Duration()); |
// Make sure buffered_time is at least the current time |
buffered_time = std::max(buffered_time, current_time); |
@@ -262,7 +259,7 @@ base::TimeDelta Pipeline::GetBufferedTime() { |
base::TimeDelta Pipeline::GetMediaDuration() const { |
base::AutoLock auto_lock(lock_); |
- return duration_; |
+ return clock_->Duration(); |
} |
int64 Pipeline::GetBufferedBytes() const { |
@@ -323,7 +320,6 @@ void Pipeline::ResetState() { |
tearing_down_ = false; |
error_caused_teardown_ = false; |
playback_rate_change_pending_ = false; |
- duration_ = kZero; |
buffered_time_ = kZero; |
buffered_bytes_ = 0; |
streaming_ = false; |
@@ -339,7 +335,7 @@ void Pipeline::ResetState() { |
has_video_ = false; |
waiting_for_clock_update_ = false; |
audio_disabled_ = false; |
- clock_->SetTime(kZero); |
+ clock_->Reset(); |
download_rate_monitor_.Reset(); |
} |
@@ -451,20 +447,31 @@ base::TimeDelta Pipeline::GetDuration() const { |
return GetMediaDuration(); |
} |
-void Pipeline::SetTime(base::TimeDelta time) { |
+void Pipeline::OnAudioTimeUpdate(base::TimeDelta time, |
+ base::TimeDelta max_time) { |
+ DCHECK(time <= max_time); |
DCHECK(IsRunning()); |
base::AutoLock auto_lock(lock_); |
- // If we were waiting for a valid timestamp and such timestamp arrives, we |
- // need to clear the flag for waiting and start the clock. |
- if (waiting_for_clock_update_) { |
- if (time < clock_->Elapsed()) |
- return; |
- clock_->SetTime(time); |
- StartClockIfWaitingForTimeUpdate_Locked(); |
+ if (!has_audio_) |
return; |
- } |
- clock_->SetTime(time); |
+ if (waiting_for_clock_update_ && time < clock_->Elapsed()) |
+ return; |
+ |
+ clock_->SetTime(time, max_time); |
+ StartClockIfWaitingForTimeUpdate_Locked(); |
+} |
+ |
+void Pipeline::OnVideoTimeUpdate(base::TimeDelta max_time) { |
+ DCHECK(IsRunning()); |
+ base::AutoLock auto_lock(lock_); |
+ |
+ if (has_audio_) |
+ return; |
+ |
+ DCHECK(!waiting_for_clock_update_); |
+ DCHECK(clock_->Elapsed() <= max_time); |
+ clock_->SetMaxTime(max_time); |
} |
void Pipeline::SetDuration(base::TimeDelta duration) { |
@@ -475,7 +482,7 @@ void Pipeline::SetDuration(base::TimeDelta duration) { |
UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration); |
base::AutoLock auto_lock(lock_); |
- duration_ = duration; |
+ clock_->SetDuration(duration); |
} |
void Pipeline::SetBufferedTime(base::TimeDelta buffered_time) { |
@@ -903,6 +910,7 @@ void Pipeline::NotifyEndedTask() { |
// Start clock since there is no more audio to |
// trigger clock updates. |
base::AutoLock auto_lock(lock_); |
+ clock_->SetMaxTime(clock_->Duration()); |
StartClockIfWaitingForTimeUpdate_Locked(); |
} |
@@ -914,8 +922,7 @@ void Pipeline::NotifyEndedTask() { |
SetState(kEnded); |
{ |
base::AutoLock auto_lock(lock_); |
- clock_->Pause(); |
- clock_->SetTime(duration_); |
+ clock_->EndOfStream(); |
} |
if (!ended_callback_.is_null()) { |
@@ -947,6 +954,7 @@ void Pipeline::DisableAudioRendererTask() { |
// Start clock since there is no more audio to |
// trigger clock updates. |
+ clock_->SetMaxTime(clock_->Duration()); |
StartClockIfWaitingForTimeUpdate_Locked(); |
} |
@@ -975,7 +983,7 @@ void Pipeline::FilterStateTransitionTask() { |
SetState(FindNextState(state_)); |
if (state_ == kSeeking) { |
base::AutoLock auto_lock(lock_); |
- clock_->SetTime(seek_timestamp_); |
+ clock_->SetTime(seek_timestamp_, seek_timestamp_); |
} |
// Carry out the action for the current state. |
@@ -1014,8 +1022,10 @@ void Pipeline::FilterStateTransitionTask() { |
// 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. |
waiting_for_clock_update_ = true; |
- if (!has_audio_) |
+ if (!has_audio_) { |
+ clock_->SetMaxTime(clock_->Duration()); |
StartClockIfWaitingForTimeUpdate_Locked(); |
+ } |
// Start monitoring rate of downloading. |
int bitrate = 0; |
@@ -1144,7 +1154,7 @@ void Pipeline::OnDemuxerBuilt(PipelineStatus status, Demuxer* demuxer) { |
base::AutoLock auto_lock(lock_); |
// We do not want to start the clock running. We only want to set the base |
// media time so our timestamp calculations will be correct. |
- clock_->SetTime(demuxer_->GetStartTime()); |
+ clock_->SetTime(demuxer_->GetStartTime(), demuxer_->GetStartTime()); |
} |
OnFilterInitialize(PIPELINE_OK); |
@@ -1232,7 +1242,9 @@ bool Pipeline::InitializeAudioRenderer( |
audio_renderer_->Initialize( |
decoder, |
base::Bind(&Pipeline::OnFilterInitialize, this), |
- base::Bind(&Pipeline::OnAudioUnderflow, this)); |
+ base::Bind(&Pipeline::OnAudioUnderflow, this), |
+ base::Bind(&Pipeline::OnAudioTimeUpdate, this)); |
+ |
return true; |
} |
@@ -1256,7 +1268,8 @@ bool Pipeline::InitializeVideoRenderer( |
video_renderer_->Initialize( |
decoder, |
base::Bind(&Pipeline::OnFilterInitialize, this), |
- base::Bind(&Pipeline::OnUpdateStatistics, this)); |
+ base::Bind(&Pipeline::OnUpdateStatistics, this), |
+ base::Bind(&Pipeline::OnVideoTimeUpdate, this)); |
return true; |
} |