Chromium Code Reviews| 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_bus.h" |
| 8 #include "media/base/audio_discard_helper.h" | 8 #include "media/base/audio_discard_helper.h" |
| 9 #include "media/base/buffers.h" | 9 #include "media/base/buffers.h" |
| 10 #include "media/base/decoder_buffer.h" | 10 #include "media/base/decoder_buffer.h" |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 static float ExtractDecodedData(const scoped_refptr<AudioBuffer>& buffer, | 39 static float ExtractDecodedData(const scoped_refptr<AudioBuffer>& buffer, |
| 40 int index) { | 40 int index) { |
| 41 // This is really inefficient, but we can't access the raw AudioBuffer if any | 41 // This is really inefficient, but we can't access the raw AudioBuffer if any |
| 42 // start trimming has been applied. | 42 // start trimming has been applied. |
| 43 scoped_ptr<AudioBus> temp_bus = AudioBus::Create(buffer->channel_count(), 1); | 43 scoped_ptr<AudioBus> temp_bus = AudioBus::Create(buffer->channel_count(), 1); |
| 44 buffer->ReadFrames(1, index, 0, temp_bus.get()); | 44 buffer->ReadFrames(1, index, 0, temp_bus.get()); |
| 45 return temp_bus->channel(0)[0]; | 45 return temp_bus->channel(0)[0]; |
| 46 } | 46 } |
| 47 | 47 |
| 48 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) { | 48 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) { |
| 49 AudioDiscardHelper discard_helper(kSampleRate); | 49 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 50 | 50 |
| 51 EXPECT_EQ(0u, discard_helper.TimeDeltaToFrames(base::TimeDelta())); | 51 EXPECT_EQ(0u, discard_helper.TimeDeltaToFrames(base::TimeDelta())); |
| 52 EXPECT_EQ( | 52 EXPECT_EQ( |
| 53 kSampleRate / 100, | 53 kSampleRate / 100, |
| 54 discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10))); | 54 discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10))); |
| 55 | 55 |
| 56 // Ensure partial frames are rounded down correctly. The equation below | 56 // Ensure partial frames are rounded down correctly. The equation below |
| 57 // calculates a frame count with a fractional part < 0.5. | 57 // calculates a frame count with a fractional part < 0.5. |
| 58 const int small_remainder = | 58 const int small_remainder = |
| 59 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate; | 59 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate; |
| 60 EXPECT_EQ(kSampleRate - 1, | 60 EXPECT_EQ(kSampleRate - 1, |
| 61 discard_helper.TimeDeltaToFrames( | 61 discard_helper.TimeDeltaToFrames( |
| 62 base::TimeDelta::FromMicroseconds(small_remainder))); | 62 base::TimeDelta::FromMicroseconds(small_remainder))); |
| 63 | 63 |
| 64 // Ditto, but rounded up using a fractional part > 0.5. | 64 // Ditto, but rounded up using a fractional part > 0.5. |
| 65 const int large_remainder = | 65 const int large_remainder = |
| 66 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.4) / kSampleRate; | 66 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.4) / kSampleRate; |
| 67 EXPECT_EQ(kSampleRate, | 67 EXPECT_EQ(kSampleRate, |
| 68 discard_helper.TimeDeltaToFrames( | 68 discard_helper.TimeDeltaToFrames( |
| 69 base::TimeDelta::FromMicroseconds(large_remainder))); | 69 base::TimeDelta::FromMicroseconds(large_remainder))); |
| 70 } | 70 } |
| 71 | 71 |
| 72 TEST(AudioDiscardHelperTest, BasicProcessBuffers) { | 72 TEST(AudioDiscardHelperTest, BasicProcessBuffers) { |
| 73 AudioDiscardHelper discard_helper(kSampleRate); | 73 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 74 ASSERT_FALSE(discard_helper.initialized()); | 74 ASSERT_FALSE(discard_helper.initialized()); |
| 75 | 75 |
| 76 const base::TimeDelta kTimestamp = base::TimeDelta(); | 76 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 77 | 77 |
| 78 // Use an estimated duration which doesn't match the number of decoded frames | 78 // Use an estimated duration which doesn't match the number of decoded frames |
| 79 // to ensure the helper is correctly setting durations based on output frames. | 79 // to ensure the helper is correctly setting durations based on output frames. |
| 80 const base::TimeDelta kEstimatedDuration = | 80 const base::TimeDelta kEstimatedDuration = |
| 81 base::TimeDelta::FromMilliseconds(9); | 81 base::TimeDelta::FromMilliseconds(9); |
| 82 const base::TimeDelta kActualDuration = base::TimeDelta::FromMilliseconds(10); | 82 const base::TimeDelta kActualDuration = base::TimeDelta::FromMilliseconds(10); |
| 83 const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration); | 83 const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 95 | 95 |
| 96 // Verify a Reset() takes us back to an uninitialized state. | 96 // Verify a Reset() takes us back to an uninitialized state. |
| 97 discard_helper.Reset(0); | 97 discard_helper.Reset(0); |
| 98 ASSERT_FALSE(discard_helper.initialized()); | 98 ASSERT_FALSE(discard_helper.initialized()); |
| 99 | 99 |
| 100 // Verify a NULL output buffer returns false. | 100 // Verify a NULL output buffer returns false. |
| 101 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL)); | 101 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL)); |
| 102 } | 102 } |
| 103 | 103 |
| 104 TEST(AudioDiscardHelperTest, NegativeTimestampClampsToZero) { | 104 TEST(AudioDiscardHelperTest, NegativeTimestampClampsToZero) { |
| 105 AudioDiscardHelper discard_helper(kSampleRate); | 105 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 106 ASSERT_FALSE(discard_helper.initialized()); | 106 ASSERT_FALSE(discard_helper.initialized()); |
| 107 | 107 |
| 108 const base::TimeDelta kTimestamp = -base::TimeDelta::FromSeconds(1); | 108 const base::TimeDelta kTimestamp = -base::TimeDelta::FromSeconds(1); |
| 109 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | 109 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 110 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | 110 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 111 | 111 |
| 112 scoped_refptr<DecoderBuffer> encoded_buffer = | 112 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 113 CreateEncodedBuffer(kTimestamp, kDuration); | 113 CreateEncodedBuffer(kTimestamp, kDuration); |
| 114 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | 114 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 115 | 115 |
| 116 // Verify the basic case where nothing is discarded. | 116 // Verify the basic case where nothing is discarded. |
| 117 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 117 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 118 ASSERT_TRUE(discard_helper.initialized()); | 118 ASSERT_TRUE(discard_helper.initialized()); |
| 119 EXPECT_EQ(base::TimeDelta(), decoded_buffer->timestamp()); | 119 EXPECT_EQ(base::TimeDelta(), decoded_buffer->timestamp()); |
| 120 EXPECT_EQ(kDuration, decoded_buffer->duration()); | 120 EXPECT_EQ(kDuration, decoded_buffer->duration()); |
| 121 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); | 121 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); |
| 122 } | 122 } |
| 123 | 123 |
| 124 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) { | 124 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) { |
| 125 AudioDiscardHelper discard_helper(kSampleRate); | 125 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 126 ASSERT_FALSE(discard_helper.initialized()); | 126 ASSERT_FALSE(discard_helper.initialized()); |
| 127 | 127 |
| 128 const base::TimeDelta kTimestamp = base::TimeDelta(); | 128 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 129 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | 129 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 130 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | 130 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 131 | 131 |
| 132 // Tell the helper we want to discard half of the initial frames. | 132 // Tell the helper we want to discard half of the initial frames. |
| 133 const int kDiscardFrames = kTestFrames / 2; | 133 const int kDiscardFrames = kTestFrames / 2; |
| 134 discard_helper.Reset(kDiscardFrames); | 134 discard_helper.Reset(kDiscardFrames); |
| 135 | 135 |
| 136 scoped_refptr<DecoderBuffer> encoded_buffer = | 136 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 137 CreateEncodedBuffer(kTimestamp, kDuration); | 137 CreateEncodedBuffer(kTimestamp, kDuration); |
| 138 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | 138 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 139 | 139 |
| 140 // Verify half the frames end up discarded. | 140 // Verify half the frames end up discarded. |
| 141 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 141 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 142 ASSERT_TRUE(discard_helper.initialized()); | 142 ASSERT_TRUE(discard_helper.initialized()); |
| 143 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | 143 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 144 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); | 144 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); |
| 145 EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count()); | 145 EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count()); |
| 146 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep, | 146 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep, |
| 147 ExtractDecodedData(decoded_buffer, 0)); | 147 ExtractDecodedData(decoded_buffer, 0)); |
| 148 } | 148 } |
| 149 | 149 |
| 150 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) { | 150 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) { |
| 151 AudioDiscardHelper discard_helper(kSampleRate); | 151 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 152 ASSERT_FALSE(discard_helper.initialized()); | 152 ASSERT_FALSE(discard_helper.initialized()); |
| 153 | 153 |
| 154 const base::TimeDelta kTimestamp = base::TimeDelta(); | 154 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 155 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | 155 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 156 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | 156 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 157 | 157 |
| 158 // Tell the helper we want to discard 1.5 buffers worth of frames. | 158 // Tell the helper we want to discard 1.5 buffers worth of frames. |
| 159 discard_helper.Reset(kTestFrames * 1.5); | 159 discard_helper.Reset(kTestFrames * 1.5); |
| 160 | 160 |
| 161 scoped_refptr<DecoderBuffer> encoded_buffer = | 161 scoped_refptr<DecoderBuffer> encoded_buffer = |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 174 // The timestamp should match that of the initial buffer. | 174 // The timestamp should match that of the initial buffer. |
| 175 const int kDiscardFrames = kTestFrames / 2; | 175 const int kDiscardFrames = kTestFrames / 2; |
| 176 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | 176 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 177 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); | 177 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); |
| 178 EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count()); | 178 EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count()); |
| 179 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep, | 179 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep, |
| 180 ExtractDecodedData(decoded_buffer, 0)); | 180 ExtractDecodedData(decoded_buffer, 0)); |
| 181 } | 181 } |
| 182 | 182 |
| 183 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) { | 183 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) { |
| 184 AudioDiscardHelper discard_helper(kSampleRate); | 184 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 185 ASSERT_FALSE(discard_helper.initialized()); | 185 ASSERT_FALSE(discard_helper.initialized()); |
| 186 | 186 |
| 187 const base::TimeDelta kTimestamp = base::TimeDelta(); | 187 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 188 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | 188 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 189 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | 189 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 190 | 190 |
| 191 scoped_refptr<DecoderBuffer> encoded_buffer = | 191 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 192 CreateEncodedBuffer(kTimestamp, kDuration); | 192 CreateEncodedBuffer(kTimestamp, kDuration); |
| 193 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | 193 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 194 | 194 |
| 195 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 195 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 196 ASSERT_TRUE(discard_helper.initialized()); | 196 ASSERT_TRUE(discard_helper.initialized()); |
| 197 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | 197 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 198 EXPECT_EQ(kDuration, decoded_buffer->duration()); | 198 EXPECT_EQ(kDuration, decoded_buffer->duration()); |
| 199 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); | 199 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); |
| 200 | 200 |
| 201 // Process the same input buffer again to ensure input timestamps which go | 201 // Process the same input buffer again to ensure input timestamps which go |
| 202 // backwards in time are not errors. | 202 // backwards in time are not errors. |
| 203 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 203 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 204 EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp()); | 204 EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp()); |
| 205 EXPECT_EQ(kDuration, decoded_buffer->duration()); | 205 EXPECT_EQ(kDuration, decoded_buffer->duration()); |
| 206 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); | 206 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); |
| 207 } | 207 } |
| 208 | 208 |
| 209 TEST(AudioDiscardHelperTest, DiscardPadding) { | 209 TEST(AudioDiscardHelperTest, DiscardEndPadding) { |
| 210 AudioDiscardHelper discard_helper(kSampleRate); | 210 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 211 ASSERT_FALSE(discard_helper.initialized()); | 211 ASSERT_FALSE(discard_helper.initialized()); |
| 212 | 212 |
| 213 const base::TimeDelta kTimestamp = base::TimeDelta(); | 213 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 214 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | 214 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 215 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | 215 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 216 | 216 |
| 217 scoped_refptr<DecoderBuffer> encoded_buffer = | 217 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 218 CreateEncodedBuffer(kTimestamp, kDuration); | 218 CreateEncodedBuffer(kTimestamp, kDuration); |
| 219 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | 219 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 220 | 220 |
| 221 // Set a discard padding equivalent to half the buffer. | 221 // Set a discard padding equivalent to half the buffer. |
| 222 encoded_buffer->set_discard_padding(kDuration / 2); | 222 encoded_buffer->set_discard_padding( |
| 223 std::make_pair(base::TimeDelta(), kDuration / 2)); | |
| 223 | 224 |
| 224 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 225 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 225 ASSERT_TRUE(discard_helper.initialized()); | 226 ASSERT_TRUE(discard_helper.initialized()); |
| 226 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | 227 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 227 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); | 228 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); |
| 228 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); | 229 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); |
| 229 ASSERT_FLOAT_EQ(0, ExtractDecodedData(decoded_buffer, 0)); | |
| 230 } | 230 } |
| 231 | 231 |
| 232 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) { | 232 TEST(AudioDiscardHelperTest, BadDiscardEndPadding) { |
| 233 AudioDiscardHelper discard_helper(kSampleRate); | 233 AudioDiscardHelper discard_helper(kSampleRate, 0); |
| 234 ASSERT_FALSE(discard_helper.initialized()); | 234 ASSERT_FALSE(discard_helper.initialized()); |
| 235 | 235 |
| 236 const base::TimeDelta kTimestamp = base::TimeDelta(); | 236 const base::TimeDelta kTimestamp = base::TimeDelta(); |
| 237 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | |
| 238 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | |
| 239 | |
| 240 scoped_refptr<DecoderBuffer> encoded_buffer = | |
| 241 CreateEncodedBuffer(kTimestamp, kDuration); | |
| 242 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | |
| 243 | |
| 244 // Set a discard padding equivalent to double the buffer size. | |
| 245 encoded_buffer->set_discard_padding( | |
| 246 std::make_pair(base::TimeDelta(), kDuration * 2)); | |
| 247 | |
| 248 // Verify the end discard padding is rejected. | |
| 249 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | |
| 250 ASSERT_TRUE(discard_helper.initialized()); | |
| 251 } | |
| 252 | |
| 253 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardEndPadding) { | |
| 254 AudioDiscardHelper discard_helper(kSampleRate, 0); | |
| 255 ASSERT_FALSE(discard_helper.initialized()); | |
| 256 | |
| 257 const base::TimeDelta kTimestamp = base::TimeDelta(); | |
| 237 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | 258 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); |
| 238 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | 259 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); |
| 239 | 260 |
| 240 scoped_refptr<DecoderBuffer> encoded_buffer = | 261 scoped_refptr<DecoderBuffer> encoded_buffer = |
| 241 CreateEncodedBuffer(kTimestamp, kDuration); | 262 CreateEncodedBuffer(kTimestamp, kDuration); |
| 242 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | 263 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); |
| 243 | 264 |
| 244 // Set a discard padding equivalent to a quarter of the buffer. | 265 // Set a discard padding equivalent to a quarter of the buffer. |
| 245 encoded_buffer->set_discard_padding(kDuration / 4); | 266 encoded_buffer->set_discard_padding( |
| 267 std::make_pair(base::TimeDelta(), kDuration / 4)); | |
| 246 | 268 |
| 247 // Set an initial discard of a quarter of the buffer. | 269 // Set an initial discard of a quarter of the buffer. |
| 248 const int kDiscardFrames = kTestFrames / 4; | 270 const int kDiscardFrames = kTestFrames / 4; |
| 249 discard_helper.Reset(kDiscardFrames); | 271 discard_helper.Reset(kDiscardFrames); |
| 250 | 272 |
| 251 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | 273 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); |
| 252 ASSERT_TRUE(discard_helper.initialized()); | 274 ASSERT_TRUE(discard_helper.initialized()); |
| 253 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | 275 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); |
| 254 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); | 276 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); |
| 255 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); | 277 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); |
| 256 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep, | 278 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep, |
| 257 ExtractDecodedData(decoded_buffer, 0)); | 279 ExtractDecodedData(decoded_buffer, 0)); |
| 258 } | 280 } |
| 259 | 281 |
| 282 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) { | |
| 283 AudioDiscardHelper discard_helper(kSampleRate, 0); | |
| 284 ASSERT_FALSE(discard_helper.initialized()); | |
| 285 | |
| 286 const base::TimeDelta kTimestamp = base::TimeDelta(); | |
| 287 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | |
| 288 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | |
| 289 | |
| 290 scoped_refptr<DecoderBuffer> encoded_buffer = | |
| 291 CreateEncodedBuffer(kTimestamp, kDuration); | |
| 292 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | |
| 293 | |
| 294 // Set a discard padding equivalent to a quarter of the buffer. | |
| 295 encoded_buffer->set_discard_padding( | |
| 296 std::make_pair(kDuration / 4, kDuration / 4)); | |
|
acolwell GONE FROM CHROMIUM
2014/05/01 01:08:34
How about using different fractions for the start,
DaleCurtis
2014/05/01 19:21:27
Done.
| |
| 297 | |
| 298 // Set an initial discard of a quarter of the buffer. | |
| 299 const int kDiscardFrames = kTestFrames / 4; | |
| 300 discard_helper.Reset(kDiscardFrames); | |
| 301 | |
| 302 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | |
| 303 ASSERT_TRUE(discard_helper.initialized()); | |
| 304 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | |
| 305 EXPECT_EQ(kDuration / 4, decoded_buffer->duration()); | |
| 306 EXPECT_EQ(kTestFrames / 4, decoded_buffer->frame_count()); | |
| 307 } | |
| 308 | |
| 309 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPaddingAndCodecDelay) { | |
| 310 // Use a codec delay of 5ms. | |
| 311 const int kCodecDelay = kSampleRate / 100 / 2; | |
|
acolwell GONE FROM CHROMIUM
2014/05/01 01:08:34
How about making this 80ms, but keeping the 10ms d
DaleCurtis
2014/05/01 19:21:27
As discussed this doesn't apply for opus and for c
| |
| 312 AudioDiscardHelper discard_helper(kSampleRate, kCodecDelay); | |
| 313 ASSERT_FALSE(discard_helper.initialized()); | |
| 314 discard_helper.Reset(kCodecDelay); | |
| 315 | |
| 316 const base::TimeDelta kTimestamp = base::TimeDelta(); | |
| 317 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | |
| 318 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | |
| 319 | |
| 320 scoped_refptr<DecoderBuffer> encoded_buffer = | |
| 321 CreateEncodedBuffer(kTimestamp, kDuration); | |
| 322 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | |
| 323 | |
| 324 // Set a discard padding equivalent to half of the buffer. | |
| 325 encoded_buffer->set_discard_padding( | |
| 326 std::make_pair(kDuration / 2, base::TimeDelta())); | |
| 327 | |
| 328 // All of the first buffer should be discarded. | |
| 329 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | |
| 330 ASSERT_TRUE(discard_helper.initialized()); | |
| 331 | |
| 332 // Processing another buffer (with the same discard padding) should discard | |
| 333 // the back half of the buffer since kCodecDelay is half a buffer. | |
| 334 encoded_buffer->set_timestamp(kTimestamp + kDuration); | |
| 335 decoded_buffer = CreateDecodedBuffer(kTestFrames); | |
| 336 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0)); | |
| 337 ASSERT_NEAR(kCodecDelay * kDataStep, | |
| 338 ExtractDecodedData(decoded_buffer, kCodecDelay), | |
| 339 kDataStep * 1000); | |
| 340 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | |
| 341 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | |
| 342 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); | |
| 343 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); | |
| 344 | |
| 345 // Verify it was actually the latter half of the buffer that was removed. | |
| 346 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0)); | |
| 347 } | |
| 348 | |
| 349 TEST(AudioDiscardHelperTest, DelayedDiscardInitialDiscardAndDiscardPadding) { | |
| 350 AudioDiscardHelper discard_helper(kSampleRate, 0); | |
| 351 ASSERT_FALSE(discard_helper.initialized()); | |
| 352 | |
| 353 const base::TimeDelta kTimestamp = base::TimeDelta(); | |
| 354 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); | |
| 355 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); | |
| 356 | |
| 357 scoped_refptr<DecoderBuffer> encoded_buffer = | |
| 358 CreateEncodedBuffer(kTimestamp, kDuration); | |
| 359 | |
| 360 // Set a discard padding equivalent to a quarter of the buffer. | |
| 361 encoded_buffer->set_discard_padding( | |
| 362 std::make_pair(kDuration / 4, kDuration / 4)); | |
|
acolwell GONE FROM CHROMIUM
2014/05/01 01:08:34
Ditto w/ respect to using different fractions here
DaleCurtis
2014/05/01 19:21:27
Done.
| |
| 363 | |
| 364 // Set an initial discard of a quarter of the buffer. | |
| 365 discard_helper.Reset(kTestFrames / 4); | |
| 366 | |
| 367 // Verify nothing is output for the first buffer, yet initialized is true. | |
| 368 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL)); | |
| 369 ASSERT_TRUE(discard_helper.initialized()); | |
| 370 | |
| 371 // Create an encoded buffer with no discard padding. | |
| 372 encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration); | |
| 373 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); | |
| 374 | |
| 375 // Verify that when the decoded buffer is consumed, the discards from the | |
| 376 // previous encoded buffer are applied. | |
| 377 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); | |
| 378 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); | |
| 379 EXPECT_EQ(kDuration / 4, decoded_buffer->duration()); | |
| 380 EXPECT_EQ(kTestFrames / 4, decoded_buffer->frame_count()); | |
| 381 } | |
| 382 | |
| 260 } // namespace media | 383 } // namespace media |
| OLD | NEW |