// 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 cobalt {
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
}  // namespace cobalt
