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 |