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.
4
5#ifndef MEDIA_BASE_CLOCK_H_
6#define MEDIA_BASE_CLOCK_H_
7
8#include "base/basictypes.h"
9#include "base/time/time.h"
10#include "media/base/media_export.h"
11
12namespace base {
13class TickClock;
14}  // namespace base
15
16namespace media {
17
18// A clock represents a single source of time to allow audio and video streams
19// to synchronize with each other.  Clock essentially tracks the media time with
20// respect to some other source of time, whether that may be the monotonic
21// system clock or updates via SetTime(). Clock uses linear interpolation to
22// calculate the current media time since the last time SetTime() was called.
23//
24// Clocks start off paused with a playback rate of 1.0f and a media time of 0.
25//
26// Clock is not thread-safe and must be externally locked.
27//
28// TODO(scherkus): Clock will some day be responsible for executing callbacks
29// given a media time.  This will be used primarily by video renderers.  For now
30// we'll keep using a poll-and-sleep solution.
31//
32// TODO(miu): Rename media::Clock to avoid confusion (and tripping up the media
33// PRESUBMIT script on future changes).
34class MEDIA_EXPORT Clock {
35 public:
36  explicit Clock(base::TickClock* clock);
37  ~Clock();
38
39  // Returns true if the clock is running.
40  bool IsPlaying() const;
41
42  // Starts the clock and returns the current media time, which will increase
43  // with respect to the current playback rate.
44  base::TimeDelta Play();
45
46  // Stops the clock and returns the current media time, which will remain
47  // constant until Play() is called.
48  base::TimeDelta Pause();
49
50  // Sets a new playback rate.  The rate at which the media time will increase
51  // will now change.
52  void SetPlaybackRate(float playback_rate);
53
54  // Forcefully sets the media time to |current_time|. The second parameter is
55  // the |max_time| that the clock should progress after a call to Play(). This
56  // value is often the time of the end of the last frame buffered and decoded.
57  //
58  // These values are clamped to the duration of the video, which is initially
59  // set to 0 (before SetDuration() is called).
60  void SetTime(base::TimeDelta current_time, base::TimeDelta max_time);
61
62  // Sets the |max_time| to be returned by a call to Elapsed().
63  void SetMaxTime(base::TimeDelta max_time);
64
65  // Returns the current elapsed media time. Returns 0 if SetDuration() has
66  // never been called.
67  base::TimeDelta Elapsed();
68
69  // Sets the duration of the video. Clock expects the duration will be set
70  // exactly once.
71  void SetDuration(base::TimeDelta duration);
72
73  // Resets clock to an uninitialized state.
74  void Reset();
75
76  // Notifies the clock that the end of stream has been reached. The clock state
77  // is updated accordingly.
78  void EndOfStream();
79
80  // Returns the duration of the clock, or 0 if not set.
81  base::TimeDelta Duration() const;
82
83 private:
84  // Updates the reference points based on the current calculated time.
85  void UpdateReferencePoints();
86
87  // Updates the reference points based on the given |current_time|.
88  void UpdateReferencePoints(base::TimeDelta current_time);
89
90  // Returns the time elapsed based on the current reference points, ignoring
91  // the |max_time_| cap.
92  base::TimeDelta EstimatedElapsedTime();
93
94  // Translates |time| into the current media time, based on the perspective of
95  // the monotonically-increasing system clock.
96  base::TimeDelta ElapsedViaProvidedTime(const base::TimeTicks& time) const;
97
98  base::TimeDelta ClampToValidTimeRange(base::TimeDelta time) const;
99
100  base::TickClock* const clock_;
101
102  // Whether the clock is running.
103  bool playing_;
104
105  // Whether the clock is stalled because it has reached the |max_time_|
106  // allowed.
107  bool underflow_;
108
109  // The monotonic system clock time when this Clock last started playing or had
110  // its time set via SetTime().
111  base::TimeTicks reference_;
112
113  // Current accumulated amount of media time.  The remaining portion must be
114  // calculated by comparing the system time to the reference time.
115  base::TimeDelta media_time_;
116
117  // Current playback rate.
118  float playback_rate_;
119
120  // The maximum time that can be returned by calls to Elapsed().
121  base::TimeDelta max_time_;
122
123  // Duration of the media.
124  base::TimeDelta duration_;
125
126  DISALLOW_COPY_AND_ASSIGN(Clock);
127};
128
129}  // namespace media
130
131#endif  // MEDIA_BASE_CLOCK_H_
132