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
)
20 max_time_(kNoTimestamp()),
21 duration_(kNoTimestamp()) {
27 bool Clock::IsPlaying() const {
31 base::TimeDelta
Clock::Play() {
33 UpdateReferencePoints();
38 base::TimeDelta
Clock::Pause() {
40 UpdateReferencePoints();
45 void Clock::SetPlaybackRate(float playback_rate
) {
46 UpdateReferencePoints();
47 playback_rate_
= playback_rate
;
50 void Clock::SetTime(base::TimeDelta current_time
, base::TimeDelta max_time
) {
51 DCHECK(current_time
<= max_time
);
52 DCHECK(current_time
!= kNoTimestamp());
54 UpdateReferencePoints(current_time
);
55 max_time_
= ClampToValidTimeRange(max_time
);
59 base::TimeDelta
Clock::Elapsed() {
60 if (duration_
== kNoTimestamp())
61 return base::TimeDelta();
63 // The clock is not advancing, so return the last recorded time.
64 if (!playing_
|| underflow_
)
67 base::TimeDelta elapsed
= EstimatedElapsedTime();
68 if (max_time_
!= kNoTimestamp() && elapsed
> max_time_
) {
69 UpdateReferencePoints(max_time_
);
77 void Clock::SetMaxTime(base::TimeDelta max_time
) {
78 DCHECK(max_time
!= kNoTimestamp());
80 UpdateReferencePoints();
81 max_time_
= ClampToValidTimeRange(max_time
);
83 underflow_
= media_time_
> max_time_
;
85 media_time_
= max_time_
;
88 void Clock::SetDuration(base::TimeDelta duration
) {
89 DCHECK(duration
> base::TimeDelta());
92 media_time_
= ClampToValidTimeRange(media_time_
);
93 if (max_time_
!= kNoTimestamp())
94 max_time_
= ClampToValidTimeRange(max_time_
);
97 base::TimeDelta
Clock::ElapsedViaProvidedTime(
98 const base::TimeTicks
& time
) const {
99 // TODO(scherkus): floating point badness scaling time by playback rate.
100 int64 now_us
= (time
- reference_
).InMicroseconds();
101 now_us
= static_cast<int64
>(now_us
* playback_rate_
);
102 return media_time_
+ base::TimeDelta::FromMicroseconds(now_us
);
105 base::TimeDelta
Clock::ClampToValidTimeRange(base::TimeDelta time
) const {
106 if (duration_
== kNoTimestamp())
107 return base::TimeDelta();
108 return std::max(std::min(time
, duration_
), base::TimeDelta());
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()));