Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(517)

Side by Side Diff: webrtc/modules/audio_coding/neteq/payload_splitter_unittest.cc

Issue 2326003002: Moved codec-specific audio packet splitting into decoders. (Closed)
Patch Set: Fixed types in packet splitting (size_t vs. uint32_t) Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/audio_coding/neteq/payload_splitter.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 uint32_t timestamp, 145 uint32_t timestamp,
146 uint8_t payload_value, 146 uint8_t payload_value,
147 bool primary = true) { 147 bool primary = true) {
148 EXPECT_EQ(payload_length, packet->payload.size()); 148 EXPECT_EQ(payload_length, packet->payload.size());
149 EXPECT_EQ(payload_type, packet->header.payloadType); 149 EXPECT_EQ(payload_type, packet->header.payloadType);
150 EXPECT_EQ(sequence_number, packet->header.sequenceNumber); 150 EXPECT_EQ(sequence_number, packet->header.sequenceNumber);
151 EXPECT_EQ(timestamp, packet->header.timestamp); 151 EXPECT_EQ(timestamp, packet->header.timestamp);
152 EXPECT_EQ(primary, packet->primary); 152 EXPECT_EQ(primary, packet->primary);
153 ASSERT_FALSE(packet->payload.empty()); 153 ASSERT_FALSE(packet->payload.empty());
154 for (size_t i = 0; i < packet->payload.size(); ++i) { 154 for (size_t i = 0; i < packet->payload.size(); ++i) {
155 EXPECT_EQ(payload_value, packet->payload[i]); 155 ASSERT_EQ(payload_value, packet->payload.data()[i]);
156 } 156 }
157 } 157 }
158 158
159 // Start of test definitions. 159 // Start of test definitions.
160 160
161 TEST(PayloadSplitter, CreateAndDestroy) { 161 TEST(PayloadSplitter, CreateAndDestroy) {
162 PayloadSplitter* splitter = new PayloadSplitter; 162 PayloadSplitter* splitter = new PayloadSplitter;
163 delete splitter; 163 delete splitter;
164 } 164 }
165 165
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 splitter.SplitRed(&packet_list)); 337 splitter.SplitRed(&packet_list));
338 ASSERT_EQ(1u, packet_list.size()); 338 ASSERT_EQ(1u, packet_list.size());
339 // Check first packet. 339 // Check first packet.
340 packet = packet_list.front(); 340 packet = packet_list.front();
341 VerifyPacket(packet, kPayloadLength, payload_types[0], kSequenceNumber, 341 VerifyPacket(packet, kPayloadLength, payload_types[0], kSequenceNumber,
342 kBaseTimestamp - 2 * kTimestampOffset, 0, false); 342 kBaseTimestamp - 2 * kTimestampOffset, 0, false);
343 delete packet; 343 delete packet;
344 packet_list.pop_front(); 344 packet_list.pop_front();
345 } 345 }
346 346
347 // Test that iSAC, iSAC-swb, RED, DTMF, CNG, and "Arbitrary" payloads do not
348 // get split.
349 TEST(AudioPayloadSplitter, NonSplittable) {
350 // Set up packets with different RTP payload types. The actual values do not
351 // matter, since we are mocking the decoder database anyway.
352 PacketList packet_list;
353 for (uint8_t i = 0; i < 6; ++i) {
354 // Let the payload type be |i|, and the payload value 10 * |i|.
355 packet_list.push_back(CreatePacket(i, kPayloadLength, 10 * i));
356 }
357
358 MockDecoderDatabase decoder_database;
359 // Tell the mock decoder database to return DecoderInfo structs with different
360 // codec types.
361 // Use scoped pointers to avoid having to delete them later.
362 std::unique_ptr<DecoderDatabase::DecoderInfo> info0(
363 new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderISAC, ""));
364 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
365 .WillRepeatedly(Return(info0.get()));
366 std::unique_ptr<DecoderDatabase::DecoderInfo> info1(
367 new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderISACswb, ""));
368 EXPECT_CALL(decoder_database, GetDecoderInfo(1))
369 .WillRepeatedly(Return(info1.get()));
370 std::unique_ptr<DecoderDatabase::DecoderInfo> info2(
371 new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderRED, ""));
372 EXPECT_CALL(decoder_database, GetDecoderInfo(2))
373 .WillRepeatedly(Return(info2.get()));
374 std::unique_ptr<DecoderDatabase::DecoderInfo> info3(
375 new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderAVT, ""));
376 EXPECT_CALL(decoder_database, GetDecoderInfo(3))
377 .WillRepeatedly(Return(info3.get()));
378 std::unique_ptr<DecoderDatabase::DecoderInfo> info4(
379 new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderCNGnb, ""));
380 EXPECT_CALL(decoder_database, GetDecoderInfo(4))
381 .WillRepeatedly(Return(info4.get()));
382 std::unique_ptr<DecoderDatabase::DecoderInfo> info5(
383 new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderArbitrary, ""));
384 EXPECT_CALL(decoder_database, GetDecoderInfo(5))
385 .WillRepeatedly(Return(info5.get()));
386
387 PayloadSplitter splitter;
388 EXPECT_EQ(0, splitter.SplitAudio(&packet_list, decoder_database));
389 EXPECT_EQ(6u, packet_list.size());
390
391 // Check that all payloads are intact.
392 uint8_t payload_type = 0;
393 PacketList::iterator it = packet_list.begin();
394 while (it != packet_list.end()) {
395 VerifyPacket((*it), kPayloadLength, payload_type, kSequenceNumber,
396 kBaseTimestamp, 10 * payload_type);
397 ++payload_type;
398 delete (*it);
399 it = packet_list.erase(it);
400 }
401
402 // The destructor is called when decoder_database goes out of scope.
403 EXPECT_CALL(decoder_database, Die());
404 }
405
406 // Test unknown payload type.
407 TEST(AudioPayloadSplitter, UnknownPayloadType) {
408 PacketList packet_list;
409 static const uint8_t kPayloadType = 17; // Just a random number.
410 size_t kPayloadLengthBytes = 4711; // Random number.
411 packet_list.push_back(CreatePacket(kPayloadType, kPayloadLengthBytes, 0));
412
413 MockDecoderDatabase decoder_database;
414 // Tell the mock decoder database to return NULL when asked for decoder info.
415 // This signals that the decoder database does not recognize the payload type.
416 EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType))
417 .WillRepeatedly(ReturnNull());
418
419 PayloadSplitter splitter;
420 EXPECT_EQ(PayloadSplitter::kUnknownPayloadType,
421 splitter.SplitAudio(&packet_list, decoder_database));
422 EXPECT_EQ(1u, packet_list.size());
423
424
425 // Delete the packets and payloads to avoid having the test leak memory.
426 PacketList::iterator it = packet_list.begin();
427 while (it != packet_list.end()) {
428 delete (*it);
429 it = packet_list.erase(it);
430 }
431
432 // The destructor is called when decoder_database goes out of scope.
433 EXPECT_CALL(decoder_database, Die());
434 }
435
436 class SplitBySamplesTest : public ::testing::TestWithParam<NetEqDecoder> {
437 protected:
438 virtual void SetUp() {
439 decoder_type_ = GetParam();
440 switch (decoder_type_) {
441 case NetEqDecoder::kDecoderPCMu:
442 case NetEqDecoder::kDecoderPCMa:
443 bytes_per_ms_ = 8;
444 samples_per_ms_ = 8;
445 break;
446 case NetEqDecoder::kDecoderPCMu_2ch:
447 case NetEqDecoder::kDecoderPCMa_2ch:
448 bytes_per_ms_ = 2 * 8;
449 samples_per_ms_ = 8;
450 break;
451 case NetEqDecoder::kDecoderG722:
452 bytes_per_ms_ = 8;
453 samples_per_ms_ = 16;
454 break;
455 case NetEqDecoder::kDecoderPCM16B:
456 bytes_per_ms_ = 16;
457 samples_per_ms_ = 8;
458 break;
459 case NetEqDecoder::kDecoderPCM16Bwb:
460 bytes_per_ms_ = 32;
461 samples_per_ms_ = 16;
462 break;
463 case NetEqDecoder::kDecoderPCM16Bswb32kHz:
464 bytes_per_ms_ = 64;
465 samples_per_ms_ = 32;
466 break;
467 case NetEqDecoder::kDecoderPCM16Bswb48kHz:
468 bytes_per_ms_ = 96;
469 samples_per_ms_ = 48;
470 break;
471 case NetEqDecoder::kDecoderPCM16B_2ch:
472 bytes_per_ms_ = 2 * 16;
473 samples_per_ms_ = 8;
474 break;
475 case NetEqDecoder::kDecoderPCM16Bwb_2ch:
476 bytes_per_ms_ = 2 * 32;
477 samples_per_ms_ = 16;
478 break;
479 case NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch:
480 bytes_per_ms_ = 2 * 64;
481 samples_per_ms_ = 32;
482 break;
483 case NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch:
484 bytes_per_ms_ = 2 * 96;
485 samples_per_ms_ = 48;
486 break;
487 case NetEqDecoder::kDecoderPCM16B_5ch:
488 bytes_per_ms_ = 5 * 16;
489 samples_per_ms_ = 8;
490 break;
491 default:
492 assert(false);
493 break;
494 }
495 }
496 size_t bytes_per_ms_;
497 int samples_per_ms_;
498 NetEqDecoder decoder_type_;
499 };
500
501 // Test splitting sample-based payloads.
502 TEST_P(SplitBySamplesTest, PayloadSizes) {
503 PacketList packet_list;
504 static const uint8_t kPayloadType = 17; // Just a random number.
505 for (int payload_size_ms = 10; payload_size_ms <= 60; payload_size_ms += 10) {
506 // The payload values are set to be the same as the payload_size, so that
507 // one can distinguish from which packet the split payloads come from.
508 size_t payload_size_bytes = payload_size_ms * bytes_per_ms_;
509 packet_list.push_back(CreatePacket(kPayloadType, payload_size_bytes,
510 payload_size_ms));
511 }
512
513 MockDecoderDatabase decoder_database;
514 // Tell the mock decoder database to return DecoderInfo structs with different
515 // codec types.
516 // Use scoped pointers to avoid having to delete them later.
517 // (Sample rate is set to 8000 Hz, but does not matter.)
518 std::unique_ptr<DecoderDatabase::DecoderInfo> info(
519 new DecoderDatabase::DecoderInfo(decoder_type_, ""));
520 EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType))
521 .WillRepeatedly(Return(info.get()));
522
523 PayloadSplitter splitter;
524 EXPECT_EQ(0, splitter.SplitAudio(&packet_list, decoder_database));
525 // The payloads are expected to be split as follows:
526 // 10 ms -> 10 ms
527 // 20 ms -> 20 ms
528 // 30 ms -> 30 ms
529 // 40 ms -> 20 + 20 ms
530 // 50 ms -> 25 + 25 ms
531 // 60 ms -> 30 + 30 ms
532 int expected_size_ms[] = {10, 20, 30, 20, 20, 25, 25, 30, 30};
533 int expected_payload_value[] = {10, 20, 30, 40, 40, 50, 50, 60, 60};
534 int expected_timestamp_offset_ms[] = {0, 0, 0, 0, 20, 0, 25, 0, 30};
535 size_t expected_num_packets =
536 sizeof(expected_size_ms) / sizeof(expected_size_ms[0]);
537 EXPECT_EQ(expected_num_packets, packet_list.size());
538
539 PacketList::iterator it = packet_list.begin();
540 int i = 0;
541 while (it != packet_list.end()) {
542 size_t length_bytes = expected_size_ms[i] * bytes_per_ms_;
543 uint32_t expected_timestamp = kBaseTimestamp +
544 expected_timestamp_offset_ms[i] * samples_per_ms_;
545 VerifyPacket((*it), length_bytes, kPayloadType, kSequenceNumber,
546 expected_timestamp, expected_payload_value[i]);
547 delete (*it);
548 it = packet_list.erase(it);
549 ++i;
550 }
551
552 // The destructor is called when decoder_database goes out of scope.
553 EXPECT_CALL(decoder_database, Die());
554 }
555
556 INSTANTIATE_TEST_CASE_P(
557 PayloadSplitter,
558 SplitBySamplesTest,
559 ::testing::Values(NetEqDecoder::kDecoderPCMu,
560 NetEqDecoder::kDecoderPCMa,
561 NetEqDecoder::kDecoderPCMu_2ch,
562 NetEqDecoder::kDecoderPCMa_2ch,
563 NetEqDecoder::kDecoderG722,
564 NetEqDecoder::kDecoderPCM16B,
565 NetEqDecoder::kDecoderPCM16Bwb,
566 NetEqDecoder::kDecoderPCM16Bswb32kHz,
567 NetEqDecoder::kDecoderPCM16Bswb48kHz,
568 NetEqDecoder::kDecoderPCM16B_2ch,
569 NetEqDecoder::kDecoderPCM16Bwb_2ch,
570 NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch,
571 NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch,
572 NetEqDecoder::kDecoderPCM16B_5ch));
573
574 class SplitIlbcTest : public ::testing::TestWithParam<std::pair<int, int> > {
575 protected:
576 virtual void SetUp() {
577 const std::pair<int, int> parameters = GetParam();
578 num_frames_ = parameters.first;
579 frame_length_ms_ = parameters.second;
580 frame_length_bytes_ = (frame_length_ms_ == 20) ? 38 : 50;
581 }
582 size_t num_frames_;
583 int frame_length_ms_;
584 size_t frame_length_bytes_;
585 };
586
587 // Test splitting sample-based payloads.
588 TEST_P(SplitIlbcTest, NumFrames) {
589 PacketList packet_list;
590 static const uint8_t kPayloadType = 17; // Just a random number.
591 const int frame_length_samples = frame_length_ms_ * 8;
592 size_t payload_length_bytes = frame_length_bytes_ * num_frames_;
593 Packet* packet = CreatePacket(kPayloadType, payload_length_bytes, 0);
594 // Fill payload with increasing integers {0, 1, 2, ...}.
595 for (size_t i = 0; i < packet->payload.size(); ++i) {
596 packet->payload[i] = static_cast<uint8_t>(i);
597 }
598 packet_list.push_back(packet);
599
600 MockDecoderDatabase decoder_database;
601 // Tell the mock decoder database to return DecoderInfo structs with different
602 // codec types.
603 // Use scoped pointers to avoid having to delete them later.
604 std::unique_ptr<DecoderDatabase::DecoderInfo> info(
605 new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderILBC, ""));
606 EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType))
607 .WillRepeatedly(Return(info.get()));
608
609 PayloadSplitter splitter;
610 EXPECT_EQ(0, splitter.SplitAudio(&packet_list, decoder_database));
611 EXPECT_EQ(num_frames_, packet_list.size());
612
613 PacketList::iterator it = packet_list.begin();
614 int frame_num = 0;
615 uint8_t payload_value = 0;
616 while (it != packet_list.end()) {
617 Packet* packet = (*it);
618 EXPECT_EQ(kBaseTimestamp + frame_length_samples * frame_num,
619 packet->header.timestamp);
620 EXPECT_EQ(frame_length_bytes_, packet->payload.size());
621 EXPECT_EQ(kPayloadType, packet->header.payloadType);
622 EXPECT_EQ(kSequenceNumber, packet->header.sequenceNumber);
623 EXPECT_EQ(true, packet->primary);
624 ASSERT_FALSE(packet->payload.empty());
625 for (size_t i = 0; i < packet->payload.size(); ++i) {
626 EXPECT_EQ(payload_value, packet->payload[i]);
627 ++payload_value;
628 }
629 delete (*it);
630 it = packet_list.erase(it);
631 ++frame_num;
632 }
633
634 // The destructor is called when decoder_database goes out of scope.
635 EXPECT_CALL(decoder_database, Die());
636 }
637
638 // Test 1 through 5 frames of 20 and 30 ms size.
639 // Also test the maximum number of frames in one packet for 20 and 30 ms.
640 // The maximum is defined by the largest payload length that can be uniquely
641 // resolved to a frame size of either 38 bytes (20 ms) or 50 bytes (30 ms).
642 INSTANTIATE_TEST_CASE_P(
643 PayloadSplitter, SplitIlbcTest,
644 ::testing::Values(std::pair<int, int>(1, 20), // 1 frame, 20 ms.
645 std::pair<int, int>(2, 20), // 2 frames, 20 ms.
646 std::pair<int, int>(3, 20), // And so on.
647 std::pair<int, int>(4, 20),
648 std::pair<int, int>(5, 20),
649 std::pair<int, int>(24, 20),
650 std::pair<int, int>(1, 30),
651 std::pair<int, int>(2, 30),
652 std::pair<int, int>(3, 30),
653 std::pair<int, int>(4, 30),
654 std::pair<int, int>(5, 30),
655 std::pair<int, int>(18, 30)));
656
657 // Test too large payload size.
658 TEST(IlbcPayloadSplitter, TooLargePayload) {
659 PacketList packet_list;
660 static const uint8_t kPayloadType = 17; // Just a random number.
661 size_t kPayloadLengthBytes = 950;
662 Packet* packet = CreatePacket(kPayloadType, kPayloadLengthBytes, 0);
663 packet_list.push_back(packet);
664
665 MockDecoderDatabase decoder_database;
666 std::unique_ptr<DecoderDatabase::DecoderInfo> info(
667 new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderILBC, ""));
668 EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType))
669 .WillRepeatedly(Return(info.get()));
670
671 PayloadSplitter splitter;
672 EXPECT_EQ(PayloadSplitter::kTooLargePayload,
673 splitter.SplitAudio(&packet_list, decoder_database));
674 EXPECT_EQ(1u, packet_list.size());
675
676 // Delete the packets and payloads to avoid having the test leak memory.
677 PacketList::iterator it = packet_list.begin();
678 while (it != packet_list.end()) {
679 delete (*it);
680 it = packet_list.erase(it);
681 }
682
683 // The destructor is called when decoder_database goes out of scope.
684 EXPECT_CALL(decoder_database, Die());
685 }
686
687 // Payload not an integer number of frames.
688 TEST(IlbcPayloadSplitter, UnevenPayload) {
689 PacketList packet_list;
690 static const uint8_t kPayloadType = 17; // Just a random number.
691 size_t kPayloadLengthBytes = 39; // Not an even number of frames.
692 Packet* packet = CreatePacket(kPayloadType, kPayloadLengthBytes, 0);
693 packet_list.push_back(packet);
694
695 MockDecoderDatabase decoder_database;
696 std::unique_ptr<DecoderDatabase::DecoderInfo> info(
697 new DecoderDatabase::DecoderInfo(NetEqDecoder::kDecoderILBC, ""));
698 EXPECT_CALL(decoder_database, GetDecoderInfo(kPayloadType))
699 .WillRepeatedly(Return(info.get()));
700
701 PayloadSplitter splitter;
702 EXPECT_EQ(PayloadSplitter::kFrameSplitError,
703 splitter.SplitAudio(&packet_list, decoder_database));
704 EXPECT_EQ(1u, packet_list.size());
705
706 // Delete the packets and payloads to avoid having the test leak memory.
707 PacketList::iterator it = packet_list.begin();
708 while (it != packet_list.end()) {
709 delete (*it);
710 it = packet_list.erase(it);
711 }
712
713 // The destructor is called when decoder_database goes out of scope.
714 EXPECT_CALL(decoder_database, Die());
715 }
716
717 TEST(FecPayloadSplitter, MixedPayload) { 347 TEST(FecPayloadSplitter, MixedPayload) {
718 PacketList packet_list; 348 PacketList packet_list;
719 DecoderDatabase decoder_database(CreateBuiltinAudioDecoderFactory()); 349 DecoderDatabase decoder_database(CreateBuiltinAudioDecoderFactory());
720 350
721 decoder_database.RegisterPayload(0, NetEqDecoder::kDecoderOpus, "opus"); 351 decoder_database.RegisterPayload(0, NetEqDecoder::kDecoderOpus, "opus");
722 decoder_database.RegisterPayload(1, NetEqDecoder::kDecoderPCMu, "pcmu"); 352 decoder_database.RegisterPayload(1, NetEqDecoder::kDecoderPCMu, "pcmu");
723 353
724 Packet* packet = CreatePacket(0, 10, 0xFF, true); 354 Packet* packet = CreatePacket(0, 10, 0xFF, true);
725 packet_list.push_back(packet); 355 packet_list.push_back(packet);
726 356
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 EXPECT_EQ(0, packet->header.payloadType); 448 EXPECT_EQ(0, packet->header.payloadType);
819 EXPECT_EQ(kBaseTimestamp - kTimestampOffset, packet->header.timestamp); 449 EXPECT_EQ(kBaseTimestamp - kTimestampOffset, packet->header.timestamp);
820 EXPECT_EQ(kPayloadLength, packet->payload.size()); 450 EXPECT_EQ(kPayloadLength, packet->payload.size());
821 EXPECT_TRUE(packet->primary); 451 EXPECT_TRUE(packet->primary);
822 EXPECT_EQ(packet->payload[3], 0); 452 EXPECT_EQ(packet->payload[3], 0);
823 delete packet; 453 delete packet;
824 packet_list.pop_front(); 454 packet_list.pop_front();
825 } 455 }
826 456
827 } // namespace webrtc 457 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/neteq/payload_splitter.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698