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

Side by Side 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, 7 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 unified diff | Download patch | Annotate | Revision Log
« 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "media/base/audio_discard_helper.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10 #include "media/base/audio_buffer.h"
11 #include "media/base/buffers.h"
12 #include "media/base/decoder_buffer.h"
13
14 namespace media {
15
16 static void WarnOnNonMonotonicTimestamps(base::TimeDelta last_timestamp,
17 base::TimeDelta current_timestamp) {
18 if (last_timestamp == kNoTimestamp() || last_timestamp < current_timestamp)
19 return;
20
21 const base::TimeDelta diff = current_timestamp - last_timestamp;
22 DLOG(WARNING) << "Input timestamps are not monotonically increasing! "
23 << " ts " << current_timestamp.InMicroseconds() << " us"
24 << " diff " << diff.InMicroseconds() << " us";
25 }
26
27 AudioDiscardHelper::AudioDiscardHelper(int sample_rate)
28 : sample_rate_(sample_rate),
29 timestamp_helper_(sample_rate_),
30 discard_frames_(0),
31 last_input_timestamp_(kNoTimestamp()) {
32 DCHECK_GT(sample_rate_, 0);
33 }
34
35 AudioDiscardHelper::~AudioDiscardHelper() {
36 }
37
38 size_t AudioDiscardHelper::TimeDeltaToFrames(base::TimeDelta duration) const {
39 DCHECK(duration >= base::TimeDelta());
40 return duration.InSecondsF() * sample_rate_ + 0.5;
41 }
42
43 void AudioDiscardHelper::Reset(size_t initial_discard) {
44 discard_frames_ = initial_discard;
45 last_input_timestamp_ = kNoTimestamp();
46 timestamp_helper_.SetBaseTimestamp(kNoTimestamp());
47 }
48
49 bool AudioDiscardHelper::ProcessBuffers(
50 const scoped_refptr<DecoderBuffer>& encoded_buffer,
51 const scoped_refptr<AudioBuffer>& decoded_buffer) {
52 DCHECK(!encoded_buffer->end_of_stream());
53 DCHECK(encoded_buffer->timestamp() != kNoTimestamp());
54
55 // Issue a debug warning when we see non-monotonic timestamps. Only a warning
56 // to allow chained OGG playback.
57 WarnOnNonMonotonicTimestamps(last_input_timestamp_,
58 encoded_buffer->timestamp());
59 last_input_timestamp_ = encoded_buffer->timestamp();
60
61 // If this is the first buffer seen, setup the timestamp helper.
62 if (!initialized()) {
63 // Clamp the base timestamp to zero.
64 timestamp_helper_.SetBaseTimestamp(
65 std::max(base::TimeDelta(), encoded_buffer->timestamp()));
66 }
67 DCHECK(initialized());
68
69 if (!decoded_buffer || !decoded_buffer->frame_count())
70 return false;
71
72 if (discard_frames_ > 0) {
73 const size_t decoded_frames = decoded_buffer->frame_count();
74 const size_t frames_to_discard = std::min(discard_frames_, decoded_frames);
75 discard_frames_ -= frames_to_discard;
76
77 // If everything would be discarded, indicate a new buffer is required.
78 if (frames_to_discard == decoded_frames)
79 return false;
80
81 decoded_buffer->TrimStart(frames_to_discard);
82 }
83
84 // TODO(dalecurtis): Applying the current buffer's discard padding doesn't
85 // make sense in the Vorbis case because there is a delay of one buffer before
86 // decoded buffers are returned. Fix and add support for more than just end
87 // trimming. See http://crbug.com/360961.
88 if (encoded_buffer->discard_padding() > base::TimeDelta()) {
89 const size_t decoded_frames = decoded_buffer->frame_count();
90 const size_t end_frames_to_discard =
91 TimeDeltaToFrames(encoded_buffer->discard_padding());
92 if (end_frames_to_discard > decoded_frames) {
93 DLOG(ERROR) << "Encountered invalid discard padding value.";
94 return false;
95 }
96
97 // If everything would be discarded, indicate a new buffer is required.
98 if (end_frames_to_discard == decoded_frames)
99 return false;
100
101 decoded_buffer->TrimEnd(end_frames_to_discard);
102 } else {
103 DCHECK(encoded_buffer->discard_padding() == base::TimeDelta());
104 }
105
106 // Assign timestamp and duration to the buffer.
107 decoded_buffer->set_timestamp(timestamp_helper_.GetTimestamp());
108 decoded_buffer->set_duration(
109 timestamp_helper_.GetFrameDuration(decoded_buffer->frame_count()));
110 timestamp_helper_.AddFrames(decoded_buffer->frame_count());
111 return true;
112 }
113
114 } // namespace media
OLDNEW
« 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