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

Side by Side Diff: media/base/audio_discard_helper.cc

Issue 414603002: Add support for partial append window end trimming. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixes. Created 6 years, 5 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/audio_discard_helper.h" 5 #include "media/base/audio_discard_helper.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "media/base/audio_buffer.h" 10 #include "media/base/audio_buffer.h"
(...skipping 11 matching lines...) Expand all
22 << " ts " << current_timestamp.InMicroseconds() << " us" 22 << " ts " << current_timestamp.InMicroseconds() << " us"
23 << " diff " << diff.InMicroseconds() << " us"; 23 << " diff " << diff.InMicroseconds() << " us";
24 } 24 }
25 25
26 AudioDiscardHelper::AudioDiscardHelper(int sample_rate, size_t decoder_delay) 26 AudioDiscardHelper::AudioDiscardHelper(int sample_rate, size_t decoder_delay)
27 : sample_rate_(sample_rate), 27 : sample_rate_(sample_rate),
28 decoder_delay_(decoder_delay), 28 decoder_delay_(decoder_delay),
29 timestamp_helper_(sample_rate_), 29 timestamp_helper_(sample_rate_),
30 discard_frames_(0), 30 discard_frames_(0),
31 last_input_timestamp_(kNoTimestamp()), 31 last_input_timestamp_(kNoTimestamp()),
32 delayed_discard_(false) { 32 delayed_discard_(false),
33 delayed_end_discard_(0) {
33 DCHECK_GT(sample_rate_, 0); 34 DCHECK_GT(sample_rate_, 0);
34 } 35 }
35 36
36 AudioDiscardHelper::~AudioDiscardHelper() { 37 AudioDiscardHelper::~AudioDiscardHelper() {
37 } 38 }
38 39
39 size_t AudioDiscardHelper::TimeDeltaToFrames(base::TimeDelta duration) const { 40 size_t AudioDiscardHelper::TimeDeltaToFrames(base::TimeDelta duration) const {
40 DCHECK(duration >= base::TimeDelta()); 41 DCHECK(duration >= base::TimeDelta());
41 return duration.InSecondsF() * sample_rate_ + 0.5; 42 return duration.InSecondsF() * sample_rate_ + 0.5;
42 } 43 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 // around endpoint tracking when handling complete buffer discards. 93 // around endpoint tracking when handling complete buffer discards.
93 DCHECK_EQ(decoder_delay_, 0u); 94 DCHECK_EQ(decoder_delay_, 0u);
94 std::swap(current_discard_padding, delayed_discard_padding_); 95 std::swap(current_discard_padding, delayed_discard_padding_);
95 } 96 }
96 97
97 if (discard_frames_ > 0) { 98 if (discard_frames_ > 0) {
98 const size_t decoded_frames = decoded_buffer->frame_count(); 99 const size_t decoded_frames = decoded_buffer->frame_count();
99 const size_t frames_to_discard = std::min(discard_frames_, decoded_frames); 100 const size_t frames_to_discard = std::min(discard_frames_, decoded_frames);
100 discard_frames_ -= frames_to_discard; 101 discard_frames_ -= frames_to_discard;
101 102
103 DVLOG(1) << "Initial discard of " << frames_to_discard << " out of "
104 << decoded_frames << " frames.";
105
102 // If everything would be discarded, indicate a new buffer is required. 106 // If everything would be discarded, indicate a new buffer is required.
103 if (frames_to_discard == decoded_frames) { 107 if (frames_to_discard == decoded_frames) {
104 // For simplicity disallow cases where a buffer with discard padding is 108 // For simplicity disallow cases where a buffer with discard padding is
105 // present. Doing so allows us to avoid complexity around tracking 109 // present. Doing so allows us to avoid complexity around tracking
106 // discards across buffers. 110 // discards across buffers.
107 DCHECK(current_discard_padding.first == base::TimeDelta()); 111 DCHECK(current_discard_padding.first == base::TimeDelta());
108 DCHECK(current_discard_padding.second == base::TimeDelta()); 112 DCHECK(current_discard_padding.second == base::TimeDelta());
109 return false; 113 return false;
110 } 114 }
111 115
112 decoded_buffer->TrimStart(frames_to_discard); 116 decoded_buffer->TrimStart(frames_to_discard);
113 } 117 }
114 118
119 // Process any delayed end discard from the previous buffer.
120 if (delayed_end_discard_ > 0) {
121 DCHECK_GT(decoder_delay_, 0u);
122 DCHECK_LT(delayed_end_discard_, decoder_delay_);
123
124 const size_t decoded_frames = decoded_buffer->frame_count();
125 const size_t frames_to_discard = decoder_delay_ - delayed_end_discard_;
126 DCHECK_LT(frames_to_discard, decoded_frames);
127
128 DVLOG(1) << "Delayed end discard of " << frames_to_discard << " out of "
129 << decoded_frames << " frames starting at "
130 << delayed_end_discard_;
131
132 decoded_buffer->TrimRange(delayed_end_discard_,
133 delayed_end_discard_ + frames_to_discard);
134 delayed_end_discard_ = 0;
135 }
136
115 // Handle front discard padding. 137 // Handle front discard padding.
116 if (current_discard_padding.first > base::TimeDelta()) { 138 if (current_discard_padding.first > base::TimeDelta()) {
117 const size_t decoded_frames = decoded_buffer->frame_count(); 139 const size_t decoded_frames = decoded_buffer->frame_count();
118 140
119 // If a complete buffer discard is requested and there's no decoder delay, 141 // If a complete buffer discard is requested and there's no decoder delay,
120 // just discard all remaining frames from this buffer. With decoder delay 142 // just discard all remaining frames from this buffer. With decoder delay
121 // we have to estimate the correct number of frames to discard based on the 143 // we have to estimate the correct number of frames to discard based on the
122 // duration of the encoded buffer. 144 // duration of the encoded buffer.
123 const size_t start_frames_to_discard = 145 const size_t start_frames_to_discard =
124 current_discard_padding.first == kInfiniteDuration() 146 current_discard_padding.first == kInfiniteDuration()
(...skipping 21 matching lines...) Expand all
146 CHECK_LT(discard_start, decoded_frames); 168 CHECK_LT(discard_start, decoded_frames);
147 169
148 const size_t frames_to_discard = 170 const size_t frames_to_discard =
149 std::min(start_frames_to_discard, decoded_frames - discard_start); 171 std::min(start_frames_to_discard, decoded_frames - discard_start);
150 172
151 // Carry over any frames which need to be discarded from the front of the 173 // Carry over any frames which need to be discarded from the front of the
152 // next buffer. 174 // next buffer.
153 DCHECK(!discard_frames_); 175 DCHECK(!discard_frames_);
154 discard_frames_ = start_frames_to_discard - frames_to_discard; 176 discard_frames_ = start_frames_to_discard - frames_to_discard;
155 177
178 DVLOG(1) << "Front discard of " << frames_to_discard << " out of "
179 << decoded_frames << " frames starting at " << discard_start;
180
156 // If everything would be discarded, indicate a new buffer is required. 181 // If everything would be discarded, indicate a new buffer is required.
157 if (frames_to_discard == decoded_frames) { 182 if (frames_to_discard == decoded_frames) {
158 // The buffer should not have been marked with end discard if the front 183 // The buffer should not have been marked with end discard if the front
159 // discard removes everything. 184 // discard removes everything.
160 DCHECK(current_discard_padding.second == base::TimeDelta()); 185 DCHECK(current_discard_padding.second == base::TimeDelta());
161 return false; 186 return false;
162 } 187 }
163 188
164 decoded_buffer->TrimRange(discard_start, discard_start + frames_to_discard); 189 decoded_buffer->TrimRange(discard_start, discard_start + frames_to_discard);
165 } else { 190 } else {
166 DCHECK(current_discard_padding.first == base::TimeDelta()); 191 DCHECK(current_discard_padding.first == base::TimeDelta());
167 } 192 }
168 193
169 // Handle end discard padding. 194 // Handle end discard padding.
170 if (current_discard_padding.second > base::TimeDelta()) { 195 if (current_discard_padding.second > base::TimeDelta()) {
171 // Limit end discarding to when there is no |decoder_delay_|, otherwise it's 196 const size_t decoded_frames = decoded_buffer->frame_count();
172 // non-trivial determining where to start discarding end frames. 197 size_t end_frames_to_discard =
173 CHECK(!decoder_delay_); 198 TimeDeltaToFrames(current_discard_padding.second);
174 199
175 const size_t decoded_frames = decoded_buffer->frame_count(); 200 if (decoder_delay_) {
176 const size_t end_frames_to_discard = 201 // Delayed end discard only works if the decoder delay is less than a
177 TimeDeltaToFrames(current_discard_padding.second); 202 // single buffer.
203 DCHECK_LT(decoder_delay_, original_frame_count);
204
205 // If the discard is >= the decoder delay, trim everything we can off the
206 // end of this buffer and the rest from the start of the next.
207 if (end_frames_to_discard >= decoder_delay_) {
208 DCHECK(!discard_frames_);
209 discard_frames_ = decoder_delay_;
210 end_frames_to_discard -= decoder_delay_;
211 } else {
212 delayed_end_discard_ = decoder_delay_ - end_frames_to_discard;
acolwell GONE FROM CHROMIUM 2014/07/24 19:22:14 Can you just store end_frames_to_discard here and
DaleCurtis 2014/07/29 01:35:09 Done.
213 end_frames_to_discard = 0;
214 }
215 }
178 216
179 if (end_frames_to_discard > decoded_frames) { 217 if (end_frames_to_discard > decoded_frames) {
180 DLOG(ERROR) << "Encountered invalid discard padding value."; 218 DLOG(ERROR) << "Encountered invalid discard padding value.";
181 return false; 219 return false;
182 } 220 }
183 221
184 // If everything would be discarded, indicate a new buffer is required. 222 if (end_frames_to_discard > 0) {
185 if (end_frames_to_discard == decoded_frames) 223 DVLOG(1) << "End discard of " << end_frames_to_discard << " out of "
186 return false; 224 << decoded_frames;
187 225
188 decoded_buffer->TrimEnd(end_frames_to_discard); 226 // If everything would be discarded, indicate a new buffer is required.
227 if (end_frames_to_discard == decoded_frames)
228 return false;
229
230 decoded_buffer->TrimEnd(end_frames_to_discard);
231 }
189 } else { 232 } else {
190 DCHECK(current_discard_padding.second == base::TimeDelta()); 233 DCHECK(current_discard_padding.second == base::TimeDelta());
191 } 234 }
192 235
193 // Assign timestamp to the buffer. 236 // Assign timestamp to the buffer.
194 decoded_buffer->set_timestamp(timestamp_helper_.GetTimestamp()); 237 decoded_buffer->set_timestamp(timestamp_helper_.GetTimestamp());
195 timestamp_helper_.AddFrames(decoded_buffer->frame_count()); 238 timestamp_helper_.AddFrames(decoded_buffer->frame_count());
196 return true; 239 return true;
197 } 240 }
198 241
199 } // namespace media 242 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698