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

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: Simplify! 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/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..b907fe8e4858d3a4b92fcaa6de5a3eeb17fa65d7
--- /dev/null
+++ b/media/base/audio_discard_helper.cc
@@ -0,0 +1,110 @@
+// 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 <cmath>
+
+#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()) {
wolenetz 2014/04/28 21:52:07 nit: is any sanity checking needed on sample_rate_
DaleCurtis 2014/04/28 23:09:03 As far as this code is concerned it just needs to
+}
+
+AudioDiscardHelper::~AudioDiscardHelper() {
+}
+
+int AudioDiscardHelper::TimeDeltaToFrames(base::TimeDelta duration) const {
+ DCHECK(duration >= base::TimeDelta());
+ return std::ceil(duration.InSecondsF() * sample_rate_);
wolenetz 2014/04/28 21:52:07 With ceil(), might we hit off-by-one stuff here? (
DaleCurtis 2014/04/28 23:09:03 Since this floating point value is calculated from
+}
+
+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())
+ timestamp_helper_.SetBaseTimestamp(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);
wolenetz 2014/04/28 21:52:07 TrimStart() will modify decoded_buffer's duration_
DaleCurtis 2014/04/28 22:03:51 It's this codes expectation that it is the sole au
wolenetz 2014/04/28 22:37:56 Regarding assumption of ability to set duration/ti
DaleCurtis 2014/04/28 23:09:03 I think that comment can be removed now. I'll do
+ }
+
+ // 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.
wolenetz 2014/04/28 21:52:07 nit: reference bug?
DaleCurtis 2014/04/28 23:09:03 Done.
+ 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) {
wolenetz 2014/04/28 21:52:07 Is end discard aware of start discard? (If not, co
DaleCurtis 2014/04/28 22:03:51 It's expected that users of discard_padding() will
+ DLOG(ERROR) << "Invalid file. Incorrect discard padding value.";
wolenetz 2014/04/28 21:52:07 nit: If this helper will be used by MSE, not just
DaleCurtis 2014/04/28 23:09:03 Done.
+ 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

Powered by Google App Engine
This is Rietveld 408576698