Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Unified Diff: media/filters/buffered_audio_tracker.cc

Issue 256163005: Introduce AudioClock to improve playback delay calculations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/filters/buffered_audio_tracker.cc
diff --git a/media/filters/buffered_audio_tracker.cc b/media/filters/buffered_audio_tracker.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f55ee784c49986c9986bac9c89871e9a9cc4e30c
--- /dev/null
+++ b/media/filters/buffered_audio_tracker.cc
@@ -0,0 +1,100 @@
+// Copyright 2014 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.
+
+#include "media/filters/buffered_audio_tracker.h"
+
+#include "base/logging.h"
+
+namespace media {
+
+BufferedAudioTracker::BufferedAudioTracker(int sample_rate)
+ : sample_rate_(sample_rate) {
+}
+
+BufferedAudioTracker::~BufferedAudioTracker() {
+}
+
+void BufferedAudioTracker::AudioCallbackFired(int delay_frames) {
+ if (buffered_audio_.empty())
+ return;
+
+ size_t i = buffered_audio_.size() - 1;
+ while (true) {
+ if (buffered_audio_[i].frames <= delay_frames) {
+ // Reached the end before accounting for all of |delay_frames|. This means
+ // we haven't written enough audio data yet to account for hardware delay.
+ // In this case, do nothing.
+ if (i == 0)
+ return;
+
+ // Keep accounting for |delay_frames|.
+ delay_frames -= buffered_audio_[i].frames;
+ --i;
+ continue;
+ }
+
+ // All of |delay_frames| has been accounted for: adjust amount of frames
+ // left in current buffer. All preceeding elements with index < |i| should
+ // be considered played out and hence discared.
+ buffered_audio_[i].frames = delay_frames;
+ break;
+ }
+
+ // At this point |i| points at what will be the new head of |buffered_audio_|
+ // however if it contains no audio it should be removed as well.
+ if (buffered_audio_[i].frames == 0)
+ ++i;
+
+ buffered_audio_.erase(buffered_audio_.begin(), buffered_audio_.begin() + i);
+}
+
+base::TimeDelta BufferedAudioTracker::BufferedTime() const {
+ base::TimeDelta buffered_time;
+
+ for (size_t i = 0; i < buffered_audio_.size(); ++i) {
+ // Skip over silence.
+ if (buffered_audio_[i].playback_rate == 0)
+ continue;
+
+ // Multiply by playback rate as frames represent time-scaled audio.
+ buffered_time += base::TimeDelta::FromMicroseconds(
+ base::Time::kMicrosecondsPerSecond * buffered_audio_[i].frames *
+ buffered_audio_[i].playback_rate / sample_rate_);
+ }
+
+ return buffered_time;
+}
+
+void BufferedAudioTracker::WroteAudio(int frames, float playback_rate) {
+ CHECK_GT(playback_rate, 0);
+ CHECK_GT(frames, 0);
+
+ // Avoid creating extra elements where possible.
+ if (!buffered_audio_.empty() &&
+ buffered_audio_.back().playback_rate == playback_rate) {
+ buffered_audio_.back().frames += frames;
+ return;
+ }
+
+ buffered_audio_.push_back(BufferedAudio(frames, playback_rate));
+}
+
+void BufferedAudioTracker::WroteSilence(int frames) {
+ CHECK_GT(frames, 0);
+
+ // Avoid creating extra elements where possible.
+ if (!buffered_audio_.empty() && buffered_audio_.back().playback_rate == 0) {
+ buffered_audio_.back().frames += frames;
+ return;
+ }
+
+ buffered_audio_.push_back(BufferedAudio(frames, 0));
+}
+
+BufferedAudioTracker::BufferedAudio::BufferedAudio(int frames,
+ float playback_rate)
+ : frames(frames), playback_rate(playback_rate) {
+}
+
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698