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.
5 #include "base/memory/scoped_ptr.h"
6 #include "media/base/audio_buffer.h"
7 #include "media/base/audio_bus.h"
8 #include "media/base/audio_discard_helper.h"
9 #include "media/base/buffers.h"
10 #include "media/base/decoder_buffer.h"
11 #include "media/base/test_helpers.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 static const float kDataStep
= 0.01f
;
17 static const size_t kSampleRate
= 48000;
19 static scoped_refptr
<DecoderBuffer
> CreateEncodedBuffer(
20 base::TimeDelta timestamp
,
21 base::TimeDelta duration
) {
22 scoped_refptr
<DecoderBuffer
> result(new DecoderBuffer(1));
23 result
->set_timestamp(timestamp
);
24 result
->set_duration(duration
);
28 static scoped_refptr
<AudioBuffer
> CreateDecodedBuffer(int frames
) {
29 return MakeAudioBuffer(kSampleFormatPlanarF32
,
39 static float ExtractDecodedData(const scoped_refptr
<AudioBuffer
>& buffer
,
41 // This is really inefficient, but we can't access the raw AudioBuffer if any
42 // start trimming has been applied.
43 scoped_ptr
<AudioBus
> temp_bus
= AudioBus::Create(buffer
->channel_count(), 1);
44 buffer
->ReadFrames(1, index
, 0, temp_bus
.get());
45 return temp_bus
->channel(0)[0];
48 TEST(AudioDiscardHelperTest
, TimeDeltaToFrames
) {
49 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
51 EXPECT_EQ(0u, discard_helper
.TimeDeltaToFrames(base::TimeDelta()));
54 discard_helper
.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10)));
56 // Ensure partial frames are rounded down correctly. The equation below
57 // calculates a frame count with a fractional part < 0.5.
58 const int small_remainder
=
59 base::Time::kMicrosecondsPerSecond
* (kSampleRate
- 0.9) / kSampleRate
;
60 EXPECT_EQ(kSampleRate
- 1,
61 discard_helper
.TimeDeltaToFrames(
62 base::TimeDelta::FromMicroseconds(small_remainder
)));
64 // Ditto, but rounded up using a fractional part > 0.5.
65 const int large_remainder
=
66 base::Time::kMicrosecondsPerSecond
* (kSampleRate
- 0.4) / kSampleRate
;
67 EXPECT_EQ(kSampleRate
,
68 discard_helper
.TimeDeltaToFrames(
69 base::TimeDelta::FromMicroseconds(large_remainder
)));
72 TEST(AudioDiscardHelperTest
, BasicProcessBuffers
) {
73 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
74 ASSERT_FALSE(discard_helper
.initialized());
76 const base::TimeDelta kTimestamp
= base::TimeDelta();
78 // Use an estimated duration which doesn't match the number of decoded frames
79 // to ensure the helper is correctly setting durations based on output frames.
80 const base::TimeDelta kEstimatedDuration
=
81 base::TimeDelta::FromMilliseconds(9);
82 const base::TimeDelta kActualDuration
= base::TimeDelta::FromMilliseconds(10);
83 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kActualDuration
);
85 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
86 CreateEncodedBuffer(kTimestamp
, kEstimatedDuration
);
87 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
89 // Verify the basic case where nothing is discarded.
90 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
91 ASSERT_TRUE(discard_helper
.initialized());
92 EXPECT_EQ(kTimestamp
, decoded_buffer
->timestamp());
93 EXPECT_EQ(kActualDuration
, decoded_buffer
->duration());
94 EXPECT_EQ(kTestFrames
, decoded_buffer
->frame_count());
96 // Verify a Reset() takes us back to an uninitialized state.
97 discard_helper
.Reset(0);
98 ASSERT_FALSE(discard_helper
.initialized());
100 // Verify a NULL output buffer returns false.
101 ASSERT_FALSE(discard_helper
.ProcessBuffers(encoded_buffer
, NULL
));
104 TEST(AudioDiscardHelperTest
, NegativeTimestampClampsToZero
) {
105 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
106 ASSERT_FALSE(discard_helper
.initialized());
108 const base::TimeDelta kTimestamp
= -base::TimeDelta::FromSeconds(1);
109 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
110 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
112 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
113 CreateEncodedBuffer(kTimestamp
, kDuration
);
114 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
116 // Verify the basic case where nothing is discarded.
117 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
118 ASSERT_TRUE(discard_helper
.initialized());
119 EXPECT_EQ(base::TimeDelta(), decoded_buffer
->timestamp());
120 EXPECT_EQ(kDuration
, decoded_buffer
->duration());
121 EXPECT_EQ(kTestFrames
, decoded_buffer
->frame_count());
124 TEST(AudioDiscardHelperTest
, ProcessBuffersWithInitialDiscard
) {
125 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
126 ASSERT_FALSE(discard_helper
.initialized());
128 const base::TimeDelta kTimestamp
= base::TimeDelta();
129 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
130 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
132 // Tell the helper we want to discard half of the initial frames.
133 const int kDiscardFrames
= kTestFrames
/ 2;
134 discard_helper
.Reset(kDiscardFrames
);
136 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
137 CreateEncodedBuffer(kTimestamp
, kDuration
);
138 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
140 // Verify half the frames end up discarded.
141 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
142 ASSERT_TRUE(discard_helper
.initialized());
143 EXPECT_EQ(kTimestamp
, decoded_buffer
->timestamp());
144 EXPECT_EQ(kDuration
/ 2, decoded_buffer
->duration());
145 EXPECT_EQ(kDiscardFrames
, decoded_buffer
->frame_count());
146 ASSERT_FLOAT_EQ(kDiscardFrames
* kDataStep
,
147 ExtractDecodedData(decoded_buffer
, 0));
150 TEST(AudioDiscardHelperTest
, ProcessBuffersWithLargeInitialDiscard
) {
151 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
152 ASSERT_FALSE(discard_helper
.initialized());
154 const base::TimeDelta kTimestamp
= base::TimeDelta();
155 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
156 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
158 // Tell the helper we want to discard 1.5 buffers worth of frames.
159 discard_helper
.Reset(kTestFrames
* 1.5);
161 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
162 CreateEncodedBuffer(kTimestamp
, kDuration
);
163 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
165 // The first call should fail since no output buffer remains.
166 ASSERT_FALSE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
167 ASSERT_TRUE(discard_helper
.initialized());
169 // Generate another set of buffers and expect half the output frames.
170 encoded_buffer
= CreateEncodedBuffer(kTimestamp
+ kDuration
, kDuration
);
171 decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
172 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
174 // The timestamp should match that of the initial buffer.
175 const int kDiscardFrames
= kTestFrames
/ 2;
176 EXPECT_EQ(kTimestamp
, decoded_buffer
->timestamp());
177 EXPECT_EQ(kDuration
/ 2, decoded_buffer
->duration());
178 EXPECT_EQ(kDiscardFrames
, decoded_buffer
->frame_count());
179 ASSERT_FLOAT_EQ(kDiscardFrames
* kDataStep
,
180 ExtractDecodedData(decoded_buffer
, 0));
183 TEST(AudioDiscardHelperTest
, AllowNonMonotonicTimestamps
) {
184 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
185 ASSERT_FALSE(discard_helper
.initialized());
187 const base::TimeDelta kTimestamp
= base::TimeDelta();
188 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
189 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
191 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
192 CreateEncodedBuffer(kTimestamp
, kDuration
);
193 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
195 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
196 ASSERT_TRUE(discard_helper
.initialized());
197 EXPECT_EQ(kTimestamp
, decoded_buffer
->timestamp());
198 EXPECT_EQ(kDuration
, decoded_buffer
->duration());
199 EXPECT_EQ(kTestFrames
, decoded_buffer
->frame_count());
201 // Process the same input buffer again to ensure input timestamps which go
202 // backwards in time are not errors.
203 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
204 EXPECT_EQ(kTimestamp
+ kDuration
, decoded_buffer
->timestamp());
205 EXPECT_EQ(kDuration
, decoded_buffer
->duration());
206 EXPECT_EQ(kTestFrames
, decoded_buffer
->frame_count());
209 TEST(AudioDiscardHelperTest
, DiscardEndPadding
) {
210 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
211 ASSERT_FALSE(discard_helper
.initialized());
213 const base::TimeDelta kTimestamp
= base::TimeDelta();
214 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
215 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
217 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
218 CreateEncodedBuffer(kTimestamp
, kDuration
);
219 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
221 // Set a discard padding equivalent to half the buffer.
222 encoded_buffer
->set_discard_padding(
223 std::make_pair(base::TimeDelta(), kDuration
/ 2));
225 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
226 ASSERT_TRUE(discard_helper
.initialized());
227 EXPECT_EQ(kTimestamp
, decoded_buffer
->timestamp());
228 EXPECT_EQ(kDuration
/ 2, decoded_buffer
->duration());
229 EXPECT_EQ(kTestFrames
/ 2, decoded_buffer
->frame_count());
232 TEST(AudioDiscardHelperTest
, BadDiscardEndPadding
) {
233 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
234 ASSERT_FALSE(discard_helper
.initialized());
236 const base::TimeDelta kTimestamp
= base::TimeDelta();
237 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
238 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
240 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
241 CreateEncodedBuffer(kTimestamp
, kDuration
);
242 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
244 // Set a discard padding equivalent to double the buffer size.
245 encoded_buffer
->set_discard_padding(
246 std::make_pair(base::TimeDelta(), kDuration
* 2));
248 // Verify the end discard padding is rejected.
249 ASSERT_FALSE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
250 ASSERT_TRUE(discard_helper
.initialized());
253 TEST(AudioDiscardHelperTest
, InitialDiscardAndDiscardEndPadding
) {
254 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
255 ASSERT_FALSE(discard_helper
.initialized());
257 const base::TimeDelta kTimestamp
= base::TimeDelta();
258 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
259 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
261 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
262 CreateEncodedBuffer(kTimestamp
, kDuration
);
263 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
265 // Set a discard padding equivalent to a quarter of the buffer.
266 encoded_buffer
->set_discard_padding(
267 std::make_pair(base::TimeDelta(), kDuration
/ 4));
269 // Set an initial discard of a quarter of the buffer.
270 const int kDiscardFrames
= kTestFrames
/ 4;
271 discard_helper
.Reset(kDiscardFrames
);
273 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
274 ASSERT_TRUE(discard_helper
.initialized());
275 EXPECT_EQ(kTimestamp
, decoded_buffer
->timestamp());
276 EXPECT_EQ(kDuration
/ 2, decoded_buffer
->duration());
277 EXPECT_EQ(kTestFrames
/ 2, decoded_buffer
->frame_count());
278 ASSERT_FLOAT_EQ(kDiscardFrames
* kDataStep
,
279 ExtractDecodedData(decoded_buffer
, 0));
282 TEST(AudioDiscardHelperTest
, InitialDiscardAndDiscardPadding
) {
283 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
284 ASSERT_FALSE(discard_helper
.initialized());
286 const base::TimeDelta kTimestamp
= base::TimeDelta();
287 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
288 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
290 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
291 CreateEncodedBuffer(kTimestamp
, kDuration
);
292 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
294 // Set all the discard values to be different to ensure each is properly used.
295 const int kDiscardFrames
= kTestFrames
/ 4;
296 encoded_buffer
->set_discard_padding(
297 std::make_pair(kDuration
/ 8, kDuration
/ 16));
298 discard_helper
.Reset(kDiscardFrames
);
300 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
301 ASSERT_TRUE(discard_helper
.initialized());
302 EXPECT_EQ(kTimestamp
, decoded_buffer
->timestamp());
303 EXPECT_EQ(kDuration
- kDuration
/ 4 - kDuration
/ 8 - kDuration
/ 16,
304 decoded_buffer
->duration());
305 EXPECT_EQ(kTestFrames
- kTestFrames
/ 4 - kTestFrames
/ 8 - kTestFrames
/ 16,
306 decoded_buffer
->frame_count());
309 TEST(AudioDiscardHelperTest
, InitialDiscardAndDiscardPaddingAndDecoderDelay
) {
310 // Use a decoder delay of 5ms.
311 const int kDecoderDelay
= kSampleRate
/ 100 / 2;
312 AudioDiscardHelper
discard_helper(kSampleRate
, kDecoderDelay
);
313 ASSERT_FALSE(discard_helper
.initialized());
314 discard_helper
.Reset(kDecoderDelay
);
316 const base::TimeDelta kTimestamp
= base::TimeDelta();
317 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
318 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
320 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
321 CreateEncodedBuffer(kTimestamp
, kDuration
);
322 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
324 // Set a discard padding equivalent to half of the buffer.
325 encoded_buffer
->set_discard_padding(
326 std::make_pair(kDuration
/ 2, base::TimeDelta()));
328 // All of the first buffer should be discarded, half from the inital delay and
329 // another half from the front discard padding.
331 // Encoded Discard Delay
332 // |--------| |---------| |----|
333 // |AAAAAAAA| --> |....|AAAA| --> |AAAA| -------> NULL
334 // |--------| |---------| |----|
335 // Decoded Discard Front Padding
337 ASSERT_FALSE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
338 ASSERT_TRUE(discard_helper
.initialized());
340 // Processing another buffer that has front discard set to half the buffer's
341 // duration should discard the back half of the buffer since kDecoderDelay is
342 // half a buffer. The end padding should not be discarded until another
343 // buffer is processed. kDuration / 4 is chosen for the end discard since it
344 // will force the end discard to start after position zero within the next
347 // Encoded Discard Front Padding (from B)
348 // |--------| |---------| |----|
349 // |BBBBBBBB| --> |AAAA|BBBB| ----------> |AAAA|
350 // |--------| |---------| |----|
352 // (includes carryover from A)
354 encoded_buffer
->set_timestamp(encoded_buffer
->timestamp() + kDuration
);
355 encoded_buffer
->set_discard_padding(
356 std::make_pair(kDuration
/ 2, kDuration
/ 4));
357 decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
358 ASSERT_FLOAT_EQ(0.0f
, ExtractDecodedData(decoded_buffer
, 0));
359 ASSERT_NEAR(kDecoderDelay
* kDataStep
,
360 ExtractDecodedData(decoded_buffer
, kDecoderDelay
),
362 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
363 EXPECT_EQ(kTimestamp
, decoded_buffer
->timestamp());
364 EXPECT_EQ(kDuration
/ 2, decoded_buffer
->duration());
365 EXPECT_EQ(kTestFrames
/ 2, decoded_buffer
->frame_count());
367 // Verify it was actually the latter half of the buffer that was removed.
368 ASSERT_FLOAT_EQ(0.0f
, ExtractDecodedData(decoded_buffer
, 0));
370 // Verify the end discard padding is carried over to the next buffer. Use
371 // kDuration / 2 for the end discard padding so that the next buffer has its
372 // start entirely discarded.
374 // Encoded Discard End Padding (from B)
375 // |--------| |---------| |-------|
376 // |CCCCCCCC| --> |BBBB|CCCC| ----------> |BB|CCCC|
377 // |--------| |---------| |-------|
379 // (includes carryover from B)
381 encoded_buffer
->set_timestamp(encoded_buffer
->timestamp() + kDuration
);
382 encoded_buffer
->set_discard_padding(
383 std::make_pair(base::TimeDelta(), kDuration
/ 2));
384 decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
385 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
386 EXPECT_EQ(kTimestamp
+ kDuration
/ 2, decoded_buffer
->timestamp());
387 EXPECT_EQ(3 * kDuration
/ 4, decoded_buffer
->duration());
388 EXPECT_EQ(3 * kTestFrames
/ 4, decoded_buffer
->frame_count());
390 // Verify it was actually the second quarter of the buffer that was removed.
391 const int kDiscardFrames
= kTestFrames
/ 4;
392 ASSERT_FLOAT_EQ(0.0f
, ExtractDecodedData(decoded_buffer
, 0));
394 kDiscardFrames
* 2 * kDataStep
,
395 ExtractDecodedData(decoded_buffer
, kDecoderDelay
- kDiscardFrames
));
397 // One last test to ensure carryover discard from the start works.
399 // Encoded Discard End Padding (from C)
400 // |--------| |---------| |----|
401 // |DDDDDDDD| --> |CCCC|DDDD| ----------> |DDDD|
402 // |--------| |---------| |----|
404 // (includes carryover from C)
406 encoded_buffer
->set_timestamp(encoded_buffer
->timestamp() + kDuration
);
407 encoded_buffer
->set_discard_padding(DecoderBuffer::DiscardPadding());
408 decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
409 ASSERT_FLOAT_EQ(0.0f
, ExtractDecodedData(decoded_buffer
, 0));
410 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
411 EXPECT_EQ(kTimestamp
+ kDuration
/ 2 + 3 * kDuration
/ 4,
412 decoded_buffer
->timestamp());
413 EXPECT_EQ(kDuration
/ 2, decoded_buffer
->duration());
414 EXPECT_EQ(kTestFrames
/ 2, decoded_buffer
->frame_count());
415 ASSERT_FLOAT_EQ(kTestFrames
/ 2 * kDataStep
,
416 ExtractDecodedData(decoded_buffer
, 0));
419 TEST(AudioDiscardHelperTest
, DelayedDiscardInitialDiscardAndDiscardPadding
) {
420 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
421 ASSERT_FALSE(discard_helper
.initialized());
423 const base::TimeDelta kTimestamp
= base::TimeDelta();
424 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
425 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
427 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
428 CreateEncodedBuffer(kTimestamp
, kDuration
);
430 // Set all the discard values to be different to ensure each is properly used.
431 const int kDiscardFrames
= kTestFrames
/ 4;
432 encoded_buffer
->set_discard_padding(
433 std::make_pair(kDuration
/ 8, kDuration
/ 16));
434 discard_helper
.Reset(kDiscardFrames
);
436 // Verify nothing is output for the first buffer, yet initialized is true.
437 ASSERT_FALSE(discard_helper
.ProcessBuffers(encoded_buffer
, NULL
));
438 ASSERT_TRUE(discard_helper
.initialized());
440 // Create an encoded buffer with no discard padding.
441 encoded_buffer
= CreateEncodedBuffer(kTimestamp
+ kDuration
, kDuration
);
442 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
444 // Verify that when the decoded buffer is consumed, the discards from the
445 // previous encoded buffer are applied.
446 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
447 EXPECT_EQ(kTimestamp
, decoded_buffer
->timestamp());
448 EXPECT_EQ(kDuration
- kDuration
/ 4 - kDuration
/ 8 - kDuration
/ 16,
449 decoded_buffer
->duration());
450 EXPECT_EQ(kTestFrames
- kTestFrames
/ 4 - kTestFrames
/ 8 - kTestFrames
/ 16,
451 decoded_buffer
->frame_count());
454 TEST(AudioDiscardHelperTest
, CompleteDiscard
) {
455 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
456 ASSERT_FALSE(discard_helper
.initialized());
458 const base::TimeDelta kTimestamp
= base::TimeDelta();
459 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
460 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
461 discard_helper
.Reset(0);
463 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
464 CreateEncodedBuffer(kTimestamp
, kDuration
);
465 encoded_buffer
->set_discard_padding(
466 std::make_pair(kInfiniteDuration(), base::TimeDelta()));
467 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
469 // Verify all of the first buffer is discarded.
470 ASSERT_FALSE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
471 ASSERT_TRUE(discard_helper
.initialized());
472 encoded_buffer
->set_timestamp(kTimestamp
+ kDuration
);
473 encoded_buffer
->set_discard_padding(DecoderBuffer::DiscardPadding());
475 // Verify a second buffer goes through untouched.
476 decoded_buffer
= CreateDecodedBuffer(kTestFrames
/ 2);
477 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
478 EXPECT_EQ(kTimestamp
, decoded_buffer
->timestamp());
479 EXPECT_EQ(kDuration
/ 2, decoded_buffer
->duration());
480 EXPECT_EQ(kTestFrames
/ 2, decoded_buffer
->frame_count());
481 ASSERT_FLOAT_EQ(0.0f
, ExtractDecodedData(decoded_buffer
, 0));
484 TEST(AudioDiscardHelperTest
, CompleteDiscardWithDelayedDiscard
) {
485 AudioDiscardHelper
discard_helper(kSampleRate
, 0);
486 ASSERT_FALSE(discard_helper
.initialized());
488 const base::TimeDelta kTimestamp
= base::TimeDelta();
489 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
490 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
491 discard_helper
.Reset(0);
493 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
494 CreateEncodedBuffer(kTimestamp
, kDuration
);
495 encoded_buffer
->set_discard_padding(
496 std::make_pair(kInfiniteDuration(), base::TimeDelta()));
497 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
499 // Setup a delayed discard.
500 ASSERT_FALSE(discard_helper
.ProcessBuffers(encoded_buffer
, NULL
));
501 ASSERT_TRUE(discard_helper
.initialized());
503 // Verify the first output buffer is dropped.
504 encoded_buffer
->set_timestamp(kTimestamp
+ kDuration
);
505 encoded_buffer
->set_discard_padding(DecoderBuffer::DiscardPadding());
506 ASSERT_FALSE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
508 // Verify the second buffer goes through untouched.
509 encoded_buffer
->set_timestamp(kTimestamp
+ 2 * kDuration
);
510 decoded_buffer
= CreateDecodedBuffer(kTestFrames
/ 2);
511 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
512 EXPECT_EQ(kTimestamp
, decoded_buffer
->timestamp());
513 EXPECT_EQ(kDuration
/ 2, decoded_buffer
->duration());
514 EXPECT_EQ(kTestFrames
/ 2, decoded_buffer
->frame_count());
515 ASSERT_FLOAT_EQ(0.0f
, ExtractDecodedData(decoded_buffer
, 0));
518 TEST(AudioDiscardHelperTest
, CompleteDiscardWithInitialDiscardDecoderDelay
) {
519 // Use a decoder delay of 5ms.
520 const int kDecoderDelay
= kSampleRate
/ 100 / 2;
521 AudioDiscardHelper
discard_helper(kSampleRate
, kDecoderDelay
);
522 ASSERT_FALSE(discard_helper
.initialized());
523 discard_helper
.Reset(kDecoderDelay
);
525 const base::TimeDelta kTimestamp
= base::TimeDelta();
526 const base::TimeDelta kDuration
= base::TimeDelta::FromMilliseconds(10);
527 const int kTestFrames
= discard_helper
.TimeDeltaToFrames(kDuration
);
529 scoped_refptr
<DecoderBuffer
> encoded_buffer
=
530 CreateEncodedBuffer(kTimestamp
, kDuration
);
531 encoded_buffer
->set_discard_padding(
532 std::make_pair(kInfiniteDuration(), base::TimeDelta()));
533 scoped_refptr
<AudioBuffer
> decoded_buffer
= CreateDecodedBuffer(kTestFrames
);
535 // Verify all of the first buffer is discarded.
536 ASSERT_FALSE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
537 ASSERT_TRUE(discard_helper
.initialized());
538 encoded_buffer
->set_timestamp(kTimestamp
+ kDuration
);
539 encoded_buffer
->set_discard_padding(DecoderBuffer::DiscardPadding());
541 // Verify 5ms off the front of the second buffer is discarded.
542 decoded_buffer
= CreateDecodedBuffer(kTestFrames
* 2);
543 ASSERT_TRUE(discard_helper
.ProcessBuffers(encoded_buffer
, decoded_buffer
));
544 EXPECT_EQ(kTimestamp
, decoded_buffer
->timestamp());
545 EXPECT_EQ(kDuration
* 2 - kDuration
/ 2, decoded_buffer
->duration());
546 EXPECT_EQ(kTestFrames
* 2 - kDecoderDelay
, decoded_buffer
->frame_count());
547 ASSERT_FLOAT_EQ(kDecoderDelay
* kDataStep
,
548 ExtractDecodedData(decoded_buffer
, 0));