summaryrefslogtreecommitdiffstats
path: root/media/base/clock.h
blob: 5b2a90c28e8f6b9aa069564bdee661664b16dbf4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_BASE_CLOCK_H_
#define MEDIA_BASE_CLOCK_H_

#include "base/basictypes.h"
#include "base/time.h"
#include "media/base/media_export.h"

namespace media {

// A clock represents a single source of time to allow audio and video streams
// to synchronize with each other.  Clock essentially tracks the media time with
// respect to some other source of time, whether that may be the system clock or
// updates via SetTime(). Clock uses linear interpolation to calculate the
// current media time since the last time SetTime() was called.
//
// Clocks start off paused with a playback rate of 1.0f and a media time of 0.
//
// Clock is not thread-safe and must be externally locked.
//
// TODO(scherkus): Clock will some day be responsible for executing callbacks
// given a media time.  This will be used primarily by video renderers.  For now
// we'll keep using a poll-and-sleep solution.
class MEDIA_EXPORT Clock {
 public:
  // Type for a static function pointer that acts as a time source.
  typedef base::Time(TimeProvider)();

  explicit Clock(TimeProvider* time_provider);
  ~Clock();

  // Returns true if the clock is running.
  bool IsPlaying() const;

  // Starts the clock and returns the current media time, which will increase
  // with respect to the current playback rate.
  base::TimeDelta Play();

  // Stops the clock and returns the current media time, which will remain
  // constant until Play() is called.
  base::TimeDelta Pause();

  // Sets a new playback rate.  The rate at which the media time will increase
  // will now change.
  void SetPlaybackRate(float playback_rate);

  // Forcefully sets the media time to |current_time|. The second parameter is
  // the |max_time| that the clock should progress after a call to Play(). This
  // value is often the time of the end of the last frame buffered and decoded.
  //
  // These values are clamped to the duration of the video, which is initially
  // set to 0 (before SetDuration() is called).
  void SetTime(base::TimeDelta current_time, base::TimeDelta max_time);

  // Sets the |max_time| to be returned by a call to Elapsed().
  void SetMaxTime(base::TimeDelta max_time);

  // Returns the current elapsed media time. Returns 0 if SetDuration() has
  // never been called.
  base::TimeDelta Elapsed();

  // Sets the duration of the video. Clock expects the duration will be set
  // exactly once.
  void SetDuration(base::TimeDelta duration);

  // Resets clock to an uninitialized state.
  void Reset();

  // Notifies the clock that the end of stream has been reached. The clock state
  // is updated accordingly.
  void EndOfStream();

  // Returns the duration of the clock, or 0 if not set.
  base::TimeDelta Duration() const;

 private:
  // Updates the reference points based on the current calculated time.
  void UpdateReferencePoints();

  // Updates the reference points based on the given |current_time|.
  void UpdateReferencePoints(base::TimeDelta current_time);

  // Returns the time elapsed based on the current reference points, ignoring
  // the |max_time_| cap.
  base::TimeDelta EstimatedElapsedTime();

  // Returns the current media time treating the given time as the latest
  // value as returned by |time_provider_|.
  base::TimeDelta ElapsedViaProvidedTime(const base::Time& time) const;

  base::Time GetTimeFromProvider() const;

  base::TimeDelta ClampToValidTimeRange(base::TimeDelta time) const;

  // Function returning current time in base::Time units.
  TimeProvider* time_provider_;

  // Whether the clock is running.
  bool playing_;

  // Whether the clock is stalled because it has reached the |max_time_|
  // allowed.
  bool underflow_;

  // The system clock time when this clock last starting playing or had its
  // time set via SetTime().
  base::Time reference_;

  // Current accumulated amount of media time.  The remaining portion must be
  // calculated by comparing the system time to the reference time.
  base::TimeDelta media_time_;

  // Current playback rate.
  float playback_rate_;

  // The maximum time that can be returned by calls to Elapsed().
  base::TimeDelta max_time_;

  // Duration of the media.
  base::TimeDelta duration_;

  DISALLOW_COPY_AND_ASSIGN(Clock);
};

}  // namespace media

#endif  // MEDIA_BASE_CLOCK_H_