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

Unified Diff: media/base/audio_discard_helper.cc

Issue 259453003: Introduce AudioDiscardHelper. Refactor audio decoders to use it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix x64 type. 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
« no previous file with comments | « media/base/audio_discard_helper.h ('k') | media/base/audio_discard_helper_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/audio_discard_helper.cc
diff --git a/media/base/audio_discard_helper.cc b/media/base/audio_discard_helper.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3088130b00c48ca9f3c7966a4c45eac53e4ca87c
--- /dev/null
+++ b/media/base/audio_discard_helper.cc
@@ -0,0 +1,114 @@
+// 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/base/audio_discard_helper.h"
+
+#include <algorithm>
+
+#include "base/logging.h"
+#include "media/base/audio_buffer.h"
+#include "media/base/buffers.h"
+#include "media/base/decoder_buffer.h"
+
+namespace media {
+
+static void WarnOnNonMonotonicTimestamps(base::TimeDelta last_timestamp,
+ base::TimeDelta current_timestamp) {
+ if (last_timestamp == kNoTimestamp() || last_timestamp < current_timestamp)
+ return;
+
+ const base::TimeDelta diff = current_timestamp - last_timestamp;
+ DLOG(WARNING) << "Input timestamps are not monotonically increasing! "
+ << " ts " << current_timestamp.InMicroseconds() << " us"
+ << " diff " << diff.InMicroseconds() << " us";
+}
+
+AudioDiscardHelper::AudioDiscardHelper(int sample_rate)
+ : sample_rate_(sample_rate),
+ timestamp_helper_(sample_rate_),
+ discard_frames_(0),
+ last_input_timestamp_(kNoTimestamp()) {
+ DCHECK_GT(sample_rate_, 0);
+}
+
+AudioDiscardHelper::~AudioDiscardHelper() {
+}
+
+size_t AudioDiscardHelper::TimeDeltaToFrames(base::TimeDelta duration) const {
+ DCHECK(duration >= base::TimeDelta());
+ return duration.InSecondsF() * sample_rate_ + 0.5;
+}
+
+void AudioDiscardHelper::Reset(size_t initial_discard) {
+ discard_frames_ = initial_discard;
+ last_input_timestamp_ = kNoTimestamp();
+ timestamp_helper_.SetBaseTimestamp(kNoTimestamp());
+}
+
+bool AudioDiscardHelper::ProcessBuffers(
+ const scoped_refptr<DecoderBuffer>& encoded_buffer,
+ const scoped_refptr<AudioBuffer>& decoded_buffer) {
+ DCHECK(!encoded_buffer->end_of_stream());
+ DCHECK(encoded_buffer->timestamp() != kNoTimestamp());
+
+ // Issue a debug warning when we see non-monotonic timestamps. Only a warning
+ // to allow chained OGG playback.
+ WarnOnNonMonotonicTimestamps(last_input_timestamp_,
+ encoded_buffer->timestamp());
+ last_input_timestamp_ = encoded_buffer->timestamp();
+
+ // If this is the first buffer seen, setup the timestamp helper.
+ if (!initialized()) {
+ // Clamp the base timestamp to zero.
+ timestamp_helper_.SetBaseTimestamp(
+ std::max(base::TimeDelta(), encoded_buffer->timestamp()));
+ }
+ DCHECK(initialized());
+
+ if (!decoded_buffer || !decoded_buffer->frame_count())
+ return false;
+
+ if (discard_frames_ > 0) {
+ const size_t decoded_frames = decoded_buffer->frame_count();
+ const size_t frames_to_discard = std::min(discard_frames_, decoded_frames);
+ discard_frames_ -= frames_to_discard;
+
+ // If everything would be discarded, indicate a new buffer is required.
+ if (frames_to_discard == decoded_frames)
+ return false;
+
+ decoded_buffer->TrimStart(frames_to_discard);
+ }
+
+ // TODO(dalecurtis): Applying the current buffer's discard padding doesn't
+ // make sense in the Vorbis case because there is a delay of one buffer before
+ // decoded buffers are returned. Fix and add support for more than just end
+ // trimming. See http://crbug.com/360961.
+ if (encoded_buffer->discard_padding() > base::TimeDelta()) {
+ const size_t decoded_frames = decoded_buffer->frame_count();
+ const size_t end_frames_to_discard =
+ TimeDeltaToFrames(encoded_buffer->discard_padding());
+ if (end_frames_to_discard > decoded_frames) {
+ DLOG(ERROR) << "Encountered invalid discard padding value.";
+ return false;
+ }
+
+ // If everything would be discarded, indicate a new buffer is required.
+ if (end_frames_to_discard == decoded_frames)
+ return false;
+
+ decoded_buffer->TrimEnd(end_frames_to_discard);
+ } else {
+ DCHECK(encoded_buffer->discard_padding() == base::TimeDelta());
+ }
+
+ // Assign timestamp and duration to the buffer.
+ decoded_buffer->set_timestamp(timestamp_helper_.GetTimestamp());
+ decoded_buffer->set_duration(
+ timestamp_helper_.GetFrameDuration(decoded_buffer->frame_count()));
+ timestamp_helper_.AddFrames(decoded_buffer->frame_count());
+ return true;
+}
+
+} // namespace media
« no previous file with comments | « media/base/audio_discard_helper.h ('k') | media/base/audio_discard_helper_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698