// 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 "base/memory/scoped_ptr.h"
#include "media/base/audio_buffer.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_discard_helper.h"
#include "media/base/buffers.h"
#include "media/base/decoder_buffer.h"
#include "media/base/test_helpers.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 scoped_refptr<AudioBuffer>& buffer,
                                int index) {
  // This is really inefficient, but we can't access the raw AudioBuffer if any
  // start trimming has been applied.
  scoped_ptr<AudioBus> temp_bus = AudioBus::Create(buffer->channel_count(), 1);
  buffer->ReadFrames(1, index, 0, temp_bus.get());
  return temp_bus->channel(0)[0];
}

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

  EXPECT_EQ(0u, discard_helper.TimeDeltaToFrames(base::TimeDelta()));
  EXPECT_EQ(
      kSampleRate / 100,
      discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(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::TimeDelta::FromMicroseconds(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::TimeDelta::FromMicroseconds(large_remainder)));
}

TEST(AudioDiscardHelperTest, BasicProcessBuffers) {
  AudioDiscardHelper discard_helper(kSampleRate, 0);
  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::TimeDelta::FromMilliseconds(9);
  const base::TimeDelta kActualDuration = base::TimeDelta::FromMilliseconds(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));
  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);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = -base::TimeDelta::FromSeconds(1);
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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));
  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);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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));
  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);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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));
  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));

  // 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);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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));
  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));
  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);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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));
  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);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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));
  ASSERT_TRUE(discard_helper.initialized());
}

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

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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));
  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);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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));
  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);
  ASSERT_FALSE(discard_helper.initialized());
  discard_helper.Reset(kDecoderDelay);

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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.
  ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
  ASSERT_TRUE(discard_helper.initialized());

  // Processing another buffer (with the same discard padding) should discard
  // the back half of the buffer since kDecoderDelay is half a buffer.
  encoded_buffer->set_timestamp(kTimestamp + kDuration);
  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));
  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));
}

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

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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));
  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);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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));
  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));
  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);
  ASSERT_FALSE(discard_helper.initialized());

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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));

  // 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));
  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);
  ASSERT_FALSE(discard_helper.initialized());
  discard_helper.Reset(kDecoderDelay);

  const base::TimeDelta kTimestamp = base::TimeDelta();
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(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));
  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));
  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
