// 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 "base/memory/scoped_ptr.h"
#include "media/base/audio_buffer.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_splicer.h"
#include "media/base/audio_timestamp_helper.h"
#include "media/base/buffers.h"
#include "media/base/test_helpers.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;
COMPILE_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),
        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();
    scoped_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);
    scoped_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 && 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_;

  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));
}

}  // namespace media
