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
14namespace media {
15
16// Do not change this format.  AddInput() and GetValue() only work with float.
17static const SampleFormat kSampleFormat = kSampleFormatF32;
18COMPILE_ASSERT(kSampleFormat == kSampleFormatF32, invalid_splice_format);
19
20static const int kChannels = 1;
21static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_MONO;
22static const int kDefaultSampleRate = 44100;
23static const int kDefaultBufferSize = 100;
24
25class 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.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;
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
156TEST_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
175TEST_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
196TEST_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// +--------------+----+--------------+
226TEST_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.
261TEST_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.
292TEST_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// +--------------+----------+
318TEST_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// +--------------+-------------+
365TEST_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.
404TEST_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.
488TEST_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.
549TEST_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// +----------+--------------+
613TEST_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// +--------+-+--------------+
656TEST_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.
695TEST_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.
727TEST_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
768