cc: Fix logic for detecting when raster tasks were throttled
[chromium-blink-merge.git] / media / base / clock.cc
blobea954834e94d3c4138313bc922123e71981eb1a3
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/base/clock.h"
7 #include <algorithm>
9 #include "base/logging.h"
10 #include "base/time/tick_clock.h"
11 #include "media/base/buffers.h"
13 namespace media {
15 Clock::Clock(base::TickClock* clock) : clock_(clock) {
16 DCHECK(clock_);
17 Reset();
20 Clock::~Clock() {}
22 bool Clock::IsPlaying() const {
23 return playing_;
26 base::TimeDelta Clock::Play() {
27 DCHECK(!playing_);
28 UpdateReferencePoints();
29 playing_ = true;
30 return media_time_;
33 base::TimeDelta Clock::Pause() {
34 DCHECK(playing_);
35 UpdateReferencePoints();
36 playing_ = false;
37 return media_time_;
40 void Clock::SetPlaybackRate(float playback_rate) {
41 UpdateReferencePoints();
42 playback_rate_ = playback_rate;
45 void Clock::SetTime(base::TimeDelta current_time, base::TimeDelta max_time) {
46 DCHECK(current_time <= max_time);
47 DCHECK(current_time != kNoTimestamp());
49 UpdateReferencePoints(current_time);
50 max_time_ = ClampToValidTimeRange(max_time);
51 underflow_ = false;
54 base::TimeDelta Clock::Elapsed() {
55 if (duration_ == kNoTimestamp())
56 return base::TimeDelta();
58 // The clock is not advancing, so return the last recorded time.
59 if (!playing_ || underflow_)
60 return media_time_;
62 base::TimeDelta elapsed = EstimatedElapsedTime();
63 if (max_time_ != kNoTimestamp() && elapsed > max_time_) {
64 UpdateReferencePoints(max_time_);
65 underflow_ = true;
66 elapsed = max_time_;
69 return elapsed;
72 void Clock::SetMaxTime(base::TimeDelta max_time) {
73 DCHECK(max_time != kNoTimestamp());
75 UpdateReferencePoints();
76 max_time_ = ClampToValidTimeRange(max_time);
78 underflow_ = media_time_ > max_time_;
79 if (underflow_)
80 media_time_ = max_time_;
83 void Clock::SetDuration(base::TimeDelta duration) {
84 DCHECK(duration > base::TimeDelta());
85 duration_ = duration;
87 media_time_ = ClampToValidTimeRange(media_time_);
88 if (max_time_ != kNoTimestamp())
89 max_time_ = ClampToValidTimeRange(max_time_);
92 base::TimeDelta Clock::ElapsedViaProvidedTime(
93 const base::TimeTicks& time) const {
94 // TODO(scherkus): floating point badness scaling time by playback rate.
95 int64 now_us = (time - reference_).InMicroseconds();
96 now_us = static_cast<int64>(now_us * playback_rate_);
97 return media_time_ + base::TimeDelta::FromMicroseconds(now_us);
100 base::TimeDelta Clock::ClampToValidTimeRange(base::TimeDelta time) const {
101 if (duration_ == kNoTimestamp())
102 return base::TimeDelta();
103 return std::max(std::min(time, duration_), base::TimeDelta());
106 void Clock::EndOfStream() {
107 Pause();
108 SetTime(Duration(), Duration());
111 base::TimeDelta Clock::Duration() const {
112 if (duration_ == kNoTimestamp())
113 return base::TimeDelta();
114 return duration_;
117 void Clock::UpdateReferencePoints() {
118 UpdateReferencePoints(Elapsed());
121 void Clock::UpdateReferencePoints(base::TimeDelta current_time) {
122 media_time_ = ClampToValidTimeRange(current_time);
123 reference_ = clock_->NowTicks();
126 base::TimeDelta Clock::EstimatedElapsedTime() {
127 return ClampToValidTimeRange(ElapsedViaProvidedTime(clock_->NowTicks()));
130 void Clock::Reset() {
131 playing_ = false;
132 playback_rate_ = 1.0f;
133 max_time_ = kNoTimestamp();
134 duration_ = kNoTimestamp();
135 media_time_ = base::TimeDelta();
136 reference_ = base::TimeTicks();
137 underflow_ = false;
140 } // namespace media