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 3 // found in the LICENSE file. 4 5 #include "base/memory/scoped_ptr.h" 6 #include "media/base/audio_buffer.h" 7 #include "media/base/audio_bus.h" 8 #include "media/base/audio_discard_helper.h" 9 #include "media/base/buffers.h" 10 #include "media/base/decoder_buffer.h" 11 #include "media/base/test_helpers.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 namespace media { 15 16 static const float kDataStep = 0.01f; 17 static const size_t kSampleRate = 48000; 18 19 static scoped_refptr<DecoderBuffer> CreateEncodedBuffer( 20 base::TimeDelta timestamp, 21 base::TimeDelta duration) { 22 scoped_refptr<DecoderBuffer> result(new DecoderBuffer(1)); 23 result->set_timestamp(timestamp); 24 result->set_duration(duration); 25 return result; 26 } 27 28 static scoped_refptr<AudioBuffer> CreateDecodedBuffer(int frames) { 29 return MakeAudioBuffer(kSampleFormatPlanarF32, 30 CHANNEL_LAYOUT_MONO, 31 1, 32 kSampleRate, 33 0.0f, 34 kDataStep, 35 frames, 36 kNoTimestamp()); 37 } 38 39 static float ExtractDecodedData(const scoped_refptr<AudioBuffer>& buffer, 40 int index) { 41 // This is really inefficient, but we can't access the raw AudioBuffer if any 42 // start trimming has been applied. 43 scoped_ptr<AudioBus> temp_bus = AudioBus::Create(buffer->channel_count(), 1); 44 buffer->ReadFrames(1, index, 0, temp_bus.get()); 45 return temp_bus->channel(0)[0]; 46 } 47 48 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) { 49 AudioDiscardHelper discard_helper(kSampleRate, 0); 50 51 EXPECT_EQ(0u, discard_helper.TimeDeltaToFrames(base::TimeDelta())); 52 EXPECT_EQ( 53 kSampleRate / 100, 54 discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10))); 55 56 // Ensure partial frames are rounded down correctly. The equation below 57 // calculates a frame count with a fractional part < 0.5. 58 const int small_remainder = 59 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate; 60 EXPECT_EQ(kSampleRate - 1, 61 discard_helper.TimeDeltaToFrames( 62 base::TimeDelta::FromMicroseconds(small_remainder))); 63 64 // Ditto, but rounded up using a fractional part > 0.5. 65 const int large_remainder = 66 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.4) / kSampleRate; 67 EXPECT_EQ(kSampleRate, 68 discard_helper.TimeDeltaToFrames( 69 base::TimeDelta::FromMicroseconds(large_remainder))); 70 } 71 72 TEST(AudioDiscardHelperTest, BasicProcessBuffers) { 73 AudioDiscardHelper discard_helper(kSampleRate, 0); 74 ASSERT_FALSE(discard_helper.initialized()); 75 76 const base::TimeDelta kTimestamp = base::TimeDelta(); 77 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. 80 const base::TimeDelta kEstimatedDuration = 81 base::TimeDelta::FromMilliseconds(9); 82 const base::TimeDelta kActualDuration = base::TimeDelta::FromMilliseconds(10); 83 const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration); 84 85 scoped_refptr<DecoderBuffer> encoded_buffer = 86 CreateEncodedBuffer(kTimestamp, kEstimatedDuration); 87 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 88 89 // Verify the basic case where nothing is discarded. 90 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 91 ASSERT_TRUE(discard_helper.initialized()); 92 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 93 EXPECT_EQ(kActualDuration, decoded_buffer->duration()); 94 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); 95 96 // Verify a Reset() takes us back to an uninitialized state. 97 discard_helper.Reset(0); 98 ASSERT_FALSE(discard_helper.initialized()); 99 100 // Verify a NULL output buffer returns false. 101 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL)); 102 } 103 104 TEST(AudioDiscardHelperTest, NegativeTimestampClampsToZero) { 105 AudioDiscardHelper discard_helper(kSampleRate, 0); 106 ASSERT_FALSE(discard_helper.initialized()); 107 108 const base::TimeDelta kTimestamp = -base::TimeDelta::FromSeconds(1); 109 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 110 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 111 112 scoped_refptr<DecoderBuffer> encoded_buffer = 113 CreateEncodedBuffer(kTimestamp, kDuration); 114 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 115 116 // Verify the basic case where nothing is discarded. 117 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 118 ASSERT_TRUE(discard_helper.initialized()); 119 EXPECT_EQ(base::TimeDelta(), decoded_buffer->timestamp()); 120 EXPECT_EQ(kDuration, decoded_buffer->duration()); 121 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); 122 } 123 124 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) { 125 AudioDiscardHelper discard_helper(kSampleRate, 0); 126 ASSERT_FALSE(discard_helper.initialized()); 127 128 const base::TimeDelta kTimestamp = base::TimeDelta(); 129 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 130 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 131 132 // Tell the helper we want to discard half of the initial frames. 133 const int kDiscardFrames = kTestFrames / 2; 134 discard_helper.Reset(kDiscardFrames); 135 136 scoped_refptr<DecoderBuffer> encoded_buffer = 137 CreateEncodedBuffer(kTimestamp, kDuration); 138 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 139 140 // Verify half the frames end up discarded. 141 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 142 ASSERT_TRUE(discard_helper.initialized()); 143 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 144 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 145 EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count()); 146 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep, 147 ExtractDecodedData(decoded_buffer, 0)); 148 } 149 150 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) { 151 AudioDiscardHelper discard_helper(kSampleRate, 0); 152 ASSERT_FALSE(discard_helper.initialized()); 153 154 const base::TimeDelta kTimestamp = base::TimeDelta(); 155 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 156 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 157 158 // Tell the helper we want to discard 1.5 buffers worth of frames. 159 discard_helper.Reset(kTestFrames * 1.5); 160 161 scoped_refptr<DecoderBuffer> encoded_buffer = 162 CreateEncodedBuffer(kTimestamp, kDuration); 163 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 164 165 // The first call should fail since no output buffer remains. 166 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 167 ASSERT_TRUE(discard_helper.initialized()); 168 169 // Generate another set of buffers and expect half the output frames. 170 encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration); 171 decoded_buffer = CreateDecodedBuffer(kTestFrames); 172 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 173 174 // The timestamp should match that of the initial buffer. 175 const int kDiscardFrames = kTestFrames / 2; 176 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 177 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 178 EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count()); 179 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep, 180 ExtractDecodedData(decoded_buffer, 0)); 181 } 182 183 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) { 184 AudioDiscardHelper discard_helper(kSampleRate, 0); 185 ASSERT_FALSE(discard_helper.initialized()); 186 187 const base::TimeDelta kTimestamp = base::TimeDelta(); 188 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 189 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 190 191 scoped_refptr<DecoderBuffer> encoded_buffer = 192 CreateEncodedBuffer(kTimestamp, kDuration); 193 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 194 195 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 196 ASSERT_TRUE(discard_helper.initialized()); 197 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 198 EXPECT_EQ(kDuration, decoded_buffer->duration()); 199 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); 200 201 // Process the same input buffer again to ensure input timestamps which go 202 // backwards in time are not errors. 203 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 204 EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp()); 205 EXPECT_EQ(kDuration, decoded_buffer->duration()); 206 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); 207 } 208 209 TEST(AudioDiscardHelperTest, DiscardEndPadding) { 210 AudioDiscardHelper discard_helper(kSampleRate, 0); 211 ASSERT_FALSE(discard_helper.initialized()); 212 213 const base::TimeDelta kTimestamp = base::TimeDelta(); 214 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 215 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 216 217 scoped_refptr<DecoderBuffer> encoded_buffer = 218 CreateEncodedBuffer(kTimestamp, kDuration); 219 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 220 221 // Set a discard padding equivalent to half the buffer. 222 encoded_buffer->set_discard_padding( 223 std::make_pair(base::TimeDelta(), kDuration / 2)); 224 225 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 226 ASSERT_TRUE(discard_helper.initialized()); 227 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 228 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 229 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); 230 } 231 232 TEST(AudioDiscardHelperTest, BadDiscardEndPadding) { 233 AudioDiscardHelper discard_helper(kSampleRate, 0); 234 ASSERT_FALSE(discard_helper.initialized()); 235 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(); 258 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 259 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 260 261 scoped_refptr<DecoderBuffer> encoded_buffer = 262 CreateEncodedBuffer(kTimestamp, kDuration); 263 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 264 265 // Set a discard padding equivalent to a quarter of the buffer. 266 encoded_buffer->set_discard_padding( 267 std::make_pair(base::TimeDelta(), kDuration / 4)); 268 269 // Set an initial discard of a quarter of the buffer. 270 const int kDiscardFrames = kTestFrames / 4; 271 discard_helper.Reset(kDiscardFrames); 272 273 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 274 ASSERT_TRUE(discard_helper.initialized()); 275 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 276 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 277 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); 278 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep, 279 ExtractDecodedData(decoded_buffer, 0)); 280 } 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 all the discard values to be different to ensure each is properly used. 295 const int kDiscardFrames = kTestFrames / 4; 296 encoded_buffer->set_discard_padding( 297 std::make_pair(kDuration / 8, kDuration / 16)); 298 discard_helper.Reset(kDiscardFrames); 299 300 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 301 ASSERT_TRUE(discard_helper.initialized()); 302 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 303 EXPECT_EQ(kDuration - kDuration / 4 - kDuration / 8 - kDuration / 16, 304 decoded_buffer->duration()); 305 EXPECT_EQ(kTestFrames - kTestFrames / 4 - kTestFrames / 8 - kTestFrames / 16, 306 decoded_buffer->frame_count()); 307 } 308 309 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPaddingAndDecoderDelay) { 310 // Use a decoder delay of 5ms. 311 const int kDecoderDelay = kSampleRate / 100 / 2; 312 AudioDiscardHelper discard_helper(kSampleRate, kDecoderDelay); 313 ASSERT_FALSE(discard_helper.initialized()); 314 discard_helper.Reset(kDecoderDelay); 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, half from the inital delay and 329 // another half from the front discard padding. 330 // 331 // Encoded Discard Delay 332 // |--------| |---------| |----| 333 // |AAAAAAAA| --> |....|AAAA| --> |AAAA| -------> NULL 334 // |--------| |---------| |----| 335 // Decoded Discard Front Padding 336 // 337 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 338 ASSERT_TRUE(discard_helper.initialized()); 339 340 // Processing another buffer that has front discard set to half the buffer's 341 // duration should discard the back half of the buffer since kDecoderDelay is 342 // half a buffer. The end padding should not be discarded until another 343 // buffer is processed. kDuration / 4 is chosen for the end discard since it 344 // will force the end discard to start after position zero within the next 345 // decoded buffer. 346 // 347 // Encoded Discard Front Padding (from B) 348 // |--------| |---------| |----| 349 // |BBBBBBBB| --> |AAAA|BBBB| ----------> |AAAA| 350 // |--------| |---------| |----| 351 // Decoded 352 // (includes carryover from A) 353 // 354 encoded_buffer->set_timestamp(encoded_buffer->timestamp() + kDuration); 355 encoded_buffer->set_discard_padding( 356 std::make_pair(kDuration / 2, kDuration / 4)); 357 decoded_buffer = CreateDecodedBuffer(kTestFrames); 358 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0)); 359 ASSERT_NEAR(kDecoderDelay * kDataStep, 360 ExtractDecodedData(decoded_buffer, kDecoderDelay), 361 kDataStep / 1000); 362 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 363 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 364 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 365 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); 366 367 // Verify it was actually the latter half of the buffer that was removed. 368 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0)); 369 370 // Verify the end discard padding is carried over to the next buffer. Use 371 // kDuration / 2 for the end discard padding so that the next buffer has its 372 // start entirely discarded. 373 // 374 // Encoded Discard End Padding (from B) 375 // |--------| |---------| |-------| 376 // |CCCCCCCC| --> |BBBB|CCCC| ----------> |BB|CCCC| 377 // |--------| |---------| |-------| 378 // Decoded 379 // (includes carryover from B) 380 // 381 encoded_buffer->set_timestamp(encoded_buffer->timestamp() + kDuration); 382 encoded_buffer->set_discard_padding( 383 std::make_pair(base::TimeDelta(), kDuration / 2)); 384 decoded_buffer = CreateDecodedBuffer(kTestFrames); 385 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 386 EXPECT_EQ(kTimestamp + kDuration / 2, decoded_buffer->timestamp()); 387 EXPECT_EQ(3 * kDuration / 4, decoded_buffer->duration()); 388 EXPECT_EQ(3 * kTestFrames / 4, decoded_buffer->frame_count()); 389 390 // Verify it was actually the second quarter of the buffer that was removed. 391 const int kDiscardFrames = kTestFrames / 4; 392 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0)); 393 ASSERT_FLOAT_EQ( 394 kDiscardFrames * 2 * kDataStep, 395 ExtractDecodedData(decoded_buffer, kDecoderDelay - kDiscardFrames)); 396 397 // One last test to ensure carryover discard from the start works. 398 // 399 // Encoded Discard End Padding (from C) 400 // |--------| |---------| |----| 401 // |DDDDDDDD| --> |CCCC|DDDD| ----------> |DDDD| 402 // |--------| |---------| |----| 403 // Decoded 404 // (includes carryover from C) 405 // 406 encoded_buffer->set_timestamp(encoded_buffer->timestamp() + kDuration); 407 encoded_buffer->set_discard_padding(DecoderBuffer::DiscardPadding()); 408 decoded_buffer = CreateDecodedBuffer(kTestFrames); 409 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0)); 410 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 411 EXPECT_EQ(kTimestamp + kDuration / 2 + 3 * kDuration / 4, 412 decoded_buffer->timestamp()); 413 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 414 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); 415 ASSERT_FLOAT_EQ(kTestFrames / 2 * kDataStep, 416 ExtractDecodedData(decoded_buffer, 0)); 417 } 418 419 TEST(AudioDiscardHelperTest, DelayedDiscardInitialDiscardAndDiscardPadding) { 420 AudioDiscardHelper discard_helper(kSampleRate, 0); 421 ASSERT_FALSE(discard_helper.initialized()); 422 423 const base::TimeDelta kTimestamp = base::TimeDelta(); 424 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 425 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 426 427 scoped_refptr<DecoderBuffer> encoded_buffer = 428 CreateEncodedBuffer(kTimestamp, kDuration); 429 430 // Set all the discard values to be different to ensure each is properly used. 431 const int kDiscardFrames = kTestFrames / 4; 432 encoded_buffer->set_discard_padding( 433 std::make_pair(kDuration / 8, kDuration / 16)); 434 discard_helper.Reset(kDiscardFrames); 435 436 // Verify nothing is output for the first buffer, yet initialized is true. 437 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL)); 438 ASSERT_TRUE(discard_helper.initialized()); 439 440 // Create an encoded buffer with no discard padding. 441 encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration); 442 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 443 444 // Verify that when the decoded buffer is consumed, the discards from the 445 // previous encoded buffer are applied. 446 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 447 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 448 EXPECT_EQ(kDuration - kDuration / 4 - kDuration / 8 - kDuration / 16, 449 decoded_buffer->duration()); 450 EXPECT_EQ(kTestFrames - kTestFrames / 4 - kTestFrames / 8 - kTestFrames / 16, 451 decoded_buffer->frame_count()); 452 } 453 454 TEST(AudioDiscardHelperTest, CompleteDiscard) { 455 AudioDiscardHelper discard_helper(kSampleRate, 0); 456 ASSERT_FALSE(discard_helper.initialized()); 457 458 const base::TimeDelta kTimestamp = base::TimeDelta(); 459 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 460 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 461 discard_helper.Reset(0); 462 463 scoped_refptr<DecoderBuffer> encoded_buffer = 464 CreateEncodedBuffer(kTimestamp, kDuration); 465 encoded_buffer->set_discard_padding( 466 std::make_pair(kInfiniteDuration(), base::TimeDelta())); 467 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 468 469 // Verify all of the first buffer is discarded. 470 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 471 ASSERT_TRUE(discard_helper.initialized()); 472 encoded_buffer->set_timestamp(kTimestamp + kDuration); 473 encoded_buffer->set_discard_padding(DecoderBuffer::DiscardPadding()); 474 475 // Verify a second buffer goes through untouched. 476 decoded_buffer = CreateDecodedBuffer(kTestFrames / 2); 477 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 478 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 479 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 480 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); 481 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0)); 482 } 483 484 TEST(AudioDiscardHelperTest, CompleteDiscardWithDelayedDiscard) { 485 AudioDiscardHelper discard_helper(kSampleRate, 0); 486 ASSERT_FALSE(discard_helper.initialized()); 487 488 const base::TimeDelta kTimestamp = base::TimeDelta(); 489 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 490 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 491 discard_helper.Reset(0); 492 493 scoped_refptr<DecoderBuffer> encoded_buffer = 494 CreateEncodedBuffer(kTimestamp, kDuration); 495 encoded_buffer->set_discard_padding( 496 std::make_pair(kInfiniteDuration(), base::TimeDelta())); 497 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 498 499 // Setup a delayed discard. 500 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL)); 501 ASSERT_TRUE(discard_helper.initialized()); 502 503 // Verify the first output buffer is dropped. 504 encoded_buffer->set_timestamp(kTimestamp + kDuration); 505 encoded_buffer->set_discard_padding(DecoderBuffer::DiscardPadding()); 506 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 507 508 // Verify the second buffer goes through untouched. 509 encoded_buffer->set_timestamp(kTimestamp + 2 * kDuration); 510 decoded_buffer = CreateDecodedBuffer(kTestFrames / 2); 511 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 512 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 513 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 514 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); 515 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0)); 516 } 517 518 TEST(AudioDiscardHelperTest, CompleteDiscardWithInitialDiscardDecoderDelay) { 519 // Use a decoder delay of 5ms. 520 const int kDecoderDelay = kSampleRate / 100 / 2; 521 AudioDiscardHelper discard_helper(kSampleRate, kDecoderDelay); 522 ASSERT_FALSE(discard_helper.initialized()); 523 discard_helper.Reset(kDecoderDelay); 524 525 const base::TimeDelta kTimestamp = base::TimeDelta(); 526 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 527 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 528 529 scoped_refptr<DecoderBuffer> encoded_buffer = 530 CreateEncodedBuffer(kTimestamp, kDuration); 531 encoded_buffer->set_discard_padding( 532 std::make_pair(kInfiniteDuration(), base::TimeDelta())); 533 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 534 535 // Verify all of the first buffer is discarded. 536 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 537 ASSERT_TRUE(discard_helper.initialized()); 538 encoded_buffer->set_timestamp(kTimestamp + kDuration); 539 encoded_buffer->set_discard_padding(DecoderBuffer::DiscardPadding()); 540 541 // Verify 5ms off the front of the second buffer is discarded. 542 decoded_buffer = CreateDecodedBuffer(kTestFrames * 2); 543 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 544 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 545 EXPECT_EQ(kDuration * 2 - kDuration / 2, decoded_buffer->duration()); 546 EXPECT_EQ(kTestFrames * 2 - kDecoderDelay, decoded_buffer->frame_count()); 547 ASSERT_FLOAT_EQ(kDecoderDelay * kDataStep, 548 ExtractDecodedData(decoded_buffer, 0)); 549 } 550 551 } // namespace media 552