1 // Copyright (c) 2012 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_splicer.h" 9 #include "media/base/audio_timestamp_helper.h" 10 #include "media/base/buffers.h" 11 #include "media/base/test_helpers.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 namespace media { 15 16 // Do not change this format. AddInput() and GetValue() only work with float. 17 static const SampleFormat kSampleFormat = kSampleFormatF32; 18 COMPILE_ASSERT(kSampleFormat == kSampleFormatF32, invalid_splice_format); 19 20 static const int kChannels = 1; 21 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_MONO; 22 static const int kDefaultSampleRate = 44100; 23 static const int kDefaultBufferSize = 100; 24 25 class AudioSplicerTest : public ::testing::Test { 26 public: 27 AudioSplicerTest() 28 : splicer_(kDefaultSampleRate), 29 input_timestamp_helper_(kDefaultSampleRate) { 30 input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta()); 31 } 32 33 scoped_refptr<AudioBuffer> GetNextInputBuffer(float value) { 34 return GetNextInputBuffer(value, kDefaultBufferSize); 35 } 36 37 scoped_refptr<AudioBuffer> GetNextInputBuffer(float value, int frame_size) { 38 scoped_refptr<AudioBuffer> buffer = 39 MakeAudioBuffer<float>(kSampleFormat, 40 kChannelLayout, 41 kChannels, 42 kDefaultSampleRate, 43 value, 44 0.0f, 45 frame_size, 46 input_timestamp_helper_.GetTimestamp()); 47 input_timestamp_helper_.AddFrames(frame_size); 48 return buffer; 49 } 50 51 float GetValue(const scoped_refptr<AudioBuffer>& buffer) { 52 return reinterpret_cast<const float*>(buffer->channel_data()[0])[0]; 53 } 54 55 bool VerifyData(const scoped_refptr<AudioBuffer>& buffer, float value) { 56 int frames = buffer->frame_count(); 57 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, frames); 58 buffer->ReadFrames(frames, 0, 0, bus.get()); 59 for (int ch = 0; ch < buffer->channel_count(); ++ch) { 60 for (int i = 0; i < frames; ++i) { 61 if (bus->channel(ch)[i] != value) 62 return false; 63 } 64 } 65 return true; 66 } 67 68 void VerifyNextBuffer(const scoped_refptr<AudioBuffer>& input) { 69 ASSERT_TRUE(splicer_.HasNextBuffer()); 70 scoped_refptr<AudioBuffer> output = splicer_.GetNextBuffer(); 71 EXPECT_EQ(input->timestamp(), output->timestamp()); 72 EXPECT_EQ(input->duration(), output->duration()); 73 EXPECT_EQ(input->frame_count(), output->frame_count()); 74 EXPECT_TRUE(VerifyData(output, GetValue(input))); 75 } 76 77 void VerifyPreSpliceOutput( 78 const scoped_refptr<AudioBuffer>& overlapped_buffer, 79 const scoped_refptr<AudioBuffer>& overlapping_buffer, 80 int expected_pre_splice_size, 81 base::TimeDelta expected_pre_splice_duration) { 82 ASSERT_TRUE(splicer_.HasNextBuffer()); 83 scoped_refptr<AudioBuffer> pre_splice_output = splicer_.GetNextBuffer(); 84 EXPECT_EQ(overlapped_buffer->timestamp(), pre_splice_output->timestamp()); 85 EXPECT_EQ(expected_pre_splice_size, pre_splice_output->frame_count()); 86 EXPECT_EQ(expected_pre_splice_duration, pre_splice_output->duration()); 87 EXPECT_TRUE(VerifyData(pre_splice_output, GetValue(overlapped_buffer))); 88 } 89 90 void VerifyCrossfadeOutput( 91 const scoped_refptr<AudioBuffer>& overlapped_buffer_1, 92 const scoped_refptr<AudioBuffer>& overlapped_buffer_2, 93 const scoped_refptr<AudioBuffer>& overlapping_buffer, 94 int second_overlap_index, 95 int expected_crossfade_size, 96 base::TimeDelta expected_crossfade_duration) { 97 ASSERT_TRUE(splicer_.HasNextBuffer()); 98 99 scoped_refptr<AudioBuffer> crossfade_output = splicer_.GetNextBuffer(); 100 EXPECT_EQ(expected_crossfade_size, crossfade_output->frame_count()); 101 EXPECT_EQ(expected_crossfade_duration, crossfade_output->duration()); 102 103 // The splice timestamp may be adjusted by a microsecond. 104 EXPECT_NEAR(overlapping_buffer->timestamp().InMicroseconds(), 105 crossfade_output->timestamp().InMicroseconds(), 106 1); 107 108 // Verify the actual crossfade. 109 const int frames = crossfade_output->frame_count(); 110 float overlapped_value = GetValue(overlapped_buffer_1); 111 const float overlapping_value = GetValue(overlapping_buffer); 112 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, frames); 113 crossfade_output->ReadFrames(frames, 0, 0, bus.get()); 114 for (int ch = 0; ch < crossfade_output->channel_count(); ++ch) { 115 float cf_ratio = 0; 116 const float cf_increment = 1.0f / frames; 117 for (int i = 0; i < frames; ++i, cf_ratio += cf_increment) { 118 if (overlapped_buffer_2.get() && i >= second_overlap_index) 119 overlapped_value = GetValue(overlapped_buffer_2); 120 const float actual = bus->channel(ch)[i]; 121 const float expected = 122 (1.0f - cf_ratio) * overlapped_value + cf_ratio * overlapping_value; 123 ASSERT_FLOAT_EQ(expected, actual) << "i=" << i; 124 } 125 } 126 } 127 128 bool AddInput(const scoped_refptr<AudioBuffer>& input) { 129 // Since the splicer doesn't make copies it's working directly on the input 130 // buffers. We must make a copy before adding to ensure the original buffer 131 // is not modified in unexpected ways. 132 scoped_refptr<AudioBuffer> buffer_copy = 133 input->end_of_stream() 134 ? AudioBuffer::CreateEOSBuffer() 135 : AudioBuffer::CopyFrom(kSampleFormat, 136 input->channel_layout(), 137 input->channel_count(), 138 input->sample_rate(), 139 input->frame_count(), 140 &input->channel_data()[0], 141 input->timestamp()); 142 return splicer_.AddInput(buffer_copy); 143 } 144 145 base::TimeDelta max_crossfade_duration() { 146 return splicer_.max_crossfade_duration_; 147 } 148 149 protected: 150 AudioSplicer splicer_; 151 AudioTimestampHelper input_timestamp_helper_; 152 153 DISALLOW_COPY_AND_ASSIGN(AudioSplicerTest); 154 }; 155 156 TEST_F(AudioSplicerTest, PassThru) { 157 EXPECT_FALSE(splicer_.HasNextBuffer()); 158 159 // Test single buffer pass-thru behavior. 160 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); 161 EXPECT_TRUE(AddInput(input_1)); 162 VerifyNextBuffer(input_1); 163 EXPECT_FALSE(splicer_.HasNextBuffer()); 164 165 // Test that multiple buffers can be queued in the splicer. 166 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); 167 scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f); 168 EXPECT_TRUE(AddInput(input_2)); 169 EXPECT_TRUE(AddInput(input_3)); 170 VerifyNextBuffer(input_2); 171 VerifyNextBuffer(input_3); 172 EXPECT_FALSE(splicer_.HasNextBuffer()); 173 } 174 175 TEST_F(AudioSplicerTest, Reset) { 176 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); 177 EXPECT_TRUE(AddInput(input_1)); 178 ASSERT_TRUE(splicer_.HasNextBuffer()); 179 180 splicer_.Reset(); 181 EXPECT_FALSE(splicer_.HasNextBuffer()); 182 183 // Add some bytes to the timestamp helper so that the 184 // next buffer starts many frames beyond the end of 185 // |input_1|. This is to make sure that Reset() actually 186 // clears its state and doesn't try to insert a gap. 187 input_timestamp_helper_.AddFrames(100); 188 189 // Verify that a new input buffer passes through as expected. 190 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); 191 EXPECT_TRUE(AddInput(input_2)); 192 VerifyNextBuffer(input_2); 193 EXPECT_FALSE(splicer_.HasNextBuffer()); 194 } 195 196 TEST_F(AudioSplicerTest, EndOfStream) { 197 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); 198 scoped_refptr<AudioBuffer> input_2 = AudioBuffer::CreateEOSBuffer(); 199 scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.2f); 200 EXPECT_TRUE(input_2->end_of_stream()); 201 202 EXPECT_TRUE(AddInput(input_1)); 203 EXPECT_TRUE(AddInput(input_2)); 204 205 VerifyNextBuffer(input_1); 206 207 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); 208 EXPECT_FALSE(splicer_.HasNextBuffer()); 209 EXPECT_TRUE(output_2->end_of_stream()); 210 211 // Verify that buffers can be added again after Reset(). 212 splicer_.Reset(); 213 EXPECT_TRUE(AddInput(input_3)); 214 VerifyNextBuffer(input_3); 215 EXPECT_FALSE(splicer_.HasNextBuffer()); 216 } 217 218 // Test the gap insertion code. 219 // +--------------+ +--------------+ 220 // |11111111111111| |22222222222222| 221 // +--------------+ +--------------+ 222 // Results in: 223 // +--------------+----+--------------+ 224 // |11111111111111|0000|22222222222222| 225 // +--------------+----+--------------+ 226 TEST_F(AudioSplicerTest, GapInsertion) { 227 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); 228 229 // Add bytes to the timestamp helper so that the next buffer 230 // will have a starting timestamp that indicates a gap is 231 // present. 232 const int kGapSize = 7; 233 input_timestamp_helper_.AddFrames(kGapSize); 234 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); 235 236 EXPECT_TRUE(AddInput(input_1)); 237 EXPECT_TRUE(AddInput(input_2)); 238 239 // Verify that the first input buffer passed through unmodified. 240 VerifyNextBuffer(input_1); 241 242 // Verify the contents of the gap buffer. 243 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); 244 base::TimeDelta gap_timestamp = 245 input_1->timestamp() + input_1->duration(); 246 base::TimeDelta gap_duration = input_2->timestamp() - gap_timestamp; 247 EXPECT_GT(gap_duration, base::TimeDelta()); 248 EXPECT_EQ(gap_timestamp, output_2->timestamp()); 249 EXPECT_NEAR( 250 gap_duration.InMicroseconds(), output_2->duration().InMicroseconds(), 1); 251 EXPECT_EQ(kGapSize, output_2->frame_count()); 252 EXPECT_TRUE(VerifyData(output_2, 0.0f)); 253 254 // Verify that the second input buffer passed through unmodified. 255 VerifyNextBuffer(input_2); 256 EXPECT_FALSE(splicer_.HasNextBuffer()); 257 } 258 259 // Test that an error is signalled when the gap between input buffers is 260 // too large. 261 TEST_F(AudioSplicerTest, GapTooLarge) { 262 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); 263 264 // Add a seconds worth of bytes so that an unacceptably large 265 // gap exists between |input_1| and |input_2|. 266 const int kGapSize = kDefaultSampleRate; 267 input_timestamp_helper_.AddFrames(kGapSize); 268 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); 269 270 EXPECT_TRUE(AddInput(input_1)); 271 EXPECT_FALSE(AddInput(input_2)); 272 273 VerifyNextBuffer(input_1); 274 275 // Verify that the second buffer is not available. 276 EXPECT_FALSE(splicer_.HasNextBuffer()); 277 278 // Reset the timestamp helper so it can generate a buffer that is 279 // right after |input_1|. 280 input_timestamp_helper_.SetBaseTimestamp( 281 input_1->timestamp() + input_1->duration()); 282 283 // Verify that valid buffers are still accepted. 284 scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f); 285 EXPECT_TRUE(AddInput(input_3)); 286 VerifyNextBuffer(input_3); 287 EXPECT_FALSE(splicer_.HasNextBuffer()); 288 } 289 290 // Verifies that an error is signalled if AddInput() is called 291 // with a timestamp that is earlier than the first buffer added. 292 TEST_F(AudioSplicerTest, BufferAddedBeforeBase) { 293 input_timestamp_helper_.SetBaseTimestamp( 294 base::TimeDelta::FromMicroseconds(10)); 295 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); 296 297 // Reset the timestamp helper so the next buffer will have a timestamp earlier 298 // than |input_1|. 299 input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta::FromSeconds(0)); 300 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.1f); 301 302 EXPECT_GT(input_1->timestamp(), input_2->timestamp()); 303 EXPECT_TRUE(AddInput(input_1)); 304 EXPECT_FALSE(AddInput(input_2)); 305 } 306 307 // Test when one buffer partially overlaps another. 308 // +--------------+ 309 // |11111111111111| 310 // +--------------+ 311 // +--------------+ 312 // |22222222222222| 313 // +--------------+ 314 // Results in: 315 // +--------------+----------+ 316 // |11111111111111|2222222222| 317 // +--------------+----------+ 318 TEST_F(AudioSplicerTest, PartialOverlap) { 319 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); 320 321 // Reset timestamp helper so that the next buffer will have a 322 // timestamp that starts in the middle of |input_1|. 323 const int kOverlapSize = input_1->frame_count() / 4; 324 input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp()); 325 input_timestamp_helper_.AddFrames(input_1->frame_count() - kOverlapSize); 326 327 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); 328 329 EXPECT_TRUE(AddInput(input_1)); 330 EXPECT_TRUE(AddInput(input_2)); 331 332 // Verify that the first input buffer passed through unmodified. 333 VerifyNextBuffer(input_1); 334 335 ASSERT_TRUE(splicer_.HasNextBuffer()); 336 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); 337 EXPECT_FALSE(splicer_.HasNextBuffer()); 338 339 // Verify that the second input buffer was truncated to only contain 340 // the samples that are after the end of |input_1|. 341 base::TimeDelta expected_timestamp = 342 input_1->timestamp() + input_1->duration(); 343 base::TimeDelta expected_duration = 344 (input_2->timestamp() + input_2->duration()) - expected_timestamp; 345 EXPECT_EQ(expected_timestamp, output_2->timestamp()); 346 EXPECT_EQ(expected_duration, output_2->duration()); 347 EXPECT_TRUE(VerifyData(output_2, GetValue(input_2))); 348 } 349 350 // Test that an input buffer that is completely overlapped by a buffer 351 // that was already added is dropped. 352 // +--------------+ 353 // |11111111111111| 354 // +--------------+ 355 // +-----+ 356 // |22222| 357 // +-----+ 358 // +-------------+ 359 // |3333333333333| 360 // +-------------+ 361 // Results in: 362 // +--------------+-------------+ 363 // |11111111111111|3333333333333| 364 // +--------------+-------------+ 365 TEST_F(AudioSplicerTest, DropBuffer) { 366 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); 367 368 // Reset timestamp helper so that the next buffer will have a 369 // timestamp that starts in the middle of |input_1|. 370 const int kOverlapOffset = input_1->frame_count() / 2; 371 const int kOverlapSize = input_1->frame_count() / 4; 372 input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp()); 373 input_timestamp_helper_.AddFrames(kOverlapOffset); 374 375 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f, kOverlapSize); 376 377 // Reset the timestamp helper so the next buffer will be right after 378 // |input_1|. 379 input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp()); 380 input_timestamp_helper_.AddFrames(input_1->frame_count()); 381 scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f); 382 383 EXPECT_TRUE(AddInput(input_1)); 384 EXPECT_TRUE(AddInput(input_2)); 385 EXPECT_TRUE(AddInput(input_3)); 386 387 VerifyNextBuffer(input_1); 388 VerifyNextBuffer(input_3); 389 EXPECT_FALSE(splicer_.HasNextBuffer()); 390 } 391 392 // Test crossfade when one buffer partially overlaps another. 393 // +--------------+ 394 // |11111111111111| 395 // +--------------+ 396 // +--------------+ 397 // |22222222222222| 398 // +--------------+ 399 // Results in: 400 // +----------+----+----------+ 401 // |1111111111|xxxx|2222222222| 402 // +----------+----+----------+ 403 // Where "xxxx" represents the crossfaded portion of the signal. 404 TEST_F(AudioSplicerTest, PartialOverlapCrossfade) { 405 const int kCrossfadeSize = 406 input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()); 407 const int kBufferSize = kCrossfadeSize * 2; 408 409 scoped_refptr<AudioBuffer> extra_pre_splice_buffer = 410 GetNextInputBuffer(0.2f, kBufferSize); 411 scoped_refptr<AudioBuffer> overlapped_buffer = 412 GetNextInputBuffer(1.0f, kBufferSize); 413 414 // Reset timestamp helper so that the next buffer will have a timestamp that 415 // starts in the middle of |overlapped_buffer|. 416 input_timestamp_helper_.SetBaseTimestamp(overlapped_buffer->timestamp()); 417 input_timestamp_helper_.AddFrames(overlapped_buffer->frame_count() - 418 kCrossfadeSize); 419 splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp()); 420 scoped_refptr<AudioBuffer> overlapping_buffer = 421 GetNextInputBuffer(0.0f, kBufferSize); 422 423 // |extra_pre_splice_buffer| is entirely before the splice and should be ready 424 // for output. 425 EXPECT_TRUE(AddInput(extra_pre_splice_buffer)); 426 VerifyNextBuffer(extra_pre_splice_buffer); 427 428 // The splicer should be internally queuing input since |overlapped_buffer| is 429 // part of the splice. 430 EXPECT_TRUE(AddInput(overlapped_buffer)); 431 EXPECT_FALSE(splicer_.HasNextBuffer()); 432 433 // |overlapping_buffer| completes the splice. 434 splicer_.SetSpliceTimestamp(kNoTimestamp()); 435 EXPECT_TRUE(AddInput(overlapping_buffer)); 436 ASSERT_TRUE(splicer_.HasNextBuffer()); 437 438 // Add one more buffer to make sure it's passed through untouched. 439 scoped_refptr<AudioBuffer> extra_post_splice_buffer = 440 GetNextInputBuffer(0.5f, kBufferSize); 441 EXPECT_TRUE(AddInput(extra_post_splice_buffer)); 442 443 VerifyPreSpliceOutput(overlapped_buffer, 444 overlapping_buffer, 445 221, 446 base::TimeDelta::FromMicroseconds(5011)); 447 448 // Due to rounding the crossfade size may vary by up to a frame. 449 const int kExpectedCrossfadeSize = 220; 450 EXPECT_NEAR(kExpectedCrossfadeSize, kCrossfadeSize, 1); 451 452 VerifyCrossfadeOutput(overlapped_buffer, 453 NULL, 454 overlapping_buffer, 455 0, 456 kExpectedCrossfadeSize, 457 base::TimeDelta::FromMicroseconds(4988)); 458 459 // Retrieve the remaining portion after crossfade. 460 ASSERT_TRUE(splicer_.HasNextBuffer()); 461 scoped_refptr<AudioBuffer> post_splice_output = splicer_.GetNextBuffer(); 462 EXPECT_EQ(base::TimeDelta::FromMicroseconds(20022), 463 post_splice_output->timestamp()); 464 EXPECT_EQ(overlapping_buffer->frame_count() - kExpectedCrossfadeSize, 465 post_splice_output->frame_count()); 466 EXPECT_EQ(base::TimeDelta::FromMicroseconds(5034), 467 post_splice_output->duration()); 468 469 EXPECT_TRUE(VerifyData(post_splice_output, GetValue(overlapping_buffer))); 470 471 VerifyNextBuffer(extra_post_splice_buffer); 472 EXPECT_FALSE(splicer_.HasNextBuffer()); 473 } 474 475 // Test crossfade when one buffer partially overlaps another, but an end of 476 // stream buffer is received before the crossfade duration is reached. 477 // +--------------+ 478 // |11111111111111| 479 // +--------------+ 480 // +---------++---+ 481 // |222222222||EOS| 482 // +---------++---+ 483 // Results in: 484 // +----------+----+----++---+ 485 // |1111111111|xxxx|2222||EOS| 486 // +----------+----+----++---+ 487 // Where "x" represents the crossfaded portion of the signal. 488 TEST_F(AudioSplicerTest, PartialOverlapCrossfadeEndOfStream) { 489 const int kCrossfadeSize = 490 input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()); 491 492 scoped_refptr<AudioBuffer> overlapped_buffer = 493 GetNextInputBuffer(1.0f, kCrossfadeSize * 2); 494 495 // Reset timestamp helper so that the next buffer will have a timestamp that 496 // starts 3/4 of the way into |overlapped_buffer|. 497 input_timestamp_helper_.SetBaseTimestamp(overlapped_buffer->timestamp()); 498 input_timestamp_helper_.AddFrames(3 * overlapped_buffer->frame_count() / 4); 499 splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp()); 500 scoped_refptr<AudioBuffer> overlapping_buffer = 501 GetNextInputBuffer(0.0f, kCrossfadeSize / 3); 502 503 // The splicer should be internally queuing input since |overlapped_buffer| is 504 // part of the splice. 505 EXPECT_TRUE(AddInput(overlapped_buffer)); 506 EXPECT_FALSE(splicer_.HasNextBuffer()); 507 508 // |overlapping_buffer| should not have enough data to complete the splice, so 509 // ensure output is not available. 510 splicer_.SetSpliceTimestamp(kNoTimestamp()); 511 EXPECT_TRUE(AddInput(overlapping_buffer)); 512 EXPECT_FALSE(splicer_.HasNextBuffer()); 513 514 // Now add an EOS buffer which should complete the splice. 515 EXPECT_TRUE(AddInput(AudioBuffer::CreateEOSBuffer())); 516 517 VerifyPreSpliceOutput(overlapped_buffer, 518 overlapping_buffer, 519 331, 520 base::TimeDelta::FromMicroseconds(7505)); 521 VerifyCrossfadeOutput(overlapped_buffer, 522 NULL, 523 overlapping_buffer, 524 0, 525 overlapping_buffer->frame_count(), 526 overlapping_buffer->duration()); 527 528 // Ensure the last buffer is an EOS buffer. 529 ASSERT_TRUE(splicer_.HasNextBuffer()); 530 scoped_refptr<AudioBuffer> post_splice_output = splicer_.GetNextBuffer(); 531 EXPECT_TRUE(post_splice_output->end_of_stream()); 532 533 EXPECT_FALSE(splicer_.HasNextBuffer()); 534 } 535 536 // Test crossfade when one buffer partially overlaps another, but the amount of 537 // overlapped data is less than the crossfade duration. 538 // +------------+ 539 // |111111111111| 540 // +------------+ 541 // +--------------+ 542 // |22222222222222| 543 // +--------------+ 544 // Results in: 545 // +----------+-+------------+ 546 // |1111111111|x|222222222222| 547 // +----------+-+------------+ 548 // Where "x" represents the crossfaded portion of the signal. 549 TEST_F(AudioSplicerTest, PartialOverlapCrossfadeShortPreSplice) { 550 const int kCrossfadeSize = 551 input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()); 552 553 scoped_refptr<AudioBuffer> overlapped_buffer = 554 GetNextInputBuffer(1.0f, kCrossfadeSize / 2); 555 556 // Reset timestamp helper so that the next buffer will have a timestamp that 557 // starts in the middle of |overlapped_buffer|. 558 input_timestamp_helper_.SetBaseTimestamp(overlapped_buffer->timestamp()); 559 input_timestamp_helper_.AddFrames(overlapped_buffer->frame_count() / 2); 560 splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp()); 561 scoped_refptr<AudioBuffer> overlapping_buffer = 562 GetNextInputBuffer(0.0f, kCrossfadeSize * 2); 563 564 // The splicer should be internally queuing input since |overlapped_buffer| is 565 // part of the splice. 566 EXPECT_TRUE(AddInput(overlapped_buffer)); 567 EXPECT_FALSE(splicer_.HasNextBuffer()); 568 569 // |overlapping_buffer| completes the splice. 570 splicer_.SetSpliceTimestamp(kNoTimestamp()); 571 EXPECT_TRUE(AddInput(overlapping_buffer)); 572 573 const int kExpectedPreSpliceSize = 55; 574 const base::TimeDelta kExpectedPreSpliceDuration = 575 base::TimeDelta::FromMicroseconds(1247); 576 VerifyPreSpliceOutput(overlapped_buffer, 577 overlapping_buffer, 578 kExpectedPreSpliceSize, 579 kExpectedPreSpliceDuration); 580 VerifyCrossfadeOutput(overlapped_buffer, 581 NULL, 582 overlapping_buffer, 583 0, 584 kExpectedPreSpliceSize, 585 kExpectedPreSpliceDuration); 586 587 // Retrieve the remaining portion after crossfade. 588 ASSERT_TRUE(splicer_.HasNextBuffer()); 589 scoped_refptr<AudioBuffer> post_splice_output = splicer_.GetNextBuffer(); 590 EXPECT_EQ(overlapping_buffer->timestamp() + kExpectedPreSpliceDuration, 591 post_splice_output->timestamp()); 592 EXPECT_EQ(overlapping_buffer->frame_count() - kExpectedPreSpliceSize, 593 post_splice_output->frame_count()); 594 EXPECT_EQ(overlapping_buffer->duration() - kExpectedPreSpliceDuration, 595 post_splice_output->duration()); 596 597 EXPECT_TRUE(VerifyData(post_splice_output, GetValue(overlapping_buffer))); 598 EXPECT_FALSE(splicer_.HasNextBuffer()); 599 } 600 601 // Test behavior when a splice frame is incorrectly marked and does not actually 602 // overlap. 603 // +----------+ 604 // |1111111111| 605 // +----------+ 606 // +--------------+ 607 // |22222222222222| 608 // +--------------+ 609 // Results in: 610 // +----------+--------------+ 611 // |1111111111|22222222222222| 612 // +----------+--------------+ 613 TEST_F(AudioSplicerTest, IncorrectlyMarkedSplice) { 614 const int kBufferSize = 615 input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()) * 2; 616 617 scoped_refptr<AudioBuffer> first_buffer = 618 GetNextInputBuffer(1.0f, kBufferSize); 619 // Fuzz the duration slightly so that the buffer overlaps the splice timestamp 620 // by a microsecond, which is not enough to crossfade. 621 const base::TimeDelta kSpliceTimestamp = 622 input_timestamp_helper_.GetTimestamp() - 623 base::TimeDelta::FromMicroseconds(1); 624 splicer_.SetSpliceTimestamp(kSpliceTimestamp); 625 scoped_refptr<AudioBuffer> second_buffer = 626 GetNextInputBuffer(0.0f, kBufferSize); 627 second_buffer->set_timestamp(kSpliceTimestamp); 628 629 // The splicer should be internally queuing input since |first_buffer| is part 630 // of the supposed splice. 631 EXPECT_TRUE(AddInput(first_buffer)); 632 EXPECT_FALSE(splicer_.HasNextBuffer()); 633 634 // |second_buffer| should complete the supposed splice, so ensure output is 635 // now available. 636 splicer_.SetSpliceTimestamp(kNoTimestamp()); 637 EXPECT_TRUE(AddInput(second_buffer)); 638 639 VerifyNextBuffer(first_buffer); 640 VerifyNextBuffer(second_buffer); 641 EXPECT_FALSE(splicer_.HasNextBuffer()); 642 } 643 644 // Test behavior when a splice frame is incorrectly marked and there is a gap 645 // between whats in the pre splice and post splice. 646 // +--------+ 647 // |11111111| 648 // +--------+ 649 // +--------------+ 650 // |22222222222222| 651 // +--------------+ 652 // Results in: 653 // +--------+-+--------------+ 654 // |11111111|0|22222222222222| 655 // +--------+-+--------------+ 656 TEST_F(AudioSplicerTest, IncorrectlyMarkedSpliceWithGap) { 657 const int kBufferSize = 658 input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()) * 2; 659 const int kGapSize = 2; 660 661 scoped_refptr<AudioBuffer> first_buffer = 662 GetNextInputBuffer(1.0f, kBufferSize - kGapSize); 663 scoped_refptr<AudioBuffer> gap_buffer = 664 GetNextInputBuffer(0.0f, kGapSize); 665 splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp()); 666 scoped_refptr<AudioBuffer> second_buffer = 667 GetNextInputBuffer(0.0f, kBufferSize); 668 669 // The splicer should pass through the first buffer since it's not part of the 670 // splice. 671 EXPECT_TRUE(AddInput(first_buffer)); 672 VerifyNextBuffer(first_buffer); 673 674 // Do not add |gap_buffer|. 675 676 // |second_buffer| will complete the supposed splice. 677 splicer_.SetSpliceTimestamp(kNoTimestamp()); 678 EXPECT_TRUE(AddInput(second_buffer)); 679 680 VerifyNextBuffer(gap_buffer); 681 VerifyNextBuffer(second_buffer); 682 EXPECT_FALSE(splicer_.HasNextBuffer()); 683 } 684 685 // Test behavior when a splice frame is incorrectly marked and there is a gap 686 // between what's in the pre splice and post splice that is too large to recover 687 // from. 688 // +--------+ 689 // |11111111| 690 // +--------+ 691 // +------+ 692 // |222222| 693 // +------+ 694 // Results in an error and not a crash. 695 TEST_F(AudioSplicerTest, IncorrectlyMarkedSpliceWithBadGap) { 696 const int kBufferSize = 697 input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()) * 2; 698 const int kGapSize = kBufferSize + 699 input_timestamp_helper_.GetFramesToTarget( 700 base::TimeDelta::FromMilliseconds( 701 AudioSplicer::kMaxTimeDeltaInMilliseconds + 1)); 702 703 scoped_refptr<AudioBuffer> first_buffer = 704 GetNextInputBuffer(1.0f, kBufferSize); 705 scoped_refptr<AudioBuffer> gap_buffer = 706 GetNextInputBuffer(0.0f, kGapSize); 707 splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp()); 708 scoped_refptr<AudioBuffer> second_buffer = 709 GetNextInputBuffer(0.0f, kBufferSize); 710 711 // The splicer should pass through the first buffer since it's not part of the 712 // splice. 713 EXPECT_TRUE(AddInput(first_buffer)); 714 VerifyNextBuffer(first_buffer); 715 716 // Do not add |gap_buffer|. 717 718 // |second_buffer| will complete the supposed splice. 719 splicer_.SetSpliceTimestamp(kNoTimestamp()); 720 EXPECT_FALSE(AddInput(second_buffer)); 721 } 722 723 // Ensure we don't crash when a splice frame is incorrectly marked such that the 724 // splice timestamp has already passed when SetSpliceTimestamp() is called. 725 // This can happen if the encoded timestamps are too far behind the decoded 726 // timestamps. 727 TEST_F(AudioSplicerTest, IncorrectlyMarkedPastSplice) { 728 const int kBufferSize = 200; 729 730 scoped_refptr<AudioBuffer> first_buffer = 731 GetNextInputBuffer(1.0f, kBufferSize); 732 EXPECT_TRUE(AddInput(first_buffer)); 733 VerifyNextBuffer(first_buffer); 734 735 // Start the splice at a timestamp which has already occurred. 736 splicer_.SetSpliceTimestamp(base::TimeDelta()); 737 738 scoped_refptr<AudioBuffer> second_buffer = 739 GetNextInputBuffer(0.5f, kBufferSize); 740 EXPECT_TRUE(AddInput(second_buffer)); 741 EXPECT_FALSE(splicer_.HasNextBuffer()); 742 743 // |third_buffer| will complete the supposed splice. The buffer size is set 744 // such that unchecked the splicer would try to trim off a negative number of 745 // frames. 746 splicer_.SetSpliceTimestamp(kNoTimestamp()); 747 scoped_refptr<AudioBuffer> third_buffer = 748 GetNextInputBuffer(0.0f, kBufferSize * 10); 749 third_buffer->set_timestamp(base::TimeDelta()); 750 EXPECT_TRUE(AddInput(third_buffer)); 751 752 // The second buffer should come through unmodified. 753 VerifyNextBuffer(second_buffer); 754 755 // The third buffer should be partially dropped since it overlaps the second. 756 ASSERT_TRUE(splicer_.HasNextBuffer()); 757 const base::TimeDelta second_buffer_end_ts = 758 second_buffer->timestamp() + second_buffer->duration(); 759 scoped_refptr<AudioBuffer> output = splicer_.GetNextBuffer(); 760 EXPECT_EQ(second_buffer_end_ts, output->timestamp()); 761 EXPECT_EQ(third_buffer->duration() - 762 (second_buffer_end_ts - third_buffer->timestamp()), 763 output->duration()); 764 EXPECT_TRUE(VerifyData(output, GetValue(third_buffer))); 765 } 766 767 } // namespace media 768