Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / media / base / audio_splicer_unittest.cc
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.
4
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/buffers.h"
11 #include "media/base/test_helpers.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace media {
15
16 // Do not change this format.  AddInput() and GetValue() only work with float.
17 static const SampleFormat kSampleFormat = kSampleFormatF32;
18 COMPILE_ASSERT(kSampleFormat == kSampleFormatF32, invalid_splice_format);
19
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;
24
25 class AudioSplicerTest : public ::testing::Test {
26  public:
27   AudioSplicerTest()
28       : splicer_(kDefaultSampleRate),
29         input_timestamp_helper_(kDefaultSampleRate) {
30     input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta());
31   }
32
33   scoped_refptr<AudioBuffer> GetNextInputBuffer(float value) {
34     return GetNextInputBuffer(value, kDefaultBufferSize);
35   }
36
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;
49   }
50
51   float GetValue(const scoped_refptr<AudioBuffer>& buffer) {
52     return reinterpret_cast<const float*>(buffer->channel_data()[0])[0];
53   }
54
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;
63       }
64     }
65     return true;
66   }
67
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)));
75   }
76
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)));
88   }
89
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());
98
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());
102
103     // The splice timestamp may be adjusted by a microsecond.
104     EXPECT_NEAR(overlapping_buffer->timestamp().InMicroseconds(),
105                 crossfade_output->timestamp().InMicroseconds(),
106                 1);
107
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 && 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;
124       }
125     }
126   }
127
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);
143   }
144
145   base::TimeDelta max_crossfade_duration() {
146     return splicer_.max_crossfade_duration_;
147   }
148
149  protected:
150   AudioSplicer splicer_;
151   AudioTimestampHelper input_timestamp_helper_;
152
153   DISALLOW_COPY_AND_ASSIGN(AudioSplicerTest);
154 };
155
156 TEST_F(AudioSplicerTest, PassThru) {
157   EXPECT_FALSE(splicer_.HasNextBuffer());
158
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());
164
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());
173 }
174
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());
179
180   splicer_.Reset();
181   EXPECT_FALSE(splicer_.HasNextBuffer());
182
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);
188
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());
194 }
195
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());
201
202   EXPECT_TRUE(AddInput(input_1));
203   EXPECT_TRUE(AddInput(input_2));
204
205   VerifyNextBuffer(input_1);
206
207   scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer();
208   EXPECT_FALSE(splicer_.HasNextBuffer());
209   EXPECT_TRUE(output_2->end_of_stream());
210
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());
216 }
217
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);
228
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);
235
236   EXPECT_TRUE(AddInput(input_1));
237   EXPECT_TRUE(AddInput(input_2));
238
239   // Verify that the first input buffer passed through unmodified.
240   VerifyNextBuffer(input_1);
241
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));
253
254   // Verify that the second input buffer passed through unmodified.
255   VerifyNextBuffer(input_2);
256   EXPECT_FALSE(splicer_.HasNextBuffer());
257 }
258
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);
263
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);
269
270   EXPECT_TRUE(AddInput(input_1));
271   EXPECT_FALSE(AddInput(input_2));
272
273   VerifyNextBuffer(input_1);
274
275   // Verify that the second buffer is not available.
276   EXPECT_FALSE(splicer_.HasNextBuffer());
277
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());
282
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());
288 }
289
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);
296
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);
301
302   EXPECT_GT(input_1->timestamp(), input_2->timestamp());
303   EXPECT_TRUE(AddInput(input_1));
304   EXPECT_FALSE(AddInput(input_2));
305 }
306
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);
320
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);
326
327   scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f);
328
329   EXPECT_TRUE(AddInput(input_1));
330   EXPECT_TRUE(AddInput(input_2));
331
332   // Verify that the first input buffer passed through unmodified.
333   VerifyNextBuffer(input_1);
334
335   ASSERT_TRUE(splicer_.HasNextBuffer());
336   scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer();
337   EXPECT_FALSE(splicer_.HasNextBuffer());
338
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)));
348 }
349
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);
367
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);
374
375   scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f, kOverlapSize);
376
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);
382
383   EXPECT_TRUE(AddInput(input_1));
384   EXPECT_TRUE(AddInput(input_2));
385   EXPECT_TRUE(AddInput(input_3));
386
387   VerifyNextBuffer(input_1);
388   VerifyNextBuffer(input_3);
389   EXPECT_FALSE(splicer_.HasNextBuffer());
390 }
391
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;
408
409   scoped_refptr<AudioBuffer> extra_pre_splice_buffer =
410       GetNextInputBuffer(0.2f, kBufferSize);
411   scoped_refptr<AudioBuffer> overlapped_buffer =
412       GetNextInputBuffer(1.0f, kBufferSize);
413
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);
422
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);
427
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());
432
433   // |overlapping_buffer| completes the splice.
434   splicer_.SetSpliceTimestamp(kNoTimestamp());
435   EXPECT_TRUE(AddInput(overlapping_buffer));
436   ASSERT_TRUE(splicer_.HasNextBuffer());
437
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));
442
443   VerifyPreSpliceOutput(overlapped_buffer,
444                         overlapping_buffer,
445                         221,
446                         base::TimeDelta::FromMicroseconds(5011));
447
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);
451
452   VerifyCrossfadeOutput(overlapped_buffer,
453                         NULL,
454                         overlapping_buffer,
455                         0,
456                         kExpectedCrossfadeSize,
457                         base::TimeDelta::FromMicroseconds(4988));
458
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());
468
469   EXPECT_TRUE(VerifyData(post_splice_output, GetValue(overlapping_buffer)));
470
471   VerifyNextBuffer(extra_post_splice_buffer);
472   EXPECT_FALSE(splicer_.HasNextBuffer());
473 }
474
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());
491
492   scoped_refptr<AudioBuffer> overlapped_buffer =
493       GetNextInputBuffer(1.0f, kCrossfadeSize * 2);
494
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);
502
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());
507
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());
513
514   // Now add an EOS buffer which should complete the splice.
515   EXPECT_TRUE(AddInput(AudioBuffer::CreateEOSBuffer()));
516
517   VerifyPreSpliceOutput(overlapped_buffer,
518                         overlapping_buffer,
519                         331,
520                         base::TimeDelta::FromMicroseconds(7505));
521   VerifyCrossfadeOutput(overlapped_buffer,
522                         NULL,
523                         overlapping_buffer,
524                         0,
525                         overlapping_buffer->frame_count(),
526                         overlapping_buffer->duration());
527
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());
532
533   EXPECT_FALSE(splicer_.HasNextBuffer());
534 }
535
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());
552
553   scoped_refptr<AudioBuffer> overlapped_buffer =
554       GetNextInputBuffer(1.0f, kCrossfadeSize / 2);
555
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);
563
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());
568
569   // |overlapping_buffer| completes the splice.
570   splicer_.SetSpliceTimestamp(kNoTimestamp());
571   EXPECT_TRUE(AddInput(overlapping_buffer));
572
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,
583                         0,
584                         kExpectedPreSpliceSize,
585                         kExpectedPreSpliceDuration);
586
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());
596
597   EXPECT_TRUE(VerifyData(post_splice_output, GetValue(overlapping_buffer)));
598   EXPECT_FALSE(splicer_.HasNextBuffer());
599 }
600
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;
616
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);
628
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());
633
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));
638
639   VerifyNextBuffer(first_buffer);
640   VerifyNextBuffer(second_buffer);
641   EXPECT_FALSE(splicer_.HasNextBuffer());
642 }
643
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;
660
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);
668
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);
673
674   // Do not add |gap_buffer|.
675
676   // |second_buffer| will complete the supposed splice.
677   splicer_.SetSpliceTimestamp(kNoTimestamp());
678   EXPECT_TRUE(AddInput(second_buffer));
679
680   VerifyNextBuffer(gap_buffer);
681   VerifyNextBuffer(second_buffer);
682   EXPECT_FALSE(splicer_.HasNextBuffer());
683 }
684
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));
702
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);
710
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);
715
716   // Do not add |gap_buffer|.
717
718   // |second_buffer| will complete the supposed splice.
719   splicer_.SetSpliceTimestamp(kNoTimestamp());
720   EXPECT_FALSE(AddInput(second_buffer));
721 }
722
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;
729
730   scoped_refptr<AudioBuffer> first_buffer =
731       GetNextInputBuffer(1.0f, kBufferSize);
732   EXPECT_TRUE(AddInput(first_buffer));
733   VerifyNextBuffer(first_buffer);
734
735   // Start the splice at a timestamp which has already occurred.
736   splicer_.SetSpliceTimestamp(base::TimeDelta());
737
738   scoped_refptr<AudioBuffer> second_buffer =
739       GetNextInputBuffer(0.5f, kBufferSize);
740   EXPECT_TRUE(AddInput(second_buffer));
741   EXPECT_FALSE(splicer_.HasNextBuffer());
742
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));
751
752   // The second buffer should come through unmodified.
753   VerifyNextBuffer(second_buffer);
754
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)));
765 }
766
767 }  // namespace media