diff options
Diffstat (limited to 'media/base/clock.cc')
-rw-r--r-- | media/base/clock.cc | 109 |
1 files changed, 84 insertions, 25 deletions
diff --git a/media/base/clock.cc b/media/base/clock.cc index 4cdc021..2517d1d 100644 --- a/media/base/clock.cc +++ b/media/base/clock.cc @@ -10,9 +10,8 @@ namespace media { Clock::Clock(TimeProvider* time_provider) - : time_provider_(time_provider), - playing_(false), - playback_rate_(1.0f) { + : time_provider_(time_provider) { + Reset(); } Clock::~Clock() {} @@ -23,44 +22,64 @@ bool Clock::IsPlaying() const { base::TimeDelta Clock::Play() { DCHECK(!playing_); - reference_ = GetTimeFromProvider(); + UpdateReferencePoints(); playing_ = true; return media_time_; } base::TimeDelta Clock::Pause() { DCHECK(playing_); - // Save our new accumulated amount of media time. - media_time_ = Elapsed(); + UpdateReferencePoints(); playing_ = false; return media_time_; } void Clock::SetPlaybackRate(float playback_rate) { - if (playing_) { - base::Time time = GetTimeFromProvider(); - media_time_ = ElapsedViaProvidedTime(time); - reference_ = time; - } + UpdateReferencePoints(); playback_rate_ = playback_rate; } -void Clock::SetTime(const base::TimeDelta& time) { - if (time == kNoTimestamp()) { - NOTREACHED(); - return; - } - if (playing_) { - reference_ = GetTimeFromProvider(); - } - media_time_ = time; +void Clock::SetTime(base::TimeDelta current_time, base::TimeDelta max_time) { + DCHECK(current_time <= max_time); + DCHECK(current_time != kNoTimestamp()); + + UpdateReferencePoints(current_time); + max_time_ = ClampToValidTimeRange(max_time); + underflow_ = false; } -base::TimeDelta Clock::Elapsed() const { - if (!playing_) { +base::TimeDelta Clock::Elapsed() { + if (duration_ == kNoTimestamp()) + return base::TimeDelta(); + + // The clock is not advancing, so return the last recorded time. + if (!playing_ || underflow_) return media_time_; + + base::TimeDelta elapsed = EstimatedElapsedTime(); + if (max_time_ != kNoTimestamp() && elapsed > max_time_) { + UpdateReferencePoints(max_time_); + underflow_ = true; + elapsed = max_time_; } - return ElapsedViaProvidedTime(GetTimeFromProvider()); + + return elapsed; +} + +void Clock::SetMaxTime(base::TimeDelta max_time) { + DCHECK(max_time != kNoTimestamp()); + + UpdateReferencePoints(); + max_time_ = ClampToValidTimeRange(max_time); + + DCHECK(media_time_ <= max_time_); + underflow_ = false; +} + +void Clock::SetDuration(base::TimeDelta duration) { + DCHECK(duration_ == kNoTimestamp()); + DCHECK(duration > base::TimeDelta()); + duration_ = duration; } base::TimeDelta Clock::ElapsedViaProvidedTime(const base::Time& time) const { @@ -71,10 +90,50 @@ base::TimeDelta Clock::ElapsedViaProvidedTime(const base::Time& time) const { } base::Time Clock::GetTimeFromProvider() const { - if (time_provider_) { + if (time_provider_) return time_provider_(); - } return base::Time(); } +base::TimeDelta Clock::ClampToValidTimeRange(base::TimeDelta time) const { + if (duration_ == kNoTimestamp()) + return base::TimeDelta(); + return std::max(std::min(time, duration_), base::TimeDelta()); +} + +void Clock::EndOfStream() { + Pause(); + SetTime(Duration(), Duration()); +} + +base::TimeDelta Clock::Duration() const { + if (duration_ == kNoTimestamp()) + return base::TimeDelta(); + return duration_; +} + +void Clock::UpdateReferencePoints() { + UpdateReferencePoints(Elapsed()); +} + +void Clock::UpdateReferencePoints(base::TimeDelta current_time) { + media_time_ = ClampToValidTimeRange(current_time); + reference_ = GetTimeFromProvider(); +} + +base::TimeDelta Clock::EstimatedElapsedTime() { + return ClampToValidTimeRange( + ElapsedViaProvidedTime(GetTimeFromProvider())); +} + +void Clock::Reset() { + playing_ = false; + playback_rate_ = 1.0f; + max_time_ = kNoTimestamp(); + duration_ = kNoTimestamp(); + media_time_ = base::TimeDelta(); + reference_ = base::Time(); + underflow_ = false; +} + } // namespace media |