1 // Copyright (c) 2012 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_splicer.h"
9 #include "media/base/audio_timestamp_helper.h"
10 #include "media/base/test_helpers.h"
11 #include "media/base/timestamp_constants.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 // Do not change this format. AddInput() and GetValue() only work with float.
17 static const SampleFormat kSampleFormat
= kSampleFormatF32
;
18 static_assert(kSampleFormat
== kSampleFormatF32
, "invalid splice format");
20 static const int kChannels
= 1;
21 static const ChannelLayout kChannelLayout
= CHANNEL_LAYOUT_MONO
;
22 static const int kDefaultSampleRate
= 44100;
23 static const int kDefaultBufferSize
= 100;
25 class AudioSplicerTest
: public ::testing::Test
{
28 : splicer_(kDefaultSampleRate
, new MediaLog()),
29 input_timestamp_helper_(kDefaultSampleRate
) {
30 input_timestamp_helper_
.SetBaseTimestamp(base::TimeDelta());
33 scoped_refptr
<AudioBuffer
> GetNextInputBuffer(float value
) {
34 return GetNextInputBuffer(value
, kDefaultBufferSize
);
37 scoped_refptr
<AudioBuffer
> GetNextInputBuffer(float value
, int frame_size
) {
38 scoped_refptr
<AudioBuffer
> buffer
=
39 MakeAudioBuffer
<float>(kSampleFormat
,
46 input_timestamp_helper_
.GetTimestamp());
47 input_timestamp_helper_
.AddFrames(frame_size
);
51 float GetValue(const scoped_refptr
<AudioBuffer
>& buffer
) {
52 return reinterpret_cast<const float*>(buffer
->channel_data()[0])[0];
55 bool VerifyData(const scoped_refptr
<AudioBuffer
>& buffer
, float value
) {
56 int frames
= buffer
->frame_count();
57 scoped_ptr
<AudioBus
> bus
= AudioBus::Create(kChannels
, frames
);
58 buffer
->ReadFrames(frames
, 0, 0, bus
.get());
59 for (int ch
= 0; ch
< buffer
->channel_count(); ++ch
) {
60 for (int i
= 0; i
< frames
; ++i
) {
61 if (bus
->channel(ch
)[i
] != value
)
68 void VerifyNextBuffer(const scoped_refptr
<AudioBuffer
>& input
) {
69 ASSERT_TRUE(splicer_
.HasNextBuffer());
70 scoped_refptr
<AudioBuffer
> output
= splicer_
.GetNextBuffer();
71 EXPECT_EQ(input
->timestamp(), output
->timestamp());
72 EXPECT_EQ(input
->duration(), output
->duration());
73 EXPECT_EQ(input
->frame_count(), output
->frame_count());
74 EXPECT_TRUE(VerifyData(output
, GetValue(input
)));
77 void VerifyPreSpliceOutput(
78 const scoped_refptr
<AudioBuffer
>& overlapped_buffer
,
79 const scoped_refptr
<AudioBuffer
>& overlapping_buffer
,
80 int expected_pre_splice_size
,
81 base::TimeDelta expected_pre_splice_duration
) {
82 ASSERT_TRUE(splicer_
.HasNextBuffer());
83 scoped_refptr
<AudioBuffer
> pre_splice_output
= splicer_
.GetNextBuffer();
84 EXPECT_EQ(overlapped_buffer
->timestamp(), pre_splice_output
->timestamp());
85 EXPECT_EQ(expected_pre_splice_size
, pre_splice_output
->frame_count());
86 EXPECT_EQ(expected_pre_splice_duration
, pre_splice_output
->duration());
87 EXPECT_TRUE(VerifyData(pre_splice_output
, GetValue(overlapped_buffer
)));
90 void VerifyCrossfadeOutput(
91 const scoped_refptr
<AudioBuffer
>& overlapped_buffer_1
,
92 const scoped_refptr
<AudioBuffer
>& overlapped_buffer_2
,
93 const scoped_refptr
<AudioBuffer
>& overlapping_buffer
,
94 int second_overlap_index
,
95 int expected_crossfade_size
,
96 base::TimeDelta expected_crossfade_duration
) {
97 ASSERT_TRUE(splicer_
.HasNextBuffer());
99 scoped_refptr
<AudioBuffer
> crossfade_output
= splicer_
.GetNextBuffer();
100 EXPECT_EQ(expected_crossfade_size
, crossfade_output
->frame_count());
101 EXPECT_EQ(expected_crossfade_duration
, crossfade_output
->duration());
103 // The splice timestamp may be adjusted by a microsecond.
104 EXPECT_NEAR(overlapping_buffer
->timestamp().InMicroseconds(),
105 crossfade_output
->timestamp().InMicroseconds(),
108 // Verify the actual crossfade.
109 const int frames
= crossfade_output
->frame_count();
110 float overlapped_value
= GetValue(overlapped_buffer_1
);
111 const float overlapping_value
= GetValue(overlapping_buffer
);
112 scoped_ptr
<AudioBus
> bus
= AudioBus::Create(kChannels
, frames
);
113 crossfade_output
->ReadFrames(frames
, 0, 0, bus
.get());
114 for (int ch
= 0; ch
< crossfade_output
->channel_count(); ++ch
) {
116 const float cf_increment
= 1.0f
/ frames
;
117 for (int i
= 0; i
< frames
; ++i
, cf_ratio
+= cf_increment
) {
118 if (overlapped_buffer_2
.get() && i
>= second_overlap_index
)
119 overlapped_value
= GetValue(overlapped_buffer_2
);
120 const float actual
= bus
->channel(ch
)[i
];
121 const float expected
=
122 (1.0f
- cf_ratio
) * overlapped_value
+ cf_ratio
* overlapping_value
;
123 ASSERT_FLOAT_EQ(expected
, actual
) << "i=" << i
;
128 bool AddInput(const scoped_refptr
<AudioBuffer
>& input
) {
129 // Since the splicer doesn't make copies it's working directly on the input
130 // buffers. We must make a copy before adding to ensure the original buffer
131 // is not modified in unexpected ways.
132 scoped_refptr
<AudioBuffer
> buffer_copy
=
133 input
->end_of_stream()
134 ? AudioBuffer::CreateEOSBuffer()
135 : AudioBuffer::CopyFrom(kSampleFormat
,
136 input
->channel_layout(),
137 input
->channel_count(),
138 input
->sample_rate(),
139 input
->frame_count(),
140 &input
->channel_data()[0],
142 return splicer_
.AddInput(buffer_copy
);
145 base::TimeDelta
max_crossfade_duration() {
146 return splicer_
.max_crossfade_duration_
;
150 AudioSplicer splicer_
;
151 AudioTimestampHelper input_timestamp_helper_
;
153 DISALLOW_COPY_AND_ASSIGN(AudioSplicerTest
);
156 TEST_F(AudioSplicerTest
, PassThru
) {
157 EXPECT_FALSE(splicer_
.HasNextBuffer());
159 // Test single buffer pass-thru behavior.
160 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
161 EXPECT_TRUE(AddInput(input_1
));
162 VerifyNextBuffer(input_1
);
163 EXPECT_FALSE(splicer_
.HasNextBuffer());
165 // Test that multiple buffers can be queued in the splicer.
166 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.2f
);
167 scoped_refptr
<AudioBuffer
> input_3
= GetNextInputBuffer(0.3f
);
168 EXPECT_TRUE(AddInput(input_2
));
169 EXPECT_TRUE(AddInput(input_3
));
170 VerifyNextBuffer(input_2
);
171 VerifyNextBuffer(input_3
);
172 EXPECT_FALSE(splicer_
.HasNextBuffer());
175 TEST_F(AudioSplicerTest
, Reset
) {
176 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
177 EXPECT_TRUE(AddInput(input_1
));
178 ASSERT_TRUE(splicer_
.HasNextBuffer());
181 EXPECT_FALSE(splicer_
.HasNextBuffer());
183 // Add some bytes to the timestamp helper so that the
184 // next buffer starts many frames beyond the end of
185 // |input_1|. This is to make sure that Reset() actually
186 // clears its state and doesn't try to insert a gap.
187 input_timestamp_helper_
.AddFrames(100);
189 // Verify that a new input buffer passes through as expected.
190 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.2f
);
191 EXPECT_TRUE(AddInput(input_2
));
192 VerifyNextBuffer(input_2
);
193 EXPECT_FALSE(splicer_
.HasNextBuffer());
196 TEST_F(AudioSplicerTest
, EndOfStream
) {
197 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
198 scoped_refptr
<AudioBuffer
> input_2
= AudioBuffer::CreateEOSBuffer();
199 scoped_refptr
<AudioBuffer
> input_3
= GetNextInputBuffer(0.2f
);
200 EXPECT_TRUE(input_2
->end_of_stream());
202 EXPECT_TRUE(AddInput(input_1
));
203 EXPECT_TRUE(AddInput(input_2
));
205 VerifyNextBuffer(input_1
);
207 scoped_refptr
<AudioBuffer
> output_2
= splicer_
.GetNextBuffer();
208 EXPECT_FALSE(splicer_
.HasNextBuffer());
209 EXPECT_TRUE(output_2
->end_of_stream());
211 // Verify that buffers can be added again after Reset().
213 EXPECT_TRUE(AddInput(input_3
));
214 VerifyNextBuffer(input_3
);
215 EXPECT_FALSE(splicer_
.HasNextBuffer());
218 // Test the gap insertion code.
219 // +--------------+ +--------------+
220 // |11111111111111| |22222222222222|
221 // +--------------+ +--------------+
223 // +--------------+----+--------------+
224 // |11111111111111|0000|22222222222222|
225 // +--------------+----+--------------+
226 TEST_F(AudioSplicerTest
, GapInsertion
) {
227 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
229 // Add bytes to the timestamp helper so that the next buffer
230 // will have a starting timestamp that indicates a gap is
232 const int kGapSize
= 7;
233 input_timestamp_helper_
.AddFrames(kGapSize
);
234 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.2f
);
236 EXPECT_TRUE(AddInput(input_1
));
237 EXPECT_TRUE(AddInput(input_2
));
239 // Verify that the first input buffer passed through unmodified.
240 VerifyNextBuffer(input_1
);
242 // Verify the contents of the gap buffer.
243 scoped_refptr
<AudioBuffer
> output_2
= splicer_
.GetNextBuffer();
244 base::TimeDelta gap_timestamp
=
245 input_1
->timestamp() + input_1
->duration();
246 base::TimeDelta gap_duration
= input_2
->timestamp() - gap_timestamp
;
247 EXPECT_GT(gap_duration
, base::TimeDelta());
248 EXPECT_EQ(gap_timestamp
, output_2
->timestamp());
250 gap_duration
.InMicroseconds(), output_2
->duration().InMicroseconds(), 1);
251 EXPECT_EQ(kGapSize
, output_2
->frame_count());
252 EXPECT_TRUE(VerifyData(output_2
, 0.0f
));
254 // Verify that the second input buffer passed through unmodified.
255 VerifyNextBuffer(input_2
);
256 EXPECT_FALSE(splicer_
.HasNextBuffer());
259 // Test that an error is signalled when the gap between input buffers is
261 TEST_F(AudioSplicerTest
, GapTooLarge
) {
262 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
264 // Add a seconds worth of bytes so that an unacceptably large
265 // gap exists between |input_1| and |input_2|.
266 const int kGapSize
= kDefaultSampleRate
;
267 input_timestamp_helper_
.AddFrames(kGapSize
);
268 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.2f
);
270 EXPECT_TRUE(AddInput(input_1
));
271 EXPECT_FALSE(AddInput(input_2
));
273 VerifyNextBuffer(input_1
);
275 // Verify that the second buffer is not available.
276 EXPECT_FALSE(splicer_
.HasNextBuffer());
278 // Reset the timestamp helper so it can generate a buffer that is
279 // right after |input_1|.
280 input_timestamp_helper_
.SetBaseTimestamp(
281 input_1
->timestamp() + input_1
->duration());
283 // Verify that valid buffers are still accepted.
284 scoped_refptr
<AudioBuffer
> input_3
= GetNextInputBuffer(0.3f
);
285 EXPECT_TRUE(AddInput(input_3
));
286 VerifyNextBuffer(input_3
);
287 EXPECT_FALSE(splicer_
.HasNextBuffer());
290 // Verifies that an error is signalled if AddInput() is called
291 // with a timestamp that is earlier than the first buffer added.
292 TEST_F(AudioSplicerTest
, BufferAddedBeforeBase
) {
293 input_timestamp_helper_
.SetBaseTimestamp(
294 base::TimeDelta::FromMicroseconds(10));
295 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
297 // Reset the timestamp helper so the next buffer will have a timestamp earlier
299 input_timestamp_helper_
.SetBaseTimestamp(base::TimeDelta::FromSeconds(0));
300 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.1f
);
302 EXPECT_GT(input_1
->timestamp(), input_2
->timestamp());
303 EXPECT_TRUE(AddInput(input_1
));
304 EXPECT_FALSE(AddInput(input_2
));
307 // Test when one buffer partially overlaps another.
315 // +--------------+----------+
316 // |11111111111111|2222222222|
317 // +--------------+----------+
318 TEST_F(AudioSplicerTest
, PartialOverlap
) {
319 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
321 // Reset timestamp helper so that the next buffer will have a
322 // timestamp that starts in the middle of |input_1|.
323 const int kOverlapSize
= input_1
->frame_count() / 4;
324 input_timestamp_helper_
.SetBaseTimestamp(input_1
->timestamp());
325 input_timestamp_helper_
.AddFrames(input_1
->frame_count() - kOverlapSize
);
327 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.2f
);
329 EXPECT_TRUE(AddInput(input_1
));
330 EXPECT_TRUE(AddInput(input_2
));
332 // Verify that the first input buffer passed through unmodified.
333 VerifyNextBuffer(input_1
);
335 ASSERT_TRUE(splicer_
.HasNextBuffer());
336 scoped_refptr
<AudioBuffer
> output_2
= splicer_
.GetNextBuffer();
337 EXPECT_FALSE(splicer_
.HasNextBuffer());
339 // Verify that the second input buffer was truncated to only contain
340 // the samples that are after the end of |input_1|.
341 base::TimeDelta expected_timestamp
=
342 input_1
->timestamp() + input_1
->duration();
343 base::TimeDelta expected_duration
=
344 (input_2
->timestamp() + input_2
->duration()) - expected_timestamp
;
345 EXPECT_EQ(expected_timestamp
, output_2
->timestamp());
346 EXPECT_EQ(expected_duration
, output_2
->duration());
347 EXPECT_TRUE(VerifyData(output_2
, GetValue(input_2
)));
350 // Test that an input buffer that is completely overlapped by a buffer
351 // that was already added is dropped.
362 // +--------------+-------------+
363 // |11111111111111|3333333333333|
364 // +--------------+-------------+
365 TEST_F(AudioSplicerTest
, DropBuffer
) {
366 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
368 // Reset timestamp helper so that the next buffer will have a
369 // timestamp that starts in the middle of |input_1|.
370 const int kOverlapOffset
= input_1
->frame_count() / 2;
371 const int kOverlapSize
= input_1
->frame_count() / 4;
372 input_timestamp_helper_
.SetBaseTimestamp(input_1
->timestamp());
373 input_timestamp_helper_
.AddFrames(kOverlapOffset
);
375 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.2f
, kOverlapSize
);
377 // Reset the timestamp helper so the next buffer will be right after
379 input_timestamp_helper_
.SetBaseTimestamp(input_1
->timestamp());
380 input_timestamp_helper_
.AddFrames(input_1
->frame_count());
381 scoped_refptr
<AudioBuffer
> input_3
= GetNextInputBuffer(0.3f
);
383 EXPECT_TRUE(AddInput(input_1
));
384 EXPECT_TRUE(AddInput(input_2
));
385 EXPECT_TRUE(AddInput(input_3
));
387 VerifyNextBuffer(input_1
);
388 VerifyNextBuffer(input_3
);
389 EXPECT_FALSE(splicer_
.HasNextBuffer());
392 // Test crossfade when one buffer partially overlaps another.
400 // +----------+----+----------+
401 // |1111111111|xxxx|2222222222|
402 // +----------+----+----------+
403 // Where "xxxx" represents the crossfaded portion of the signal.
404 TEST_F(AudioSplicerTest
, PartialOverlapCrossfade
) {
405 const int kCrossfadeSize
=
406 input_timestamp_helper_
.GetFramesToTarget(max_crossfade_duration());
407 const int kBufferSize
= kCrossfadeSize
* 2;
409 scoped_refptr
<AudioBuffer
> extra_pre_splice_buffer
=
410 GetNextInputBuffer(0.2f
, kBufferSize
);
411 scoped_refptr
<AudioBuffer
> overlapped_buffer
=
412 GetNextInputBuffer(1.0f
, kBufferSize
);
414 // Reset timestamp helper so that the next buffer will have a timestamp that
415 // starts in the middle of |overlapped_buffer|.
416 input_timestamp_helper_
.SetBaseTimestamp(overlapped_buffer
->timestamp());
417 input_timestamp_helper_
.AddFrames(overlapped_buffer
->frame_count() -
419 splicer_
.SetSpliceTimestamp(input_timestamp_helper_
.GetTimestamp());
420 scoped_refptr
<AudioBuffer
> overlapping_buffer
=
421 GetNextInputBuffer(0.0f
, kBufferSize
);
423 // |extra_pre_splice_buffer| is entirely before the splice and should be ready
425 EXPECT_TRUE(AddInput(extra_pre_splice_buffer
));
426 VerifyNextBuffer(extra_pre_splice_buffer
);
428 // The splicer should be internally queuing input since |overlapped_buffer| is
429 // part of the splice.
430 EXPECT_TRUE(AddInput(overlapped_buffer
));
431 EXPECT_FALSE(splicer_
.HasNextBuffer());
433 // |overlapping_buffer| completes the splice.
434 splicer_
.SetSpliceTimestamp(kNoTimestamp());
435 EXPECT_TRUE(AddInput(overlapping_buffer
));
436 ASSERT_TRUE(splicer_
.HasNextBuffer());
438 // Add one more buffer to make sure it's passed through untouched.
439 scoped_refptr
<AudioBuffer
> extra_post_splice_buffer
=
440 GetNextInputBuffer(0.5f
, kBufferSize
);
441 EXPECT_TRUE(AddInput(extra_post_splice_buffer
));
443 VerifyPreSpliceOutput(overlapped_buffer
,
446 base::TimeDelta::FromMicroseconds(5011));
448 // Due to rounding the crossfade size may vary by up to a frame.
449 const int kExpectedCrossfadeSize
= 220;
450 EXPECT_NEAR(kExpectedCrossfadeSize
, kCrossfadeSize
, 1);
452 VerifyCrossfadeOutput(overlapped_buffer
,
456 kExpectedCrossfadeSize
,
457 base::TimeDelta::FromMicroseconds(4988));
459 // Retrieve the remaining portion after crossfade.
460 ASSERT_TRUE(splicer_
.HasNextBuffer());
461 scoped_refptr
<AudioBuffer
> post_splice_output
= splicer_
.GetNextBuffer();
462 EXPECT_EQ(base::TimeDelta::FromMicroseconds(20022),
463 post_splice_output
->timestamp());
464 EXPECT_EQ(overlapping_buffer
->frame_count() - kExpectedCrossfadeSize
,
465 post_splice_output
->frame_count());
466 EXPECT_EQ(base::TimeDelta::FromMicroseconds(5034),
467 post_splice_output
->duration());
469 EXPECT_TRUE(VerifyData(post_splice_output
, GetValue(overlapping_buffer
)));
471 VerifyNextBuffer(extra_post_splice_buffer
);
472 EXPECT_FALSE(splicer_
.HasNextBuffer());
475 // Test crossfade when one buffer partially overlaps another, but an end of
476 // stream buffer is received before the crossfade duration is reached.
484 // +----------+----+----++---+
485 // |1111111111|xxxx|2222||EOS|
486 // +----------+----+----++---+
487 // Where "x" represents the crossfaded portion of the signal.
488 TEST_F(AudioSplicerTest
, PartialOverlapCrossfadeEndOfStream
) {
489 const int kCrossfadeSize
=
490 input_timestamp_helper_
.GetFramesToTarget(max_crossfade_duration());
492 scoped_refptr
<AudioBuffer
> overlapped_buffer
=
493 GetNextInputBuffer(1.0f
, kCrossfadeSize
* 2);
495 // Reset timestamp helper so that the next buffer will have a timestamp that
496 // starts 3/4 of the way into |overlapped_buffer|.
497 input_timestamp_helper_
.SetBaseTimestamp(overlapped_buffer
->timestamp());
498 input_timestamp_helper_
.AddFrames(3 * overlapped_buffer
->frame_count() / 4);
499 splicer_
.SetSpliceTimestamp(input_timestamp_helper_
.GetTimestamp());
500 scoped_refptr
<AudioBuffer
> overlapping_buffer
=
501 GetNextInputBuffer(0.0f
, kCrossfadeSize
/ 3);
503 // The splicer should be internally queuing input since |overlapped_buffer| is
504 // part of the splice.
505 EXPECT_TRUE(AddInput(overlapped_buffer
));
506 EXPECT_FALSE(splicer_
.HasNextBuffer());
508 // |overlapping_buffer| should not have enough data to complete the splice, so
509 // ensure output is not available.
510 splicer_
.SetSpliceTimestamp(kNoTimestamp());
511 EXPECT_TRUE(AddInput(overlapping_buffer
));
512 EXPECT_FALSE(splicer_
.HasNextBuffer());
514 // Now add an EOS buffer which should complete the splice.
515 EXPECT_TRUE(AddInput(AudioBuffer::CreateEOSBuffer()));
517 VerifyPreSpliceOutput(overlapped_buffer
,
520 base::TimeDelta::FromMicroseconds(7505));
521 VerifyCrossfadeOutput(overlapped_buffer
,
525 overlapping_buffer
->frame_count(),
526 overlapping_buffer
->duration());
528 // Ensure the last buffer is an EOS buffer.
529 ASSERT_TRUE(splicer_
.HasNextBuffer());
530 scoped_refptr
<AudioBuffer
> post_splice_output
= splicer_
.GetNextBuffer();
531 EXPECT_TRUE(post_splice_output
->end_of_stream());
533 EXPECT_FALSE(splicer_
.HasNextBuffer());
536 // Test crossfade when one buffer partially overlaps another, but the amount of
537 // overlapped data is less than the crossfade duration.
545 // +----------+-+------------+
546 // |1111111111|x|222222222222|
547 // +----------+-+------------+
548 // Where "x" represents the crossfaded portion of the signal.
549 TEST_F(AudioSplicerTest
, PartialOverlapCrossfadeShortPreSplice
) {
550 const int kCrossfadeSize
=
551 input_timestamp_helper_
.GetFramesToTarget(max_crossfade_duration());
553 scoped_refptr
<AudioBuffer
> overlapped_buffer
=
554 GetNextInputBuffer(1.0f
, kCrossfadeSize
/ 2);
556 // Reset timestamp helper so that the next buffer will have a timestamp that
557 // starts in the middle of |overlapped_buffer|.
558 input_timestamp_helper_
.SetBaseTimestamp(overlapped_buffer
->timestamp());
559 input_timestamp_helper_
.AddFrames(overlapped_buffer
->frame_count() / 2);
560 splicer_
.SetSpliceTimestamp(input_timestamp_helper_
.GetTimestamp());
561 scoped_refptr
<AudioBuffer
> overlapping_buffer
=
562 GetNextInputBuffer(0.0f
, kCrossfadeSize
* 2);
564 // The splicer should be internally queuing input since |overlapped_buffer| is
565 // part of the splice.
566 EXPECT_TRUE(AddInput(overlapped_buffer
));
567 EXPECT_FALSE(splicer_
.HasNextBuffer());
569 // |overlapping_buffer| completes the splice.
570 splicer_
.SetSpliceTimestamp(kNoTimestamp());
571 EXPECT_TRUE(AddInput(overlapping_buffer
));
573 const int kExpectedPreSpliceSize
= 55;
574 const base::TimeDelta kExpectedPreSpliceDuration
=
575 base::TimeDelta::FromMicroseconds(1247);
576 VerifyPreSpliceOutput(overlapped_buffer
,
578 kExpectedPreSpliceSize
,
579 kExpectedPreSpliceDuration
);
580 VerifyCrossfadeOutput(overlapped_buffer
,
584 kExpectedPreSpliceSize
,
585 kExpectedPreSpliceDuration
);
587 // Retrieve the remaining portion after crossfade.
588 ASSERT_TRUE(splicer_
.HasNextBuffer());
589 scoped_refptr
<AudioBuffer
> post_splice_output
= splicer_
.GetNextBuffer();
590 EXPECT_EQ(overlapping_buffer
->timestamp() + kExpectedPreSpliceDuration
,
591 post_splice_output
->timestamp());
592 EXPECT_EQ(overlapping_buffer
->frame_count() - kExpectedPreSpliceSize
,
593 post_splice_output
->frame_count());
594 EXPECT_EQ(overlapping_buffer
->duration() - kExpectedPreSpliceDuration
,
595 post_splice_output
->duration());
597 EXPECT_TRUE(VerifyData(post_splice_output
, GetValue(overlapping_buffer
)));
598 EXPECT_FALSE(splicer_
.HasNextBuffer());
601 // Test behavior when a splice frame is incorrectly marked and does not actually
610 // +----------+--------------+
611 // |1111111111|22222222222222|
612 // +----------+--------------+
613 TEST_F(AudioSplicerTest
, IncorrectlyMarkedSplice
) {
614 const int kBufferSize
=
615 input_timestamp_helper_
.GetFramesToTarget(max_crossfade_duration()) * 2;
617 scoped_refptr
<AudioBuffer
> first_buffer
=
618 GetNextInputBuffer(1.0f
, kBufferSize
);
619 // Fuzz the duration slightly so that the buffer overlaps the splice timestamp
620 // by a microsecond, which is not enough to crossfade.
621 const base::TimeDelta kSpliceTimestamp
=
622 input_timestamp_helper_
.GetTimestamp() -
623 base::TimeDelta::FromMicroseconds(1);
624 splicer_
.SetSpliceTimestamp(kSpliceTimestamp
);
625 scoped_refptr
<AudioBuffer
> second_buffer
=
626 GetNextInputBuffer(0.0f
, kBufferSize
);
627 second_buffer
->set_timestamp(kSpliceTimestamp
);
629 // The splicer should be internally queuing input since |first_buffer| is part
630 // of the supposed splice.
631 EXPECT_TRUE(AddInput(first_buffer
));
632 EXPECT_FALSE(splicer_
.HasNextBuffer());
634 // |second_buffer| should complete the supposed splice, so ensure output is
636 splicer_
.SetSpliceTimestamp(kNoTimestamp());
637 EXPECT_TRUE(AddInput(second_buffer
));
639 VerifyNextBuffer(first_buffer
);
640 VerifyNextBuffer(second_buffer
);
641 EXPECT_FALSE(splicer_
.HasNextBuffer());
644 // Test behavior when a splice frame is incorrectly marked and there is a gap
645 // between whats in the pre splice and post splice.
653 // +--------+-+--------------+
654 // |11111111|0|22222222222222|
655 // +--------+-+--------------+
656 TEST_F(AudioSplicerTest
, IncorrectlyMarkedSpliceWithGap
) {
657 const int kBufferSize
=
658 input_timestamp_helper_
.GetFramesToTarget(max_crossfade_duration()) * 2;
659 const int kGapSize
= 2;
661 scoped_refptr
<AudioBuffer
> first_buffer
=
662 GetNextInputBuffer(1.0f
, kBufferSize
- kGapSize
);
663 scoped_refptr
<AudioBuffer
> gap_buffer
=
664 GetNextInputBuffer(0.0f
, kGapSize
);
665 splicer_
.SetSpliceTimestamp(input_timestamp_helper_
.GetTimestamp());
666 scoped_refptr
<AudioBuffer
> second_buffer
=
667 GetNextInputBuffer(0.0f
, kBufferSize
);
669 // The splicer should pass through the first buffer since it's not part of the
671 EXPECT_TRUE(AddInput(first_buffer
));
672 VerifyNextBuffer(first_buffer
);
674 // Do not add |gap_buffer|.
676 // |second_buffer| will complete the supposed splice.
677 splicer_
.SetSpliceTimestamp(kNoTimestamp());
678 EXPECT_TRUE(AddInput(second_buffer
));
680 VerifyNextBuffer(gap_buffer
);
681 VerifyNextBuffer(second_buffer
);
682 EXPECT_FALSE(splicer_
.HasNextBuffer());
685 // Test behavior when a splice frame is incorrectly marked and there is a gap
686 // between what's in the pre splice and post splice that is too large to recover
694 // Results in an error and not a crash.
695 TEST_F(AudioSplicerTest
, IncorrectlyMarkedSpliceWithBadGap
) {
696 const int kBufferSize
=
697 input_timestamp_helper_
.GetFramesToTarget(max_crossfade_duration()) * 2;
698 const int kGapSize
= kBufferSize
+
699 input_timestamp_helper_
.GetFramesToTarget(
700 base::TimeDelta::FromMilliseconds(
701 AudioSplicer::kMaxTimeDeltaInMilliseconds
+ 1));
703 scoped_refptr
<AudioBuffer
> first_buffer
=
704 GetNextInputBuffer(1.0f
, kBufferSize
);
705 scoped_refptr
<AudioBuffer
> gap_buffer
=
706 GetNextInputBuffer(0.0f
, kGapSize
);
707 splicer_
.SetSpliceTimestamp(input_timestamp_helper_
.GetTimestamp());
708 scoped_refptr
<AudioBuffer
> second_buffer
=
709 GetNextInputBuffer(0.0f
, kBufferSize
);
711 // The splicer should pass through the first buffer since it's not part of the
713 EXPECT_TRUE(AddInput(first_buffer
));
714 VerifyNextBuffer(first_buffer
);
716 // Do not add |gap_buffer|.
718 // |second_buffer| will complete the supposed splice.
719 splicer_
.SetSpliceTimestamp(kNoTimestamp());
720 EXPECT_FALSE(AddInput(second_buffer
));
723 // Ensure we don't crash when a splice frame is incorrectly marked such that the
724 // splice timestamp has already passed when SetSpliceTimestamp() is called.
725 // This can happen if the encoded timestamps are too far behind the decoded
727 TEST_F(AudioSplicerTest
, IncorrectlyMarkedPastSplice
) {
728 const int kBufferSize
= 200;
730 scoped_refptr
<AudioBuffer
> first_buffer
=
731 GetNextInputBuffer(1.0f
, kBufferSize
);
732 EXPECT_TRUE(AddInput(first_buffer
));
733 VerifyNextBuffer(first_buffer
);
735 // Start the splice at a timestamp which has already occurred.
736 splicer_
.SetSpliceTimestamp(base::TimeDelta());
738 scoped_refptr
<AudioBuffer
> second_buffer
=
739 GetNextInputBuffer(0.5f
, kBufferSize
);
740 EXPECT_TRUE(AddInput(second_buffer
));
741 EXPECT_FALSE(splicer_
.HasNextBuffer());
743 // |third_buffer| will complete the supposed splice. The buffer size is set
744 // such that unchecked the splicer would try to trim off a negative number of
746 splicer_
.SetSpliceTimestamp(kNoTimestamp());
747 scoped_refptr
<AudioBuffer
> third_buffer
=
748 GetNextInputBuffer(0.0f
, kBufferSize
* 10);
749 third_buffer
->set_timestamp(base::TimeDelta());
750 EXPECT_TRUE(AddInput(third_buffer
));
752 // The second buffer should come through unmodified.
753 VerifyNextBuffer(second_buffer
);
755 // The third buffer should be partially dropped since it overlaps the second.
756 ASSERT_TRUE(splicer_
.HasNextBuffer());
757 const base::TimeDelta second_buffer_end_ts
=
758 second_buffer
->timestamp() + second_buffer
->duration();
759 scoped_refptr
<AudioBuffer
> output
= splicer_
.GetNextBuffer();
760 EXPECT_EQ(second_buffer_end_ts
, output
->timestamp());
761 EXPECT_EQ(third_buffer
->duration() -
762 (second_buffer_end_ts
- third_buffer
->timestamp()),
764 EXPECT_TRUE(VerifyData(output
, GetValue(third_buffer
)));