| Index: media/base/audio_discard_helper_unittest.cc
|
| diff --git a/media/base/audio_discard_helper_unittest.cc b/media/base/audio_discard_helper_unittest.cc
|
| index 1a6b592120da4b8425361e606a89b28cb334c1b9..8807f97c66343c5963c818e5e81f46f14a9b00b1 100644
|
| --- a/media/base/audio_discard_helper_unittest.cc
|
| +++ b/media/base/audio_discard_helper_unittest.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #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"
|
| @@ -12,6 +13,7 @@
|
|
|
| namespace media {
|
|
|
| +static const float kDataStep = 0.01f;
|
| static const int kSampleRate = 48000;
|
|
|
| static scoped_refptr<DecoderBuffer> CreateEncodedBuffer(
|
| @@ -29,14 +31,23 @@ static scoped_refptr<AudioBuffer> CreateDecodedBuffer(int frames) {
|
| 1,
|
| kSampleRate,
|
| 0.0f,
|
| - 0.01f,
|
| + kDataStep,
|
| frames,
|
| kNoTimestamp(),
|
| 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);
|
| + AudioDiscardHelper discard_helper(kSampleRate, 0);
|
|
|
| EXPECT_EQ(0, discard_helper.TimeDeltaToFrames(base::TimeDelta()));
|
| EXPECT_EQ(
|
| @@ -53,7 +64,7 @@ TEST(AudioDiscardHelperTest, TimeDeltaToFrames) {
|
| }
|
|
|
| TEST(AudioDiscardHelperTest, BasicProcessBuffers) {
|
| - AudioDiscardHelper discard_helper(kSampleRate);
|
| + AudioDiscardHelper discard_helper(kSampleRate, 0);
|
| ASSERT_FALSE(discard_helper.initialized());
|
|
|
| const base::TimeDelta kTimestamp = base::TimeDelta();
|
| @@ -85,7 +96,7 @@ TEST(AudioDiscardHelperTest, BasicProcessBuffers) {
|
| }
|
|
|
| TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) {
|
| - AudioDiscardHelper discard_helper(kSampleRate);
|
| + AudioDiscardHelper discard_helper(kSampleRate, 0);
|
| ASSERT_FALSE(discard_helper.initialized());
|
|
|
| const base::TimeDelta kTimestamp = base::TimeDelta();
|
| @@ -108,7 +119,7 @@ TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) {
|
| }
|
|
|
| TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) {
|
| - AudioDiscardHelper discard_helper(kSampleRate);
|
| + AudioDiscardHelper discard_helper(kSampleRate, 0);
|
| ASSERT_FALSE(discard_helper.initialized());
|
|
|
| const base::TimeDelta kTimestamp = base::TimeDelta();
|
| @@ -138,7 +149,7 @@ TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) {
|
| }
|
|
|
| TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) {
|
| - AudioDiscardHelper discard_helper(kSampleRate);
|
| + AudioDiscardHelper discard_helper(kSampleRate, 0);
|
| ASSERT_FALSE(discard_helper.initialized());
|
|
|
| const base::TimeDelta kTimestamp = base::TimeDelta();
|
| @@ -163,8 +174,8 @@ TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) {
|
| EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
|
| }
|
|
|
| -TEST(AudioDiscardHelperTest, DiscardPadding) {
|
| - AudioDiscardHelper discard_helper(kSampleRate);
|
| +TEST(AudioDiscardHelperTest, DiscardEndPadding) {
|
| + AudioDiscardHelper discard_helper(kSampleRate, 0);
|
| ASSERT_FALSE(discard_helper.initialized());
|
|
|
| const base::TimeDelta kTimestamp = base::TimeDelta();
|
| @@ -176,7 +187,55 @@ TEST(AudioDiscardHelperTest, DiscardPadding) {
|
| scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
|
|
|
| // Set a discard padding equivalent to half the buffer.
|
| - encoded_buffer->set_discard_padding(kDuration / 2);
|
| + 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.
|
| + discard_helper.Reset(kTestFrames / 4);
|
|
|
| ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
|
| ASSERT_TRUE(discard_helper.initialized());
|
| @@ -186,7 +245,7 @@ TEST(AudioDiscardHelperTest, DiscardPadding) {
|
| }
|
|
|
| TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) {
|
| - AudioDiscardHelper discard_helper(kSampleRate);
|
| + AudioDiscardHelper discard_helper(kSampleRate, 0);
|
| ASSERT_FALSE(discard_helper.initialized());
|
|
|
| const base::TimeDelta kTimestamp = base::TimeDelta();
|
| @@ -198,7 +257,8 @@ TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) {
|
| scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
|
|
|
| // Set a discard padding equivalent to a quarter of the buffer.
|
| - encoded_buffer->set_discard_padding(kDuration / 4);
|
| + encoded_buffer->set_discard_padding(
|
| + std::make_pair(kDuration / 4, kDuration / 4));
|
|
|
| // Set an initial discard of a quarter of the buffer.
|
| discard_helper.Reset(kTestFrames / 4);
|
| @@ -206,9 +266,82 @@ TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) {
|
| ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
|
| ASSERT_TRUE(discard_helper.initialized());
|
| EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
|
| + EXPECT_EQ(kDuration / 4, decoded_buffer->duration());
|
| + EXPECT_EQ(kTestFrames / 4, decoded_buffer->frame_count());
|
| +}
|
| +
|
| +TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPaddingAndCodecDelay) {
|
| + // Use a codec delay of 5ms.
|
| + const int kCodecDelay = kSampleRate / 100 / 2;
|
| + AudioDiscardHelper discard_helper(kSampleRate, kCodecDelay);
|
| + ASSERT_FALSE(discard_helper.initialized());
|
| + discard_helper.Reset(kCodecDelay);
|
| +
|
| + 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 kCodecDelay 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(kCodecDelay * kDataStep,
|
| + ExtractDecodedData(decoded_buffer, kCodecDelay),
|
| + 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 a discard padding equivalent to a quarter of the buffer.
|
| + encoded_buffer->set_discard_padding(
|
| + std::make_pair(kDuration / 4, kDuration / 4));
|
| +
|
| + // Set an initial discard of a quarter of the buffer.
|
| + discard_helper.Reset(kTestFrames / 4);
|
| +
|
| + // 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 / 4, decoded_buffer->duration());
|
| + EXPECT_EQ(kTestFrames / 4, decoded_buffer->frame_count());
|
| +}
|
|
|
| } // namespace media
|
|
|