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  // Returns the duration of the clock, or 0 if not set.
74  base::TimeDelta Duration() const;
75
76 private:
77  // Updates the reference points based on the current calculated time.
78  void UpdateReferencePoints();
79
80  // Updates the reference points based on the given |current_time|.
81  void UpdateReferencePoints(base::TimeDelta current_time);
82
83  // Returns the time elapsed based on the current reference points, ignoring
84  // the |max_time_| cap.
85  base::TimeDelta EstimatedElapsedTime();
86
87  // Translates |time| into the current media time, based on the perspective of
88  // the monotonically-increasing system clock.
89  base::TimeDelta ElapsedViaProvidedTime(const base::TimeTicks& time) const;
90
91  base::TimeDelta ClampToValidTimeRange(base::TimeDelta time) const;
92
93  base::TickClock* const clock_;
94
95  // Whether the clock is running.
96  bool playing_;
97
98  // Whether the clock is stalled because it has reached the |max_time_|
99  // allowed.
100  bool underflow_;
101
102  // The monotonic system clock time when this Clock last started playing or had
103  // its time set via SetTime().
104  base::TimeTicks reference_;
105
106  // Current accumulated amount of media time.  The remaining portion must be
107  // calculated by comparing the system time to the reference time.
108  base::TimeDelta media_time_;
109
110  // Current playback rate.
111  float playback_rate_;
112
113  // The maximum time that can be returned by calls to Elapsed().
114  base::TimeDelta max_time_;
115
116  // Duration of the media.
117  base::TimeDelta duration_;
118
119  DISALLOW_COPY_AND_ASSIGN(Clock);
120};
121
122}  // namespace media
123
124#endif  // MEDIA_BASE_CLOCK_H_
125