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"
9 #include "base/logging.h"
10 #include "base/time/tick_clock.h"
11 #include "media/base/buffers.h"
15 Clock::Clock(base::TickClock
* clock
) : clock_(clock
) {
22 bool Clock::IsPlaying() const {
26 base::TimeDelta
Clock::Play() {
28 UpdateReferencePoints();
33 base::TimeDelta
Clock::Pause() {
35 UpdateReferencePoints();
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
);
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_
)
62 base::TimeDelta elapsed
= EstimatedElapsedTime();
63 if (max_time_
!= kNoTimestamp() && elapsed
> max_time_
) {
64 UpdateReferencePoints(max_time_
);
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_
;
80 media_time_
= max_time_
;
83 void Clock::SetDuration(base::TimeDelta duration
) {
84 DCHECK(duration
> base::TimeDelta());
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() {
108 SetTime(Duration(), Duration());
111 base::TimeDelta
Clock::Duration() const {
112 if (duration_
== kNoTimestamp())
113 return base::TimeDelta();
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() {
132 playback_rate_
= 1.0f
;
133 max_time_
= kNoTimestamp();
134 duration_
= kNoTimestamp();
135 media_time_
= base::TimeDelta();
136 reference_
= base::TimeTicks();