// Copyright 2014 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 "media/base/audio_discard_helper.h"

#include <stddef.h>

#include <memory>

#include "media/base/audio_buffer.h"
#include "media/base/audio_bus.h"
#include "media/base/decoder_buffer.h"
#include "media/base/test_helpers.h"
#include "media/base/timestamp_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

static const float kDataStep = 0.01f;
static const size_t kSampleRate = 48000;

static scoped_refptr<DecoderBuffer> CreateEncodedBuffer(
    base::TimeDelta timestamp,
    base::TimeDelta duration) {
  scoped_refptr<DecoderBuffer> result(new DecoderBuffer(1));
  result->set_timestamp(timestamp);
  result->set_duration(duration);
  return result;
}

static scoped_refptr<AudioBuffer> CreateDecodedBuffer(int frames) {
  return MakeAudioBuffer(kSampleFormatPlanarF32, CHANNEL_LAYOUT_MONO, 1,
                         kSampleRate, 0.0f, kDataStep, frames, kNoTimestamp);
}

static float ExtractDecodedData(const AudioBuffer& buffer, int index) {
  // This is really inefficient, but we can't access the raw AudioBuffer if any
  // start trimming has been applied.
  std::unique_ptr<AudioBus> temp_bus =
      AudioBus::Create(buffer.channel_count(), 1);
  buffer.ReadFrames(1, index, 0, temp_bus.get());
  return temp_bus->channel(0)[0] * std::numeric_limits<uint16_t>::max();
}

TEST(AudioDiscardHelperTest, TimeDeltaToFrames) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, false);

  EXPECT_EQ(0u, discard_helper.TimeDeltaToFrames(base::TimeDelta()));
  EXPECT_EQ(kSampleRate / 100,
            discard_helper.TimeDeltaToFrames(base::Milliseconds(10)));

  // Ensure partial frames are rounded down correctly.  The equation below
  // calculates a frame count with a fractional part < 0.5.
  const int small_remainder =
      base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate;
  EXPECT_EQ(kSampleRate - 1, discard_helper.TimeDeltaToFrames(
                                 base::Microseconds(small_remainder)));

  // Ditto, but rounded up using a fractional part > 0.5.
  const int large_remainder =
      base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.4) / kSampleRate;
  EXPECT_EQ(kSampleRate, discard_helper.TimeDeltaToFrames(
                             base::Microseconds(large_remainder)));
}

TEST(AudioDiscardHelperTest, BasicProcessBuffers) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();

  // Use an estimated duration which doesn't match the number of decoded frames
  // to ensure the helper is correctly setting durations based on output frames.
  const base::TimeDelta kEstimatedDuration = base::Milliseconds(9);
  const base::TimeDelta kActualDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kEstimatedDuration);
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // Verify the basic case where nothing is discarded.
  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  ASSERT_TRUE(discard_helper.initialized());
  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  EXPECT_EQ(kActualDuration, decoded_buffer->duration());
  EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());

  // Verify a Reset() takes us back to an uninitialized state.
  discard_helper.Reset(0);
  ASSERT_FALSE(discard_helper.initialized());

  // Verify a NULL output buffer returns false.
  ASSERT_FALSE(discard_helper.ProcessBuffers(*encoded_buffer, NULL));
}

TEST(AudioDiscardHelperTest, NegativeTimestampClampsToZero) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = -base::Seconds(1);
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // Verify the basic case where nothing is discarded.
  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  ASSERT_TRUE(discard_helper.initialized());
  EXPECT_EQ(base::TimeDelta(), decoded_buffer->timestamp());
  EXPECT_EQ(kDuration, decoded_buffer->duration());
  EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
}

TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);

  // Tell the helper we want to discard half of the initial frames.
  const int kDiscardFrames = kTestFrames / 2;
  discard_helper.Reset(kDiscardFrames);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // Verify half the frames end up discarded.
  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  ASSERT_TRUE(discard_helper.initialized());
  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count());
  ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep,
                  ExtractDecodedData(*decoded_buffer, 0));
}

TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);

  // Tell the helper we want to discard 1.5 buffers worth of frames.
  discard_helper.Reset(kTestFrames * 1.5);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // The first call should fail since no output buffer remains.
  ASSERT_FALSE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  ASSERT_TRUE(discard_helper.initialized());

  // Generate another set of buffers and expect half the output frames.
  encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration);
  decoded_buffer = CreateDecodedBuffer(kTestFrames);
  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));

  // The timestamp should match that of the initial buffer.
  const int kDiscardFrames = kTestFrames / 2;
  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count());
  ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep,
                  ExtractDecodedData(*decoded_buffer, 0));
}

TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  ASSERT_TRUE(discard_helper.initialized());
  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  EXPECT_EQ(kDuration, decoded_buffer->duration());
  EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());

  // Process the same input buffer again to ensure input timestamps which go
  // backwards in time are not errors.
  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp());
  EXPECT_EQ(kDuration, decoded_buffer->duration());
  EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
}

TEST(AudioDiscardHelperTest, DiscardEndPadding) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // Set a discard padding equivalent to half the buffer.
  encoded_buffer->set_discard_padding(
      std::make_pair(base::TimeDelta(), kDuration / 2));

  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  ASSERT_TRUE(discard_helper.initialized());
  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
}

TEST(AudioDiscardHelperTest, BadDiscardEndPadding) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // Set a discard padding equivalent to double the buffer size.
  encoded_buffer->set_discard_padding(
      std::make_pair(base::TimeDelta(), kDuration * 2));

  // Verify the end discard padding is rejected.
  ASSERT_FALSE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  ASSERT_TRUE(discard_helper.initialized());
}

TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardEndPadding) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // Set a discard padding equivalent to a quarter of the buffer.
  encoded_buffer->set_discard_padding(
      std::make_pair(base::TimeDelta(), kDuration / 4));

  // Set an initial discard of a quarter of the buffer.
  const int kDiscardFrames = kTestFrames / 4;
  discard_helper.Reset(kDiscardFrames);

  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  ASSERT_TRUE(discard_helper.initialized());
  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
  ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep,
                  ExtractDecodedData(*decoded_buffer, 0));
}

TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // Set all the discard values to be different to ensure each is properly used.
  const int kDiscardFrames = kTestFrames / 4;
  encoded_buffer->set_discard_padding(
      std::make_pair(kDuration / 8, kDuration / 16));
  discard_helper.Reset(kDiscardFrames);

  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  ASSERT_TRUE(discard_helper.initialized());
  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  EXPECT_EQ(kDuration - kDuration / 4 - kDuration / 8 - kDuration / 16,
            decoded_buffer->duration());
  EXPECT_EQ(kTestFrames - kTestFrames / 4 - kTestFrames / 8 - kTestFrames / 16,
            decoded_buffer->frame_count());
}

TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPaddingAndDecoderDelay) {
  // Use a decoder delay of 5ms.
  const int kDecoderDelay = kSampleRate / 100 / 2;
  AudioDiscardHelper discard_helper(kSampleRate, kDecoderDelay, false);
  ASSERT_FALSE(discard_helper.initialized());
  discard_helper.Reset(kDecoderDelay);

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // Set a discard padding equivalent to half of the buffer.
  encoded_buffer->set_discard_padding(
      std::make_pair(kDuration / 2, base::TimeDelta()));

  // All of the first buffer should be discarded, half from the inital delay and
  // another half from the front discard padding.
  //
  //    Encoded                   Discard Delay
  //   |--------|     |---------|     |----|
  //   |AAAAAAAA| --> |....|AAAA| --> |AAAA| -------> NULL
  //   |--------|     |---------|     |----|
  //                    Decoded               Discard Front Padding
  //
  ASSERT_FALSE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  ASSERT_TRUE(discard_helper.initialized());

  // Processing another buffer that has front discard set to half the buffer's
  // duration should discard the back half of the buffer since kDecoderDelay is
  // half a buffer.  The end padding should not be discarded until another
  // buffer is processed.  kDuration / 4 is chosen for the end discard since it
  // will force the end discard to start after position zero within the next
  // decoded buffer.
  //
  //    Encoded                    Discard Front Padding (from B)
  //   |--------|     |---------|             |----|
  //   |BBBBBBBB| --> |AAAA|BBBB| ----------> |AAAA|
  //   |--------|     |---------|             |----|
  //                    Decoded
  //           (includes carryover from A)
  //
  encoded_buffer->set_timestamp(encoded_buffer->timestamp() + kDuration);
  encoded_buffer->set_discard_padding(
      std::make_pair(kDuration / 2, kDuration / 4));
  decoded_buffer = CreateDecodedBuffer(kTestFrames);
  ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(*decoded_buffer, 0));
  ASSERT_NEAR(kDecoderDelay * kDataStep,
              ExtractDecodedData(*decoded_buffer, kDecoderDelay),
              kDataStep / 1000);
  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());

  // Verify it was actually the latter half of the buffer that was removed.
  ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(*decoded_buffer, 0));

  // Verify the end discard padding is carried over to the next buffer.  Use
  // kDuration / 2 for the end discard padding so that the next buffer has its
  // start entirely discarded.
  //
  //    Encoded                      Discard End Padding (from B)
  //   |--------|     |---------|             |-------|
  //   |CCCCCCCC| --> |BBBB|CCCC| ----------> |BB|CCCC|
  //   |--------|     |---------|             |-------|
  //                    Decoded
  //           (includes carryover from B)
  //
  encoded_buffer->set_timestamp(encoded_buffer->timestamp() + kDuration);
  encoded_buffer->set_discard_padding(
      std::make_pair(base::TimeDelta(), kDuration / 2));
  decoded_buffer = CreateDecodedBuffer(kTestFrames);
  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  EXPECT_EQ(kTimestamp + kDuration / 2, decoded_buffer->timestamp());
  EXPECT_EQ(3 * kDuration / 4, decoded_buffer->duration());
  EXPECT_EQ(3 * kTestFrames / 4, decoded_buffer->frame_count());

  // Verify it was actually the second quarter of the buffer that was removed.
  const int kDiscardFrames = kTestFrames / 4;
  ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(*decoded_buffer, 0));
  ASSERT_FLOAT_EQ(
      kDiscardFrames * 2 * kDataStep,
      ExtractDecodedData(*decoded_buffer, kDecoderDelay - kDiscardFrames));

  // One last test to ensure carryover discard from the start works.
  //
  //    Encoded                      Discard End Padding (from C)
  //   |--------|     |---------|             |----|
  //   |DDDDDDDD| --> |CCCC|DDDD| ----------> |DDDD|
  //   |--------|     |---------|             |----|
  //                    Decoded
  //           (includes carryover from C)
  //
  encoded_buffer->set_timestamp(encoded_buffer->timestamp() + kDuration);
  encoded_buffer->set_discard_padding(DecoderBuffer::DiscardPadding());
  decoded_buffer = CreateDecodedBuffer(kTestFrames);
  ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(*decoded_buffer, 0));
  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  EXPECT_EQ(kTimestamp + kDuration / 2 + 3 * kDuration / 4,
            decoded_buffer->timestamp());
  EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
  ASSERT_FLOAT_EQ(kTestFrames / 2 * kDataStep,
                  ExtractDecodedData(*decoded_buffer, 0));
}

TEST(AudioDiscardHelperTest, DelayedDiscardInitialDiscardAndDiscardPadding) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, true);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);

  // Set all the discard values to be different to ensure each is properly used.
  const int kDiscardFrames = kTestFrames / 4;
  encoded_buffer->set_discard_padding(
      std::make_pair(kDuration / 8, kDuration / 16));
  discard_helper.Reset(kDiscardFrames);

  // Verify nothing is output for the first buffer, yet initialized is true.
  ASSERT_FALSE(discard_helper.ProcessBuffers(*encoded_buffer, NULL));
  ASSERT_TRUE(discard_helper.initialized());

  // Create an encoded buffer with no discard padding.
  encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration);
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // Verify that when the decoded buffer is consumed, the discards from the
  // previous encoded buffer are applied.
  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  EXPECT_EQ(kDuration - kDuration / 4 - kDuration / 8 - kDuration / 16,
            decoded_buffer->duration());
  EXPECT_EQ(kTestFrames - kTestFrames / 4 - kTestFrames / 8 - kTestFrames / 16,
            decoded_buffer->frame_count());
}

TEST(AudioDiscardHelperTest, CompleteDiscard) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  discard_helper.Reset(0);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);
  encoded_buffer->set_discard_padding(
      std::make_pair(kInfiniteDuration, base::TimeDelta()));
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // Verify all of the first buffer is discarded.
  ASSERT_FALSE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  ASSERT_TRUE(discard_helper.initialized());
  encoded_buffer->set_timestamp(kTimestamp + kDuration);
  encoded_buffer->set_discard_padding(DecoderBuffer::DiscardPadding());

  // Verify a second buffer goes through untouched.
  decoded_buffer = CreateDecodedBuffer(kTestFrames / 2);
  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
  ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(*decoded_buffer, 0));
}

TEST(AudioDiscardHelperTest, CompleteDiscardWithDelayedDiscard) {
  AudioDiscardHelper discard_helper(kSampleRate, 0, true);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  discard_helper.Reset(0);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);
  encoded_buffer->set_discard_padding(
      std::make_pair(kInfiniteDuration, base::TimeDelta()));
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // Setup a delayed discard.
  ASSERT_FALSE(discard_helper.ProcessBuffers(*encoded_buffer, NULL));
  ASSERT_TRUE(discard_helper.initialized());

  // Verify the first output buffer is dropped.
  encoded_buffer->set_timestamp(kTimestamp + kDuration);
  encoded_buffer->set_discard_padding(DecoderBuffer::DiscardPadding());
  ASSERT_FALSE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));

  // Verify the second buffer goes through untouched.
  encoded_buffer->set_timestamp(kTimestamp + 2 * kDuration);
  decoded_buffer = CreateDecodedBuffer(kTestFrames / 2);
  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
  ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(*decoded_buffer, 0));
}

TEST(AudioDiscardHelperTest, CompleteDiscardWithInitialDiscardDecoderDelay) {
  // Use a decoder delay of 5ms.
  const int kDecoderDelay = kSampleRate / 100 / 2;
  AudioDiscardHelper discard_helper(kSampleRate, kDecoderDelay, false);
  ASSERT_FALSE(discard_helper.initialized());
  discard_helper.Reset(kDecoderDelay);

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::Milliseconds(10);
  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);

  scoped_refptr<DecoderBuffer> encoded_buffer =
      CreateEncodedBuffer(kTimestamp, kDuration);
  encoded_buffer->set_discard_padding(
      std::make_pair(kInfiniteDuration, base::TimeDelta()));
  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);

  // Verify all of the first buffer is discarded.
  ASSERT_FALSE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  ASSERT_TRUE(discard_helper.initialized());
  encoded_buffer->set_timestamp(kTimestamp + kDuration);
  encoded_buffer->set_discard_padding(DecoderBuffer::DiscardPadding());

  // Verify 5ms off the front of the second buffer is discarded.
  decoded_buffer = CreateDecodedBuffer(kTestFrames * 2);
  ASSERT_TRUE(
      discard_helper.ProcessBuffers(*encoded_buffer, decoded_buffer.get()));
  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  EXPECT_EQ(kDuration * 2 - kDuration / 2, decoded_buffer->duration());
  EXPECT_EQ(kTestFrames * 2 - kDecoderDelay, decoded_buffer->frame_count());
  ASSERT_FLOAT_EQ(kDecoderDelay * kDataStep,
                  ExtractDecodedData(*decoded_buffer, 0));
}

}  // namespace media
