Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / base / audio_splicer_unittest.cc
blob92ab9d2fade83112e1463c4b095065174c997303
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"
14 namespace media {
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 {
26 public:
27 AudioSplicerTest()
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,
40 kChannelLayout,
41 kChannels,
42 kDefaultSampleRate,
43 value,
44 0.0f,
45 frame_size,
46 input_timestamp_helper_.GetTimestamp());
47 input_timestamp_helper_.AddFrames(frame_size);
48 return buffer;
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)
62 return false;
65 return true;
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) {
115 float cf_ratio = 0;
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],
141 input->timestamp());
142 return splicer_.AddInput(buffer_copy);
145 base::TimeDelta max_crossfade_duration() {
146 return splicer_.max_crossfade_duration_;
149 protected:
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());
180 splicer_.Reset();
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().
212 splicer_.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 // +--------------+ +--------------+
222 // Results in:
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
231 // present.
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());
249 EXPECT_NEAR(
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
260 // too large.
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
298 // than |input_1|.
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.
308 // +--------------+
309 // |11111111111111|
310 // +--------------+
311 // +--------------+
312 // |22222222222222|
313 // +--------------+
314 // Results in:
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.
352 // +--------------+
353 // |11111111111111|
354 // +--------------+
355 // +-----+
356 // |22222|
357 // +-----+
358 // +-------------+
359 // |3333333333333|
360 // +-------------+
361 // Results in:
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
378 // |input_1|.
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.
393 // +--------------+
394 // |11111111111111|
395 // +--------------+
396 // +--------------+
397 // |22222222222222|
398 // +--------------+
399 // Results in:
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() -
418 kCrossfadeSize);
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
424 // for output.
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,
444 overlapping_buffer,
445 221,
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,
453 NULL,
454 overlapping_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.
477 // +--------------+
478 // |11111111111111|
479 // +--------------+
480 // +---------++---+
481 // |222222222||EOS|
482 // +---------++---+
483 // Results in:
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,
518 overlapping_buffer,
519 331,
520 base::TimeDelta::FromMicroseconds(7505));
521 VerifyCrossfadeOutput(overlapped_buffer,
522 NULL,
523 overlapping_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.
538 // +------------+
539 // |111111111111|
540 // +------------+
541 // +--------------+
542 // |22222222222222|
543 // +--------------+
544 // Results in:
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,
577 overlapping_buffer,
578 kExpectedPreSpliceSize,
579 kExpectedPreSpliceDuration);
580 VerifyCrossfadeOutput(overlapped_buffer,
581 NULL,
582 overlapping_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
602 // overlap.
603 // +----------+
604 // |1111111111|
605 // +----------+
606 // +--------------+
607 // |22222222222222|
608 // +--------------+
609 // Results in:
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
635 // now available.
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.
646 // +--------+
647 // |11111111|
648 // +--------+
649 // +--------------+
650 // |22222222222222|
651 // +--------------+
652 // Results in:
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
670 // splice.
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
687 // from.
688 // +--------+
689 // |11111111|
690 // +--------+
691 // +------+
692 // |222222|
693 // +------+
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
712 // splice.
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
726 // timestamps.
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
745 // frames.
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()),
763 output->duration());
764 EXPECT_TRUE(VerifyData(output, GetValue(third_buffer)));
767 } // namespace media