Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / media / filters / audio_clock.h
1 // Copyright 2014 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_FILTERS_AUDIO_CLOCK_H_
6 #define MEDIA_FILTERS_AUDIO_CLOCK_H_
7
8 #include <deque>
9
10 #include "base/time/time.h"
11 #include "media/base/media_export.h"
12
13 namespace media {
14
15 // Models a queue of buffered audio in a playback pipeline for use with
16 // estimating the amount of delay in wall clock time. Takes changes in playback
17 // rate into account to handle scenarios where multiple rates may be present in
18 // a playback pipeline with large delay.
19 //
20 //
21 // USAGE
22 //
23 // Prior to starting audio playback, construct an AudioClock with an initial
24 // media timestamp and a sample rate matching the sample rate the audio device
25 // was opened at.
26 //
27 // Each time the audio rendering callback is executed, call WroteAudio() once
28 // (and only once!) containing information on what was written:
29 //   1) How many frames of audio data requested
30 //   2) How many frames of audio data provided
31 //   3) The playback rate of the audio data provided
32 //   4) The current amount of delay
33 //
34 // After a call to WroteAudio(), clients can inspect the resulting media
35 // timestamp. This can be used for UI purposes, synchronizing video, etc...
36 //
37 //
38 // DETAILS
39 //
40 // Silence (whether caused by the initial audio delay or failing to write the
41 // amount of requested frames due to underflow) is also modeled and will cause
42 // the media timestamp to stop increasing until all known silence has been
43 // played. AudioClock's model is initialized with silence during the first call
44 // to WroteAudio() using the delay value.
45 //
46 // Playback rates are tracked for translating frame durations into media
47 // durations. Since silence doesn't affect media timestamps, it also isn't
48 // affected by playback rates.
49 class MEDIA_EXPORT AudioClock {
50  public:
51   AudioClock(base::TimeDelta start_timestamp, int sample_rate);
52   ~AudioClock();
53
54   // |frames_written| amount of audio data scaled to |playback_rate| written.
55   // |frames_requested| amount of audio data requested by hardware.
56   // |delay_frames| is the current amount of hardware delay.
57   void WroteAudio(int frames_written,
58                   int frames_requested,
59                   int delay_frames,
60                   float playback_rate);
61
62   // Returns the bounds of media data currently buffered by the audio hardware,
63   // taking silence and changes in playback rate into account. Buffered audio
64   // structure and timestamps are updated with every call to WroteAudio().
65   //
66   //  start_timestamp = 1000 ms                           sample_rate = 40 Hz
67   // +-----------------------+-----------------------+-----------------------+
68   // |   10 frames silence   |   20 frames @ 1.0x    |   20 frames @ 0.5x    |
69   // |      = 250 ms (wall)  |      = 500 ms (wall)  |      = 500 ms (wall)  |
70   // |      =   0 ms (media) |      = 500 ms (media) |      = 250 ms (media) |
71   // +-----------------------+-----------------------+-----------------------+
72   // ^                                                                       ^
73   // front_timestamp() is equal to               back_timestamp() is equal to
74   // |start_timestamp| since no                  amount of media frames tracked
75   // media data has been played yet.             by AudioClock, which would be
76   //                                             1000 + 500 + 250 = 1750 ms.
77   base::TimeDelta front_timestamp() const { return front_timestamp_; }
78   base::TimeDelta back_timestamp() const { return back_timestamp_; }
79
80   // Clients can provide |time_since_writing| to simulate the passage of time
81   // since last writing audio to get a more accurate current media timestamp.
82   //
83   // The value will be bounded between front_timestamp() and back_timestamp().
84   base::TimeDelta TimestampSinceWriting(
85       base::TimeDelta time_since_writing) const;
86
87   // Returns the amount of wall time until |timestamp| will be played by the
88   // audio hardware.
89   //
90   // |timestamp| must be within front_timestamp() and back_timestamp().
91   base::TimeDelta TimeUntilPlayback(base::TimeDelta timestamp) const;
92
93   // Returns the amount of contiguous media time buffered at the head of the
94   // audio hardware buffer. Silence introduced into the audio hardware buffer is
95   // treated as a break in media time.
96   base::TimeDelta contiguous_audio_data_buffered() const {
97     return contiguous_audio_data_buffered_;
98   }
99
100   // Same as above, but also treats changes in playback rate as a break in media
101   // time.
102   base::TimeDelta contiguous_audio_data_buffered_at_same_rate() const {
103     return contiguous_audio_data_buffered_at_same_rate_;
104   }
105
106  private:
107   // Even with a ridiculously high sample rate of 256kHz, using 64 bits will
108   // permit tracking up to 416999965 days worth of time (that's 1141 millenia).
109   //
110   // 32 bits on the other hand would top out at measly 2 hours and 20 minutes.
111   struct AudioData {
112     AudioData(int64_t frames, float playback_rate);
113
114     int64_t frames;
115     float playback_rate;
116   };
117
118   // Helpers for operating on |buffered_|.
119   void PushBufferedAudioData(int64_t frames, float playback_rate);
120   void PopBufferedAudioData(int64_t frames);
121   base::TimeDelta ComputeBufferedMediaTime(int64_t frames) const;
122
123   const base::TimeDelta start_timestamp_;
124   const int sample_rate_;
125   const double microseconds_per_frame_;
126
127   std::deque<AudioData> buffered_;
128   int64_t total_buffered_frames_;
129
130   base::TimeDelta front_timestamp_;
131   base::TimeDelta back_timestamp_;
132
133   // Cached results of last call to WroteAudio().
134   base::TimeDelta contiguous_audio_data_buffered_;
135   base::TimeDelta contiguous_audio_data_buffered_at_same_rate_;
136
137   DISALLOW_COPY_AND_ASSIGN(AudioClock);
138 };
139
140 }  // namespace media
141
142 #endif  // MEDIA_FILTERS_AUDIO_CLOCK_H_