summaryrefslogtreecommitdiff
path: root/chromium/media/filters/audio_clock.h
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@theqtcompany.com>2014-12-05 15:04:29 +0100
committerAndras Becsi <andras.becsi@theqtcompany.com>2014-12-09 10:49:28 +0100
commitaf6588f8d723931a298c995fa97259bb7f7deb55 (patch)
tree060ca707847ba1735f01af2372e0d5e494dc0366 /chromium/media/filters/audio_clock.h
parent2fff84d821cc7b1c785f6404e0f8091333283e74 (diff)
downloadqtwebengine-chromium-af6588f8d723931a298c995fa97259bb7f7deb55.tar.gz
BASELINE: Update chromium to 40.0.2214.28 and ninja to 1.5.3.
Change-Id: I759465284fd64d59ad120219cbe257f7402c4181 Reviewed-by: Andras Becsi <andras.becsi@theqtcompany.com>
Diffstat (limited to 'chromium/media/filters/audio_clock.h')
-rw-r--r--chromium/media/filters/audio_clock.h138
1 files changed, 102 insertions, 36 deletions
diff --git a/chromium/media/filters/audio_clock.h b/chromium/media/filters/audio_clock.h
index a0d8212f948..6472f11319e 100644
--- a/chromium/media/filters/audio_clock.h
+++ b/chromium/media/filters/audio_clock.h
@@ -16,57 +16,123 @@ namespace media {
// estimating the amount of delay in wall clock time. Takes changes in playback
// rate into account to handle scenarios where multiple rates may be present in
// a playback pipeline with large delay.
+//
+//
+// USAGE
+//
+// Prior to starting audio playback, construct an AudioClock with an initial
+// media timestamp and a sample rate matching the sample rate the audio device
+// was opened at.
+//
+// Each time the audio rendering callback is executed, call WroteAudio() once
+// (and only once!) containing information on what was written:
+// 1) How many frames of audio data requested
+// 2) How many frames of audio data provided
+// 3) The playback rate of the audio data provided
+// 4) The current amount of delay
+//
+// After a call to WroteAudio(), clients can inspect the resulting media
+// timestamp. This can be used for UI purposes, synchronizing video, etc...
+//
+//
+// DETAILS
+//
+// Silence (whether caused by the initial audio delay or failing to write the
+// amount of requested frames due to underflow) is also modeled and will cause
+// the media timestamp to stop increasing until all known silence has been
+// played. AudioClock's model is initialized with silence during the first call
+// to WroteAudio() using the delay value.
+//
+// Playback rates are tracked for translating frame durations into media
+// durations. Since silence doesn't affect media timestamps, it also isn't
+// affected by playback rates.
class MEDIA_EXPORT AudioClock {
public:
- explicit AudioClock(int sample_rate);
+ AudioClock(base::TimeDelta start_timestamp, int sample_rate);
~AudioClock();
- // |frames| amount of audio data scaled to |playback_rate| was written.
+ // |frames_written| amount of audio data scaled to |playback_rate| written.
+ // |frames_requested| amount of audio data requested by hardware.
// |delay_frames| is the current amount of hardware delay.
- // |timestamp| is the endpoint media timestamp of the audio data written.
- void WroteAudio(int frames,
+ void WroteAudio(int frames_written,
+ int frames_requested,
int delay_frames,
- float playback_rate,
- base::TimeDelta timestamp);
-
- // |frames| amount of silence was written.
- // |delay_frames| is the current amount of hardware delay.
- void WroteSilence(int frames, int delay_frames);
-
- // Calculates the current media timestamp taking silence and changes in
- // playback rate into account.
- base::TimeDelta CurrentMediaTimestamp() const;
+ float playback_rate);
+
+ // Returns the bounds of media data currently buffered by the audio hardware,
+ // taking silence and changes in playback rate into account. Buffered audio
+ // structure and timestamps are updated with every call to WroteAudio().
+ //
+ // start_timestamp = 1000 ms sample_rate = 40 Hz
+ // +-----------------------+-----------------------+-----------------------+
+ // | 10 frames silence | 20 frames @ 1.0x | 20 frames @ 0.5x |
+ // | = 250 ms (wall) | = 500 ms (wall) | = 500 ms (wall) |
+ // | = 0 ms (media) | = 500 ms (media) | = 250 ms (media) |
+ // +-----------------------+-----------------------+-----------------------+
+ // ^ ^
+ // front_timestamp() is equal to back_timestamp() is equal to
+ // |start_timestamp| since no amount of media frames tracked
+ // media data has been played yet. by AudioClock, which would be
+ // 1000 + 500 + 250 = 1750 ms.
+ base::TimeDelta front_timestamp() const { return front_timestamp_; }
+ base::TimeDelta back_timestamp() const { return back_timestamp_; }
+
+ // Clients can provide |time_since_writing| to simulate the passage of time
+ // since last writing audio to get a more accurate current media timestamp.
+ //
+ // The value will be bounded between front_timestamp() and back_timestamp().
+ base::TimeDelta TimestampSinceWriting(
+ base::TimeDelta time_since_writing) const;
+
+ // Returns the amount of wall time until |timestamp| will be played by the
+ // audio hardware.
+ //
+ // |timestamp| must be within front_timestamp() and back_timestamp().
+ base::TimeDelta TimeUntilPlayback(base::TimeDelta timestamp) const;
+
+ // Returns the amount of contiguous media time buffered at the head of the
+ // audio hardware buffer. Silence introduced into the audio hardware buffer is
+ // treated as a break in media time.
+ base::TimeDelta contiguous_audio_data_buffered() const {
+ return contiguous_audio_data_buffered_;
+ }
- // Returns the last endpoint timestamp provided to WroteAudio().
- base::TimeDelta last_endpoint_timestamp() const {
- return last_endpoint_timestamp_;
+ // Same as above, but also treats changes in playback rate as a break in media
+ // time.
+ base::TimeDelta contiguous_audio_data_buffered_at_same_rate() const {
+ return contiguous_audio_data_buffered_at_same_rate_;
}
private:
- void TrimBufferedAudioToMatchDelay(int delay_frames);
- void PushBufferedAudio(int frames,
- float playback_rate,
- base::TimeDelta endpoint_timestamp);
+ // Even with a ridiculously high sample rate of 256kHz, using 64 bits will
+ // permit tracking up to 416999965 days worth of time (that's 1141 millenia).
+ //
+ // 32 bits on the other hand would top out at measly 2 hours and 20 minutes.
+ struct AudioData {
+ AudioData(int64_t frames, float playback_rate);
+
+ int64_t frames;
+ float playback_rate;
+ };
- const int sample_rate_;
+ // Helpers for operating on |buffered_|.
+ void PushBufferedAudioData(int64_t frames, float playback_rate);
+ void PopBufferedAudioData(int64_t frames);
+ base::TimeDelta ComputeBufferedMediaTime(int64_t frames) const;
- // Initially set to kNoTimestamp(), otherwise is the last endpoint timestamp
- // delivered to WroteAudio(). A copy is kept outside of |buffered_audio_| to
- // handle the case where all of |buffered_audio_| has been replaced with
- // silence.
- base::TimeDelta last_endpoint_timestamp_;
+ const base::TimeDelta start_timestamp_;
+ const int sample_rate_;
+ const double microseconds_per_frame_;
- struct BufferedAudio {
- BufferedAudio(int frames,
- float playback_rate,
- base::TimeDelta endpoint_timestamp);
+ std::deque<AudioData> buffered_;
+ int64_t total_buffered_frames_;
- int frames;
- float playback_rate;
- base::TimeDelta endpoint_timestamp;
- };
+ base::TimeDelta front_timestamp_;
+ base::TimeDelta back_timestamp_;
- std::deque<BufferedAudio> buffered_audio_;
+ // Cached results of last call to WroteAudio().
+ base::TimeDelta contiguous_audio_data_buffered_;
+ base::TimeDelta contiguous_audio_data_buffered_at_same_rate_;
DISALLOW_COPY_AND_ASSIGN(AudioClock);
};