Home | History | Annotate | Download | only in base
      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 }  // namespace media
    724