| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/memory/scoped_ptr.h" | 5 #include "base/memory/scoped_ptr.h" |
| 6 #include "media/base/audio_buffer.h" | 6 #include "media/base/audio_buffer.h" |
| 7 #include "media/base/audio_bus.h" |
| 7 #include "media/base/audio_discard_helper.h" | 8 #include "media/base/audio_discard_helper.h" |
| 8 #include "media/base/buffers.h" | 9 #include "media/base/buffers.h" |
| 9 #include "media/base/decoder_buffer.h" | 10 #include "media/base/decoder_buffer.h" |
| 10 #include "media/base/test_helpers.h" | 11 #include "media/base/test_helpers.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 12 | 13 |
| 13 namespace media { | 14 namespace media { |
| 14 | 15 |
| 16 static const float kDataStep = 0.01f; |
| 15 static const int kSampleRate = 48000; | 17 static const int kSampleRate = 48000; |
| 16 | 18 |
| 17 static scoped_refptr<DecoderBuffer> CreateEncodedBuffer( | 19 static scoped_refptr<DecoderBuffer> CreateEncodedBuffer( |
| 18 base::TimeDelta timestamp, | 20 base::TimeDelta timestamp, |
| 19 base::TimeDelta duration) { | 21 base::TimeDelta duration) { |
| 20 scoped_refptr<DecoderBuffer> result(new DecoderBuffer(1)); | 22 scoped_refptr<DecoderBuffer> result(new DecoderBuffer(1)); |
| 21 result->set_timestamp(timestamp); | 23 result->set_timestamp(timestamp); |
| 22 result->set_duration(duration); | 24 result->set_duration(duration); |
| 23 return result; | 25 return result; |
| 24 } | 26 } |
| 25 | 27 |
| 26 static scoped_refptr<AudioBuffer> CreateDecodedBuffer(int frames) { | 28 static scoped_refptr<AudioBuffer> CreateDecodedBuffer(int frames) { |
| 27 return MakeAudioBuffer(kSampleFormatPlanarF32, | 29 return MakeAudioBuffer(kSampleFormatPlanarF32, |
| 28 CHANNEL_LAYOUT_MONO, | 30 CHANNEL_LAYOUT_MONO, |
| 29 1, | 31 1, |
| 30 kSampleRate, | 32 kSampleRate, |
| 31 0.0f, | 33 0.0f, |
| 32 0.01f, | 34 kDataStep, |
| 33 frames, | 35 frames, |
| 34 kNoTimestamp(), | 36 kNoTimestamp(), |
| 35 kNoTimestamp()); | 37 kNoTimestamp()); |
| 36 } | 38 } |
| 37 | 39 |
| 40 static float ExtractDecodedData(const scoped_refptr<AudioBuffer>& buffer, |
| 41 int index) { |
| 42 // This is really inefficient, but we can't access the raw AudioBuffer if any |
| 43 // start trimming has been applied. |
| 44 scoped_ptr<AudioBus> temp_bus = AudioBus::Create(buffer->channel_count(), 1); |
| 45 buffer->ReadFrames(1, index, 0, temp_bus.get()); |
| 46 return temp_bus->channel(0)[0]; |
| 47 } |
| 48 |
| 38 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) { | 49 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) { |
| 39 AudioDiscardHelper discard_helper(kSampleRate); | 50 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 40 | 51 |
| 41 EXPECT_EQ(0, discard_helper.TimeDeltaToFrames(base::TimeDelta())); | 52 EXPECT_EQ(0, discard_helper.TimeDeltaToFrames(base::TimeDelta())); |
| 42 EXPECT_EQ( | 53 EXPECT_EQ( |
| 43 kSampleRate / 100, | 54 kSampleRate / 100, |
| 44 discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10))); | 55 discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10))); |
| 45 | 56 |
| 46 // Ensure partial frames are always rounded up. The equation below calculates | 57 // Ensure partial frames are always rounded up. The equation below calculates |
| 47 // a frame count with a fractional part < 0.5. | 58 // a frame count with a fractional part < 0.5. |
| 48 const int small_remainder = | 59 const int small_remainder = |
| 49 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate; | 60 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate; |
| 50 EXPECT_EQ(kSampleRate, | 61 EXPECT_EQ(kSampleRate, |
| 51 discard_helper.TimeDeltaToFrames( | 62 discard_helper.TimeDeltaToFrames( |
| 52 base::TimeDelta::FromMicroseconds(small_remainder))); | 63 base::TimeDelta::FromMicroseconds(small_remainder))); |
| 53 } | 64 } |
| 54 | 65 |
| 55 TEST(AudioDiscardHelperTest, BasicProcessBuffers) { | 66 TEST(AudioDiscardHelperTest, BasicProcessBuffers) { |
| 56 AudioDiscardHelper discard_helper(kSampleRate); | 67 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 57 ASSERT_FALSE(discard_helper.initialized()); | 68 ASSERT_FALSE(discard_helper.initialized()); |
| 58 | 69 |
| 59 const base::TimeDelta kTimestamp = base::TimeDelta(); | 70 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 60 | 71 |
| 61 // Use an estimated duration which doesn't match the number of decoded frames | 72 // Use an estimated duration which doesn't match the number of decoded frames |
| 62 // to ensure the helper is correctly setting durations based on output frames. | 73 // to ensure the helper is correctly setting durations based on output frames. |
| 63 const base::TimeDelta kEstimatedDuration = | 74 const base::TimeDelta kEstimatedDuration = |
| 64 base::TimeDelta::FromMilliseconds(9); | 75 base::TimeDelta::FromMilliseconds(9); |
| 65 const base::TimeDelta kActualDuration = base::TimeDelta::FromMilliseconds(10); | 76 const base::TimeDelta kActualDuration = base::TimeDelta::FromMilliseconds(10); |
| 66 const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration); | 77 const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 78 | 89 |
| 79 // Verify a Reset() takes us back to an uninitialized state. | 90 // Verify a Reset() takes us back to an uninitialized state. |
| 80 discard_helper.Reset(0); | 91 discard_helper.Reset(0); |
| 81 ASSERT_FALSE(discard_helper.initialized()); | 92 ASSERT_FALSE(discard_helper.initialized()); |
| 82 | 93 |
| 83 // Verify a NULL output buffer returns false. | 94 // Verify a NULL output buffer returns false. |
| 84 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL)); | 95 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL)); |
| 85 } | 96 } |
| 86 | 97 |
| 87 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) { | 98 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) { |
| 88 AudioDiscardHelper discard_helper(kSampleRate); | 99 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 89 ASSERT_FALSE(discard_helper.initialized()); | 100 ASSERT_FALSE(discard_helper.initialized()); |
| 90 | 101 |
| 91 const base::TimeDelta kTimestamp = base::TimeDelta(); | 102 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 92 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | 103 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 93 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | 104 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 94 | 105 |
| 95 // Tell the helper we want to discard half of the initial frames. | 106 // Tell the helper we want to discard half of the initial frames. |
| 96 discard_helper.Reset(kTestFrames / 2); | 107 discard_helper.Reset(kTestFrames / 2); |
| 97 | 108 |
| 98 scoped_refptr<DecoderBuffer> encoded_buffer = | 109 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 99 CreateEncodedBuffer(kTimestamp, kDuration); | 110 CreateEncodedBuffer(kTimestamp, kDuration); |
| 100 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | 111 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 101 | 112 |
| 102 // Verify half the frames end up discarded. | 113 // Verify half the frames end up discarded. |
| 103 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 114 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 104 ASSERT_TRUE(discard_helper.initialized()); | 115 ASSERT_TRUE(discard_helper.initialized()); |
| 105 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | 116 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 106 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); | 117 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); |
| 107 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); | 118 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); |
| 108 } | 119 } |
| 109 | 120 |
| 110 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) { | 121 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) { |
| 111 AudioDiscardHelper discard_helper(kSampleRate); | 122 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 112 ASSERT_FALSE(discard_helper.initialized()); | 123 ASSERT_FALSE(discard_helper.initialized()); |
| 113 | 124 |
| 114 const base::TimeDelta kTimestamp = base::TimeDelta(); | 125 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 115 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | 126 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 116 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | 127 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 117 | 128 |
| 118 // Tell the helper we want to discard 1.5 buffers worth of frames. | 129 // Tell the helper we want to discard 1.5 buffers worth of frames. |
| 119 discard_helper.Reset(kTestFrames * 1.5); | 130 discard_helper.Reset(kTestFrames * 1.5); |
| 120 | 131 |
| 121 scoped_refptr<DecoderBuffer> encoded_buffer = | 132 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 122 CreateEncodedBuffer(kTimestamp, kDuration); | 133 CreateEncodedBuffer(kTimestamp, kDuration); |
| 123 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | 134 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 124 | 135 |
| 125 // The first call should fail since no output buffer remains. | 136 // The first call should fail since no output buffer remains. |
| 126 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 137 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 127 ASSERT_TRUE(discard_helper.initialized()); | 138 ASSERT_TRUE(discard_helper.initialized()); |
| 128 | 139 |
| 129 // Generate another set of buffers and expect half the output frames. | 140 // Generate another set of buffers and expect half the output frames. |
| 130 encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration); | 141 encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration); |
| 131 decoded_buffer = CreateDecodedBuffer(kTestFrames); | 142 decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 132 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 143 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 133 | 144 |
| 134 // The timestamp should match that of the initial buffer. | 145 // The timestamp should match that of the initial buffer. |
| 135 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | 146 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 136 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); | 147 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); |
| 137 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); | 148 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); |
| 138 } | 149 } |
| 139 | 150 |
| 140 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) { | 151 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) { |
| 141 AudioDiscardHelper discard_helper(kSampleRate); | 152 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 142 ASSERT_FALSE(discard_helper.initialized()); | 153 ASSERT_FALSE(discard_helper.initialized()); |
| 143 | 154 |
| 144 const base::TimeDelta kTimestamp = base::TimeDelta(); | 155 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 145 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | 156 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 146 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | 157 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 147 | 158 |
| 148 scoped_refptr<DecoderBuffer> encoded_buffer = | 159 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 149 CreateEncodedBuffer(kTimestamp, kDuration); | 160 CreateEncodedBuffer(kTimestamp, kDuration); |
| 150 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | 161 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 151 | 162 |
| 152 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 163 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 153 ASSERT_TRUE(discard_helper.initialized()); | 164 ASSERT_TRUE(discard_helper.initialized()); |
| 154 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | 165 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 155 EXPECT_EQ(kDuration, decoded_buffer->duration()); | 166 EXPECT_EQ(kDuration, decoded_buffer->duration()); |
| 156 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); | 167 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); |
| 157 | 168 |
| 158 // Process the same input buffer again to ensure input timestamps which go | 169 // Process the same input buffer again to ensure input timestamps which go |
| 159 // backwards in time are not errors. | 170 // backwards in time are not errors. |
| 160 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 171 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 161 EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp()); | 172 EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp()); |
| 162 EXPECT_EQ(kDuration, decoded_buffer->duration()); | 173 EXPECT_EQ(kDuration, decoded_buffer->duration()); |
| 163 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); | 174 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); |
| 164 } | 175 } |
| 165 | 176 |
| 166 TEST(AudioDiscardHelperTest, DiscardPadding) { | 177 TEST(AudioDiscardHelperTest, DiscardEndPadding) { |
| 167 AudioDiscardHelper discard_helper(kSampleRate); | 178 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 168 ASSERT_FALSE(discard_helper.initialized()); | 179 ASSERT_FALSE(discard_helper.initialized()); |
| 169 | 180 |
| 170 const base::TimeDelta kTimestamp = base::TimeDelta(); | 181 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 171 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | 182 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 172 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | 183 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 173 | 184 |
| 174 scoped_refptr<DecoderBuffer> encoded_buffer = | 185 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 175 CreateEncodedBuffer(kTimestamp, kDuration); | 186 CreateEncodedBuffer(kTimestamp, kDuration); |
| 176 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | 187 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 177 | 188 |
| 178 // Set a discard padding equivalent to half the buffer. | 189 // Set a discard padding equivalent to half the buffer. |
| 179 encoded_buffer->set_discard_padding(kDuration / 2); | 190 encoded_buffer->set_discard_padding( |
| 191 std::make_pair(base::TimeDelta(), kDuration / 2)); |
| 180 | 192 |
| 181 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 193 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 182 ASSERT_TRUE(discard_helper.initialized()); | 194 ASSERT_TRUE(discard_helper.initialized()); |
| 195 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 196 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); |
| 197 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); |
| 198 } |
| 199 |
| 200 TEST(AudioDiscardHelperTest, BadDiscardEndPadding) { |
| 201 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 202 ASSERT_FALSE(discard_helper.initialized()); |
| 203 |
| 204 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 205 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 206 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 207 |
| 208 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 209 CreateEncodedBuffer(kTimestamp, kDuration); |
| 210 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 211 |
| 212 // Set a discard padding equivalent to double the buffer size. |
| 213 encoded_buffer->set_discard_padding( |
| 214 std::make_pair(base::TimeDelta(), kDuration * 2)); |
| 215 |
| 216 // Verify the end discard padding is rejected. |
| 217 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 218 ASSERT_TRUE(discard_helper.initialized()); |
| 219 } |
| 220 |
| 221 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardEndPadding) { |
| 222 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 223 ASSERT_FALSE(discard_helper.initialized()); |
| 224 |
| 225 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 226 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 227 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 228 |
| 229 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 230 CreateEncodedBuffer(kTimestamp, kDuration); |
| 231 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 232 |
| 233 // Set a discard padding equivalent to a quarter of the buffer. |
| 234 encoded_buffer->set_discard_padding( |
| 235 std::make_pair(base::TimeDelta(), kDuration / 4)); |
| 236 |
| 237 // Set an initial discard of a quarter of the buffer. |
| 238 discard_helper.Reset(kTestFrames / 4); |
| 239 |
| 240 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 241 ASSERT_TRUE(discard_helper.initialized()); |
| 183 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | 242 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 184 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); | 243 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); |
| 185 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); | 244 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); |
| 186 } | 245 } |
| 187 | 246 |
| 188 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) { | 247 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) { |
| 189 AudioDiscardHelper discard_helper(kSampleRate); | 248 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 190 ASSERT_FALSE(discard_helper.initialized()); | 249 ASSERT_FALSE(discard_helper.initialized()); |
| 191 | 250 |
| 192 const base::TimeDelta kTimestamp = base::TimeDelta(); | 251 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 193 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | 252 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 194 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | 253 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 195 | 254 |
| 196 scoped_refptr<DecoderBuffer> encoded_buffer = | 255 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 197 CreateEncodedBuffer(kTimestamp, kDuration); | 256 CreateEncodedBuffer(kTimestamp, kDuration); |
| 198 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | 257 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 199 | 258 |
| 200 // Set a discard padding equivalent to a quarter of the buffer. | 259 // Set a discard padding equivalent to a quarter of the buffer. |
| 201 encoded_buffer->set_discard_padding(kDuration / 4); | 260 encoded_buffer->set_discard_padding( |
| 261 std::make_pair(kDuration / 4, kDuration / 4)); |
| 202 | 262 |
| 203 // Set an initial discard of a quarter of the buffer. | 263 // Set an initial discard of a quarter of the buffer. |
| 204 discard_helper.Reset(kTestFrames / 4); | 264 discard_helper.Reset(kTestFrames / 4); |
| 205 | 265 |
| 206 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 266 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 207 ASSERT_TRUE(discard_helper.initialized()); | 267 ASSERT_TRUE(discard_helper.initialized()); |
| 208 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | 268 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 269 EXPECT_EQ(kDuration / 4, decoded_buffer->duration()); |
| 270 EXPECT_EQ(kTestFrames / 4, decoded_buffer->frame_count()); |
| 271 } |
| 272 |
| 273 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPaddingAndCodecDelay) { |
| 274 // Use a codec delay of 5ms. |
| 275 const int kCodecDelay = kSampleRate / 100 / 2; |
| 276 AudioDiscardHelper discard_helper(kSampleRate, kCodecDelay); |
| 277 ASSERT_FALSE(discard_helper.initialized()); |
| 278 discard_helper.Reset(kCodecDelay); |
| 279 |
| 280 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 281 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 282 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 283 |
| 284 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 285 CreateEncodedBuffer(kTimestamp, kDuration); |
| 286 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 287 |
| 288 // Set a discard padding equivalent to half of the buffer. |
| 289 encoded_buffer->set_discard_padding( |
| 290 std::make_pair(kDuration / 2, base::TimeDelta())); |
| 291 |
| 292 // All of the first buffer should be discarded. |
| 293 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 294 ASSERT_TRUE(discard_helper.initialized()); |
| 295 |
| 296 // Processing another buffer (with the same discard padding) should discard |
| 297 // the back half of the buffer since kCodecDelay is half a buffer. |
| 298 encoded_buffer->set_timestamp(kTimestamp + kDuration); |
| 299 decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 300 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0)); |
| 301 ASSERT_NEAR(kCodecDelay * kDataStep, |
| 302 ExtractDecodedData(decoded_buffer, kCodecDelay), |
| 303 kDataStep * 1000); |
| 304 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 305 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 209 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); | 306 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); |
| 210 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); | 307 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); |
| 308 |
| 309 // Verify it was actually the latter half of the buffer that was removed. |
| 310 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0)); |
| 211 } | 311 } |
| 212 | 312 |
| 313 TEST(AudioDiscardHelperTest, DelayedDiscardInitialDiscardAndDiscardPadding) { |
| 314 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 315 ASSERT_FALSE(discard_helper.initialized()); |
| 316 |
| 317 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 318 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 319 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 320 |
| 321 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 322 CreateEncodedBuffer(kTimestamp, kDuration); |
| 323 |
| 324 // Set a discard padding equivalent to a quarter of the buffer. |
| 325 encoded_buffer->set_discard_padding( |
| 326 std::make_pair(kDuration / 4, kDuration / 4)); |
| 327 |
| 328 // Set an initial discard of a quarter of the buffer. |
| 329 discard_helper.Reset(kTestFrames / 4); |
| 330 |
| 331 // Verify nothing is output for the first buffer, yet initialized is true. |
| 332 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL)); |
| 333 ASSERT_TRUE(discard_helper.initialized()); |
| 334 |
| 335 // Create an encoded buffer with no discard padding. |
| 336 encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration); |
| 337 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 338 |
| 339 // Verify that when the decoded buffer is consumed, the discards from the |
| 340 // previous encoded buffer are applied. |
| 341 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 342 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 343 EXPECT_EQ(kDuration / 4, decoded_buffer->duration()); |
| 344 EXPECT_EQ(kTestFrames / 4, decoded_buffer->frame_count()); |
| 345 } |
| 213 | 346 |
| 214 } // namespace media | 347 } // namespace media |
| OLD | NEW |