// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cobalt/media/base/audio_splicer.h"

#include <memory>

#include "base/basictypes.h"
#include "cobalt/media/base/audio_buffer.h"
#include "cobalt/media/base/audio_bus.h"
#include "cobalt/media/base/audio_timestamp_helper.h"
#include "cobalt/media/base/test_helpers.h"
#include "cobalt/media/base/timestamp_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

// Do not change this format.  AddInput() and GetValue() only work with float.
static const SampleFormat kSampleFormat = kSampleFormatF32;
static_assert(kSampleFormat == kSampleFormatF32, "invalid splice format");

static const int kChannels = 1;
static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_MONO;
static const int kDefaultSampleRate = 44100;
static const int kDefaultBufferSize = 100;

class AudioSplicerTest : public ::testing::Test {
 public:
  AudioSplicerTest()
      : splicer_(kDefaultSampleRate, new MediaLog()),
        input_timestamp_helper_(kDefaultSampleRate) {
    input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta());
  }

  scoped_refptr<AudioBuffer> GetNextInputBuffer(float value) {
    return GetNextInputBuffer(value, kDefaultBufferSize);
  }

  scoped_refptr<AudioBuffer> GetNextInputBuffer(float value, int frame_size) {
    scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<float>(
        kSampleFormat, kChannelLayout, kChannels, kDefaultSampleRate, value,
        0.0f, frame_size, input_timestamp_helper_.GetTimestamp());
    input_timestamp_helper_.AddFrames(frame_size);
    return buffer;
  }

  float GetValue(const scoped_refptr<AudioBuffer>& buffer) {
    return reinterpret_cast<const float*>(buffer->channel_data()[0])[0];
  }

  bool VerifyData(const scoped_refptr<AudioBuffer>& buffer, float value) {
    int frames = buffer->frame_count();
    std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, frames);
    buffer->ReadFrames(frames, 0, 0, bus.get());
    for (int ch = 0; ch < buffer->channel_count(); ++ch) {
      for (int i = 0; i < frames; ++i) {
        if (bus->channel(ch)[i] != value) return false;
      }
    }
    return true;
  }

  void VerifyNextBuffer(const scoped_refptr<AudioBuffer>& input) {
    ASSERT_TRUE(splicer_.HasNextBuffer());
    scoped_refptr<AudioBuffer> output = splicer_.GetNextBuffer();
    EXPECT_EQ(input->timestamp(), output->timestamp());
    EXPECT_EQ(input->duration(), output->duration());
    EXPECT_EQ(input->frame_count(), output->frame_count());
    EXPECT_TRUE(VerifyData(output, GetValue(input)));
  }

  void VerifyPreSpliceOutput(
      const scoped_refptr<AudioBuffer>& overlapped_buffer,
      const scoped_refptr<AudioBuffer>& overlapping_buffer,
      int expected_pre_splice_size,
      base::TimeDelta expected_pre_splice_duration) {
    ASSERT_TRUE(splicer_.HasNextBuffer());
    scoped_refptr<AudioBuffer> pre_splice_output = splicer_.GetNextBuffer();
    EXPECT_EQ(overlapped_buffer->timestamp(), pre_splice_output->timestamp());
    EXPECT_EQ(expected_pre_splice_size, pre_splice_output->frame_count());
    EXPECT_EQ(expected_pre_splice_duration, pre_splice_output->duration());
    EXPECT_TRUE(VerifyData(pre_splice_output, GetValue(overlapped_buffer)));
  }

  void VerifyCrossfadeOutput(
      const scoped_refptr<AudioBuffer>& overlapped_buffer_1,
      const scoped_refptr<AudioBuffer>& overlapped_buffer_2,
      const scoped_refptr<AudioBuffer>& overlapping_buffer,
      int second_overlap_index, int expected_crossfade_size,
      base::TimeDelta expected_crossfade_duration) {
    ASSERT_TRUE(splicer_.HasNextBuffer());

    scoped_refptr<AudioBuffer> crossfade_output = splicer_.GetNextBuffer();
    EXPECT_EQ(expected_crossfade_size, crossfade_output->frame_count());
    EXPECT_EQ(expected_crossfade_duration, crossfade_output->duration());

    // The splice timestamp may be adjusted by a microsecond.
    EXPECT_NEAR(overlapping_buffer->timestamp().InMicroseconds(),
                crossfade_output->timestamp().InMicroseconds(), 1);

    // Verify the actual crossfade.
    const int frames = crossfade_output->frame_count();
    float overlapped_value = GetValue(overlapped_buffer_1);
    const float overlapping_value = GetValue(overlapping_buffer);
    std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, frames);
    crossfade_output->ReadFrames(frames, 0, 0, bus.get());
    for (int ch = 0; ch < crossfade_output->channel_count(); ++ch) {
      float cf_ratio = 0;
      const float cf_increment = 1.0f / frames;
      for (int i = 0; i < frames; ++i, cf_ratio += cf_increment) {
        if (overlapped_buffer_2.get() && i >= second_overlap_index)
          overlapped_value = GetValue(overlapped_buffer_2);
        const float actual = bus->channel(ch)[i];
        const float expected =
            (1.0f - cf_ratio) * overlapped_value + cf_ratio * overlapping_value;
        ASSERT_FLOAT_EQ(expected, actual) << "i=" << i;
      }
    }
  }

  bool AddInput(const scoped_refptr<AudioBuffer>& input) {
    // Since the splicer doesn't make copies it's working directly on the input
    // buffers.  We must make a copy before adding to ensure the original buffer
    // is not modified in unexpected ways.
    scoped_refptr<AudioBuffer> buffer_copy =
        input->end_of_stream()
            ? AudioBuffer::CreateEOSBuffer()
            : AudioBuffer::CopyFrom(kSampleFormat, input->channel_layout(),
                                    input->channel_count(),
                                    input->sample_rate(), input->frame_count(),
                                    &input->channel_data()[0],
                                    input->timestamp());
    return splicer_.AddInput(buffer_copy);
  }

  base::TimeDelta max_crossfade_duration() {
    return splicer_.max_crossfade_duration_;
  }

 protected:
  AudioSplicer splicer_;
  AudioTimestampHelper input_timestamp_helper_;

 private:
  DISALLOW_COPY_AND_ASSIGN(AudioSplicerTest);
};

TEST_F(AudioSplicerTest, PassThru) {
  EXPECT_FALSE(splicer_.HasNextBuffer());

  // Test single buffer pass-thru behavior.
  scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f);
  EXPECT_TRUE(AddInput(input_1));
  VerifyNextBuffer(input_1);
  EXPECT_FALSE(splicer_.HasNextBuffer());

  // Test that multiple buffers can be queued in the splicer.
  scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f);
  scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f);
  EXPECT_TRUE(AddInput(input_2));
  EXPECT_TRUE(AddInput(input_3));
  VerifyNextBuffer(input_2);
  VerifyNextBuffer(input_3);
  EXPECT_FALSE(splicer_.HasNextBuffer());
}

TEST_F(AudioSplicerTest, Reset) {
  scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f);
  EXPECT_TRUE(AddInput(input_1));
  ASSERT_TRUE(splicer_.HasNextBuffer());

  splicer_.Reset();
  EXPECT_FALSE(splicer_.HasNextBuffer());

  // Add some bytes to the timestamp helper so that the
  // next buffer starts many frames beyond the end of
  // |input_1|. This is to make sure that Reset() actually
  // clears its state and doesn't try to insert a gap.
  input_timestamp_helper_.AddFrames(100);

  // Verify that a new input buffer passes through as expected.
  scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f);
  EXPECT_TRUE(AddInput(input_2));
  VerifyNextBuffer(input_2);
  EXPECT_FALSE(splicer_.HasNextBuffer());
}

TEST_F(AudioSplicerTest, EndOfStream) {
  scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f);
  scoped_refptr<AudioBuffer> input_2 = AudioBuffer::CreateEOSBuffer();
  scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.2f);
  EXPECT_TRUE(input_2->end_of_stream());

  EXPECT_TRUE(AddInput(input_1));
  EXPECT_TRUE(AddInput(input_2));

  VerifyNextBuffer(input_1);

  scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer();
  EXPECT_FALSE(splicer_.HasNextBuffer());
  EXPECT_TRUE(output_2->end_of_stream());

  // Verify that buffers can be added again after Reset().
  splicer_.Reset();
  EXPECT_TRUE(AddInput(input_3));
  VerifyNextBuffer(input_3);
  EXPECT_FALSE(splicer_.HasNextBuffer());
}

// Test the gap insertion code.
// +--------------+    +--------------+
// |11111111111111|    |22222222222222|
// +--------------+    +--------------+
// Results in:
// +--------------+----+--------------+
// |11111111111111|0000|22222222222222|
// +--------------+----+--------------+
TEST_F(AudioSplicerTest, GapInsertion) {
  scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f);

  // Add bytes to the timestamp helper so that the next buffer
  // will have a starting timestamp that indicates a gap is
  // present.
  const int kGapSize = 7;
  input_timestamp_helper_.AddFrames(kGapSize);
  scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f);

  EXPECT_TRUE(AddInput(input_1));
  EXPECT_TRUE(AddInput(input_2));

  // Verify that the first input buffer passed through unmodified.
  VerifyNextBuffer(input_1);

  // Verify the contents of the gap buffer.
  scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer();
  base::TimeDelta gap_timestamp = input_1->timestamp() + input_1->duration();
  base::TimeDelta gap_duration = input_2->timestamp() - gap_timestamp;
  EXPECT_GT(gap_duration, base::TimeDelta());
  EXPECT_EQ(gap_timestamp, output_2->timestamp());
  EXPECT_NEAR(gap_duration.InMicroseconds(),
              output_2->duration().InMicroseconds(), 1);
  EXPECT_EQ(kGapSize, output_2->frame_count());
  EXPECT_TRUE(VerifyData(output_2, 0.0f));

  // Verify that the second input buffer passed through unmodified.
  VerifyNextBuffer(input_2);
  EXPECT_FALSE(splicer_.HasNextBuffer());
}

// Test that an error is signalled when the gap between input buffers is
// too large.
TEST_F(AudioSplicerTest, GapTooLarge) {
  scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f);

  // Add a seconds worth of bytes so that an unacceptably large
  // gap exists between |input_1| and |input_2|.
  const int kGapSize = kDefaultSampleRate;
  input_timestamp_helper_.AddFrames(kGapSize);
  scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f);

  EXPECT_TRUE(AddInput(input_1));
  EXPECT_FALSE(AddInput(input_2));

  VerifyNextBuffer(input_1);

  // Verify that the second buffer is not available.
  EXPECT_FALSE(splicer_.HasNextBuffer());

  // Reset the timestamp helper so it can generate a buffer that is
  // right after |input_1|.
  input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp() +
                                           input_1->duration());

  // Verify that valid buffers are still accepted.
  scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f);
  EXPECT_TRUE(AddInput(input_3));
  VerifyNextBuffer(input_3);
  EXPECT_FALSE(splicer_.HasNextBuffer());
}

// Verifies that an error is signalled if AddInput() is called
// with a timestamp that is earlier than the first buffer added.
TEST_F(AudioSplicerTest, BufferAddedBeforeBase) {
  input_timestamp_helper_.SetBaseTimestamp(
      base::TimeDelta::FromMicroseconds(10));
  scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f);

  // Reset the timestamp helper so the next buffer will have a timestamp earlier
  // than |input_1|.
  input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta::FromSeconds(0));
  scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.1f);

  EXPECT_GT(input_1->timestamp(), input_2->timestamp());
  EXPECT_TRUE(AddInput(input_1));
  EXPECT_FALSE(AddInput(input_2));
}

// Test when one buffer partially overlaps another.
// +--------------+
// |11111111111111|
// +--------------+
//            +--------------+
//            |22222222222222|
//            +--------------+
// Results in:
// +--------------+----------+
// |11111111111111|2222222222|
// +--------------+----------+
TEST_F(AudioSplicerTest, PartialOverlap) {
  scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f);

  // Reset timestamp helper so that the next buffer will have a
  // timestamp that starts in the middle of |input_1|.
  const int kOverlapSize = input_1->frame_count() / 4;
  input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp());
  input_timestamp_helper_.AddFrames(input_1->frame_count() - kOverlapSize);

  scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f);

  EXPECT_TRUE(AddInput(input_1));
  EXPECT_TRUE(AddInput(input_2));

  // Verify that the first input buffer passed through unmodified.
  VerifyNextBuffer(input_1);

  ASSERT_TRUE(splicer_.HasNextBuffer());
  scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer();
  EXPECT_FALSE(splicer_.HasNextBuffer());

  // Verify that the second input buffer was truncated to only contain
  // the samples that are after the end of |input_1|.
  base::TimeDelta expected_timestamp =
      input_1->timestamp() + input_1->duration();
  base::TimeDelta expected_duration =
      (input_2->timestamp() + input_2->duration()) - expected_timestamp;
  EXPECT_EQ(expected_timestamp, output_2->timestamp());
  EXPECT_EQ(expected_duration, output_2->duration());
  EXPECT_TRUE(VerifyData(output_2, GetValue(input_2)));
}

// Test that an input buffer that is completely overlapped by a buffer
// that was already added is dropped.
// +--------------+
// |11111111111111|
// +--------------+
//       +-----+
//       |22222|
//       +-----+
//                +-------------+
//                |3333333333333|
//                +-------------+
// Results in:
// +--------------+-------------+
// |11111111111111|3333333333333|
// +--------------+-------------+
TEST_F(AudioSplicerTest, DropBuffer) {
  scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f);

  // Reset timestamp helper so that the next buffer will have a
  // timestamp that starts in the middle of |input_1|.
  const int kOverlapOffset = input_1->frame_count() / 2;
  const int kOverlapSize = input_1->frame_count() / 4;
  input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp());
  input_timestamp_helper_.AddFrames(kOverlapOffset);

  scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f, kOverlapSize);

  // Reset the timestamp helper so the next buffer will be right after
  // |input_1|.
  input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp());
  input_timestamp_helper_.AddFrames(input_1->frame_count());
  scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f);

  EXPECT_TRUE(AddInput(input_1));
  EXPECT_TRUE(AddInput(input_2));
  EXPECT_TRUE(AddInput(input_3));

  VerifyNextBuffer(input_1);
  VerifyNextBuffer(input_3);
  EXPECT_FALSE(splicer_.HasNextBuffer());
}

// Test crossfade when one buffer partially overlaps another.
// +--------------+
// |11111111111111|
// +--------------+
//            +--------------+
//            |22222222222222|
//            +--------------+
// Results in:
// +----------+----+----------+
// |1111111111|xxxx|2222222222|
// +----------+----+----------+
// Where "xxxx" represents the crossfaded portion of the signal.
TEST_F(AudioSplicerTest, PartialOverlapCrossfade) {
  const int kCrossfadeSize =
      input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration());
  const int kBufferSize = kCrossfadeSize * 2;

  scoped_refptr<AudioBuffer> extra_pre_splice_buffer =
      GetNextInputBuffer(0.2f, kBufferSize);
  scoped_refptr<AudioBuffer> overlapped_buffer =
      GetNextInputBuffer(1.0f, kBufferSize);

  // Reset timestamp helper so that the next buffer will have a timestamp that
  // starts in the middle of |overlapped_buffer|.
  input_timestamp_helper_.SetBaseTimestamp(overlapped_buffer->timestamp());
  input_timestamp_helper_.AddFrames(overlapped_buffer->frame_count() -
                                    kCrossfadeSize);
  splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp());
  scoped_refptr<AudioBuffer> overlapping_buffer =
      GetNextInputBuffer(0.0f, kBufferSize);

  // |extra_pre_splice_buffer| is entirely before the splice and should be ready
  // for output.
  EXPECT_TRUE(AddInput(extra_pre_splice_buffer));
  VerifyNextBuffer(extra_pre_splice_buffer);

  // The splicer should be internally queuing input since |overlapped_buffer| is
  // part of the splice.
  EXPECT_TRUE(AddInput(overlapped_buffer));
  EXPECT_FALSE(splicer_.HasNextBuffer());

  // |overlapping_buffer| completes the splice.
  splicer_.SetSpliceTimestamp(kNoTimestamp);
  EXPECT_TRUE(AddInput(overlapping_buffer));
  ASSERT_TRUE(splicer_.HasNextBuffer());

  // Add one more buffer to make sure it's passed through untouched.
  scoped_refptr<AudioBuffer> extra_post_splice_buffer =
      GetNextInputBuffer(0.5f, kBufferSize);
  EXPECT_TRUE(AddInput(extra_post_splice_buffer));

  VerifyPreSpliceOutput(overlapped_buffer, overlapping_buffer, 221,
                        base::TimeDelta::FromMicroseconds(5011));

  // Due to rounding the crossfade size may vary by up to a frame.
  const int kExpectedCrossfadeSize = 220;
  EXPECT_NEAR(kExpectedCrossfadeSize, kCrossfadeSize, 1);

  VerifyCrossfadeOutput(overlapped_buffer, NULL, overlapping_buffer, 0,
                        kExpectedCrossfadeSize,
                        base::TimeDelta::FromMicroseconds(4988));

  // Retrieve the remaining portion after crossfade.
  ASSERT_TRUE(splicer_.HasNextBuffer());
  scoped_refptr<AudioBuffer> post_splice_output = splicer_.GetNextBuffer();
  EXPECT_EQ(base::TimeDelta::FromMicroseconds(20022),
            post_splice_output->timestamp());
  EXPECT_EQ(overlapping_buffer->frame_count() - kExpectedCrossfadeSize,
            post_splice_output->frame_count());
  EXPECT_EQ(base::TimeDelta::FromMicroseconds(5034),
            post_splice_output->duration());

  EXPECT_TRUE(VerifyData(post_splice_output, GetValue(overlapping_buffer)));

  VerifyNextBuffer(extra_post_splice_buffer);
  EXPECT_FALSE(splicer_.HasNextBuffer());
}

// Test crossfade when one buffer partially overlaps another, but an end of
// stream buffer is received before the crossfade duration is reached.
// +--------------+
// |11111111111111|
// +--------------+
//            +---------++---+
//            |222222222||EOS|
//            +---------++---+
// Results in:
// +----------+----+----++---+
// |1111111111|xxxx|2222||EOS|
// +----------+----+----++---+
// Where "x" represents the crossfaded portion of the signal.
TEST_F(AudioSplicerTest, PartialOverlapCrossfadeEndOfStream) {
  const int kCrossfadeSize =
      input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration());

  scoped_refptr<AudioBuffer> overlapped_buffer =
      GetNextInputBuffer(1.0f, kCrossfadeSize * 2);

  // Reset timestamp helper so that the next buffer will have a timestamp that
  // starts 3/4 of the way into |overlapped_buffer|.
  input_timestamp_helper_.SetBaseTimestamp(overlapped_buffer->timestamp());
  input_timestamp_helper_.AddFrames(3 * overlapped_buffer->frame_count() / 4);
  splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp());
  scoped_refptr<AudioBuffer> overlapping_buffer =
      GetNextInputBuffer(0.0f, kCrossfadeSize / 3);

  // The splicer should be internally queuing input since |overlapped_buffer| is
  // part of the splice.
  EXPECT_TRUE(AddInput(overlapped_buffer));
  EXPECT_FALSE(splicer_.HasNextBuffer());

  // |overlapping_buffer| should not have enough data to complete the splice, so
  // ensure output is not available.
  splicer_.SetSpliceTimestamp(kNoTimestamp);
  EXPECT_TRUE(AddInput(overlapping_buffer));
  EXPECT_FALSE(splicer_.HasNextBuffer());

  // Now add an EOS buffer which should complete the splice.
  EXPECT_TRUE(AddInput(AudioBuffer::CreateEOSBuffer()));

  VerifyPreSpliceOutput(overlapped_buffer, overlapping_buffer, 331,
                        base::TimeDelta::FromMicroseconds(7505));
  VerifyCrossfadeOutput(overlapped_buffer, NULL, overlapping_buffer, 0,
                        overlapping_buffer->frame_count(),
                        overlapping_buffer->duration());

  // Ensure the last buffer is an EOS buffer.
  ASSERT_TRUE(splicer_.HasNextBuffer());
  scoped_refptr<AudioBuffer> post_splice_output = splicer_.GetNextBuffer();
  EXPECT_TRUE(post_splice_output->end_of_stream());

  EXPECT_FALSE(splicer_.HasNextBuffer());
}

// Test crossfade when one buffer partially overlaps another, but the amount of
// overlapped data is less than the crossfade duration.
// +------------+
// |111111111111|
// +------------+
//            +--------------+
//            |22222222222222|
//            +--------------+
// Results in:
// +----------+-+------------+
// |1111111111|x|222222222222|
// +----------+-+------------+
// Where "x" represents the crossfaded portion of the signal.
TEST_F(AudioSplicerTest, PartialOverlapCrossfadeShortPreSplice) {
  const int kCrossfadeSize =
      input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration());

  scoped_refptr<AudioBuffer> overlapped_buffer =
      GetNextInputBuffer(1.0f, kCrossfadeSize / 2);

  // Reset timestamp helper so that the next buffer will have a timestamp that
  // starts in the middle of |overlapped_buffer|.
  input_timestamp_helper_.SetBaseTimestamp(overlapped_buffer->timestamp());
  input_timestamp_helper_.AddFrames(overlapped_buffer->frame_count() / 2);
  splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp());
  scoped_refptr<AudioBuffer> overlapping_buffer =
      GetNextInputBuffer(0.0f, kCrossfadeSize * 2);

  // The splicer should be internally queuing input since |overlapped_buffer| is
  // part of the splice.
  EXPECT_TRUE(AddInput(overlapped_buffer));
  EXPECT_FALSE(splicer_.HasNextBuffer());

  // |overlapping_buffer| completes the splice.
  splicer_.SetSpliceTimestamp(kNoTimestamp);
  EXPECT_TRUE(AddInput(overlapping_buffer));

  const int kExpectedPreSpliceSize = 55;
  const base::TimeDelta kExpectedPreSpliceDuration =
      base::TimeDelta::FromMicroseconds(1247);
  VerifyPreSpliceOutput(overlapped_buffer, overlapping_buffer,
                        kExpectedPreSpliceSize, kExpectedPreSpliceDuration);
  VerifyCrossfadeOutput(overlapped_buffer, NULL, overlapping_buffer, 0,
                        kExpectedPreSpliceSize, kExpectedPreSpliceDuration);

  // Retrieve the remaining portion after crossfade.
  ASSERT_TRUE(splicer_.HasNextBuffer());
  scoped_refptr<AudioBuffer> post_splice_output = splicer_.GetNextBuffer();
  EXPECT_EQ(overlapping_buffer->timestamp() + kExpectedPreSpliceDuration,
            post_splice_output->timestamp());
  EXPECT_EQ(overlapping_buffer->frame_count() - kExpectedPreSpliceSize,
            post_splice_output->frame_count());
  EXPECT_EQ(overlapping_buffer->duration() - kExpectedPreSpliceDuration,
            post_splice_output->duration());

  EXPECT_TRUE(VerifyData(post_splice_output, GetValue(overlapping_buffer)));
  EXPECT_FALSE(splicer_.HasNextBuffer());
}

// Test behavior when a splice frame is incorrectly marked and does not actually
// overlap.
// +----------+
// |1111111111|
// +----------+
//            +--------------+
//            |22222222222222|
//            +--------------+
// Results in:
// +----------+--------------+
// |1111111111|22222222222222|
// +----------+--------------+
TEST_F(AudioSplicerTest, IncorrectlyMarkedSplice) {
  const int kBufferSize =
      input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()) * 2;

  scoped_refptr<AudioBuffer> first_buffer =
      GetNextInputBuffer(1.0f, kBufferSize);
  // Fuzz the duration slightly so that the buffer overlaps the splice timestamp
  // by a microsecond, which is not enough to crossfade.
  const base::TimeDelta kSpliceTimestamp =
      input_timestamp_helper_.GetTimestamp() -
      base::TimeDelta::FromMicroseconds(1);
  splicer_.SetSpliceTimestamp(kSpliceTimestamp);
  scoped_refptr<AudioBuffer> second_buffer =
      GetNextInputBuffer(0.0f, kBufferSize);
  second_buffer->set_timestamp(kSpliceTimestamp);

  // The splicer should be internally queuing input since |first_buffer| is part
  // of the supposed splice.
  EXPECT_TRUE(AddInput(first_buffer));
  EXPECT_FALSE(splicer_.HasNextBuffer());

  // |second_buffer| should complete the supposed splice, so ensure output is
  // now available.
  splicer_.SetSpliceTimestamp(kNoTimestamp);
  EXPECT_TRUE(AddInput(second_buffer));

  VerifyNextBuffer(first_buffer);
  VerifyNextBuffer(second_buffer);
  EXPECT_FALSE(splicer_.HasNextBuffer());
}

// Test behavior when a splice frame is incorrectly marked and there is a gap
// between whats in the pre splice and post splice.
// +--------+
// |11111111|
// +--------+
//            +--------------+
//            |22222222222222|
//            +--------------+
// Results in:
// +--------+-+--------------+
// |11111111|0|22222222222222|
// +--------+-+--------------+
TEST_F(AudioSplicerTest, IncorrectlyMarkedSpliceWithGap) {
  const int kBufferSize =
      input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()) * 2;
  const int kGapSize = 2;

  scoped_refptr<AudioBuffer> first_buffer =
      GetNextInputBuffer(1.0f, kBufferSize - kGapSize);
  scoped_refptr<AudioBuffer> gap_buffer = GetNextInputBuffer(0.0f, kGapSize);
  splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp());
  scoped_refptr<AudioBuffer> second_buffer =
      GetNextInputBuffer(0.0f, kBufferSize);

  // The splicer should pass through the first buffer since it's not part of the
  // splice.
  EXPECT_TRUE(AddInput(first_buffer));
  VerifyNextBuffer(first_buffer);

  // Do not add |gap_buffer|.

  // |second_buffer| will complete the supposed splice.
  splicer_.SetSpliceTimestamp(kNoTimestamp);
  EXPECT_TRUE(AddInput(second_buffer));

  VerifyNextBuffer(gap_buffer);
  VerifyNextBuffer(second_buffer);
  EXPECT_FALSE(splicer_.HasNextBuffer());
}

// Test behavior when a splice frame is incorrectly marked and there is a gap
// between what's in the pre splice and post splice that is too large to recover
// from.
// +--------+
// |11111111|
// +--------+
//                    +------+
//                    |222222|
//                    +------+
// Results in an error and not a crash.
TEST_F(AudioSplicerTest, IncorrectlyMarkedSpliceWithBadGap) {
  const int kBufferSize =
      input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()) * 2;
  const int kGapSize = kBufferSize +
                       input_timestamp_helper_.GetFramesToTarget(
                           base::TimeDelta::FromMilliseconds(
                               AudioSplicer::kMaxTimeDeltaInMilliseconds + 1));

  scoped_refptr<AudioBuffer> first_buffer =
      GetNextInputBuffer(1.0f, kBufferSize);
  scoped_refptr<AudioBuffer> gap_buffer = GetNextInputBuffer(0.0f, kGapSize);
  splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp());
  scoped_refptr<AudioBuffer> second_buffer =
      GetNextInputBuffer(0.0f, kBufferSize);

  // The splicer should pass through the first buffer since it's not part of the
  // splice.
  EXPECT_TRUE(AddInput(first_buffer));
  VerifyNextBuffer(first_buffer);

  // Do not add |gap_buffer|.

  // |second_buffer| will complete the supposed splice.
  splicer_.SetSpliceTimestamp(kNoTimestamp);
  EXPECT_FALSE(AddInput(second_buffer));
}

// Ensure we don't crash when a splice frame is incorrectly marked such that the
// splice timestamp has already passed when SetSpliceTimestamp() is called.
// This can happen if the encoded timestamps are too far behind the decoded
// timestamps.
TEST_F(AudioSplicerTest, IncorrectlyMarkedPastSplice) {
  const int kBufferSize = 200;

  scoped_refptr<AudioBuffer> first_buffer =
      GetNextInputBuffer(1.0f, kBufferSize);
  EXPECT_TRUE(AddInput(first_buffer));
  VerifyNextBuffer(first_buffer);

  // Start the splice at a timestamp which has already occurred.
  splicer_.SetSpliceTimestamp(base::TimeDelta());

  scoped_refptr<AudioBuffer> second_buffer =
      GetNextInputBuffer(0.5f, kBufferSize);
  EXPECT_TRUE(AddInput(second_buffer));
  EXPECT_FALSE(splicer_.HasNextBuffer());

  // |third_buffer| will complete the supposed splice.  The buffer size is set
  // such that unchecked the splicer would try to trim off a negative number of
  // frames.
  splicer_.SetSpliceTimestamp(kNoTimestamp);
  scoped_refptr<AudioBuffer> third_buffer =
      GetNextInputBuffer(0.0f, kBufferSize * 10);
  third_buffer->set_timestamp(base::TimeDelta());
  EXPECT_TRUE(AddInput(third_buffer));

  // The second buffer should come through unmodified.
  VerifyNextBuffer(second_buffer);

  // The third buffer should be partially dropped since it overlaps the second.
  ASSERT_TRUE(splicer_.HasNextBuffer());
  const base::TimeDelta second_buffer_end_ts =
      second_buffer->timestamp() + second_buffer->duration();
  scoped_refptr<AudioBuffer> output = splicer_.GetNextBuffer();
  EXPECT_EQ(second_buffer_end_ts, output->timestamp());
  EXPECT_EQ(third_buffer->duration() -
                (second_buffer_end_ts - third_buffer->timestamp()),
            output->duration());
  EXPECT_TRUE(VerifyData(output, GetValue(third_buffer)));
}

}  // namespace media
