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

Side by Side Diff: webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc

Issue 1979443004: Add H264 bitstream rewriting to limit frame reordering marker in header (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addressed comments Created 4 years, 6 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 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
11 #include <memory> 11 #include <memory>
12 #include <vector> 12 #include <vector>
13 13
14 #include "testing/gmock/include/gmock/gmock.h" 14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "webrtc/modules/include/module_common_types.h" 16 #include "webrtc/modules/include/module_common_types.h"
17 #include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h" 17 #include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
18 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
19 #include "webrtc/common_video/h264/h264_common.h"
18 #include "webrtc/modules/rtp_rtcp/source/rtp_format.h" 20 #include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
19 21
20 namespace webrtc { 22 namespace webrtc {
21 namespace { 23 namespace {
22 const size_t kMaxPayloadSize = 1200; 24 const size_t kMaxPayloadSize = 1200;
23 const size_t kLengthFieldLength = 2; 25 const size_t kLengthFieldLength = 2;
24 26
25 enum Nalu { 27 enum Nalu {
26 kSlice = 1, 28 kSlice = 1,
27 kIdr = 5, 29 kIdr = 5,
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 // Generate 10 full sized packets, leave room for FU-A headers minus the NALU 374 // Generate 10 full sized packets, leave room for FU-A headers minus the NALU
373 // header. 375 // header.
374 TestFua( 376 TestFua(
375 10 * (kMaxPayloadSize - kFuAHeaderSize) + kNalHeaderSize, 377 10 * (kMaxPayloadSize - kFuAHeaderSize) + kNalHeaderSize,
376 kMaxPayloadSize, 378 kMaxPayloadSize,
377 std::vector<size_t>(kExpectedPayloadSizes, 379 std::vector<size_t>(kExpectedPayloadSizes,
378 kExpectedPayloadSizes + 380 kExpectedPayloadSizes +
379 sizeof(kExpectedPayloadSizes) / sizeof(size_t))); 381 sizeof(kExpectedPayloadSizes) / sizeof(size_t)));
380 } 382 }
381 383
384 namespace {
385 const uint8_t kStartSequence[] = {0x00, 0x00, 0x00, 0x01};
386 const uint8_t kOriginalSps[] = {kSps, 0x00, 0x00, 0x03, 0x03,
387 0xF4, 0x05, 0x03, 0xC7, 0xC0};
388 const uint8_t kRewrittenSps[] = {kSps, 0x00, 0x00, 0x03, 0x03, 0xF4, 0x05, 0x03,
389 0xC7, 0xE0, 0x1B, 0x41, 0x10, 0x8D, 0x00};
390 const uint8_t kIdrOne[] = {kIdr, 0xFF, 0x00, 0x00, 0x04};
391 const uint8_t kIdrTwo[] = {kIdr, 0xFF, 0x00, 0x11};
392 }
393
394 class RtpPacketizerH264TestSpsRewriting : public ::testing::Test {
395 public:
396 void SetUp() override {
397 fragmentation_header_.VerifyAndAllocateFragmentationHeader(3);
398 fragmentation_header_.fragmentationVectorSize = 3;
399 in_buffer_.AppendData(kStartSequence);
400
401 fragmentation_header_.fragmentationOffset[0] = in_buffer_.size();
402 fragmentation_header_.fragmentationLength[0] = sizeof(kOriginalSps);
403 in_buffer_.AppendData(kOriginalSps);
404
405 fragmentation_header_.fragmentationOffset[1] = in_buffer_.size();
406 fragmentation_header_.fragmentationLength[1] = sizeof(kIdrOne);
407 in_buffer_.AppendData(kIdrOne);
408
409 fragmentation_header_.fragmentationOffset[2] = in_buffer_.size();
410 fragmentation_header_.fragmentationLength[2] = sizeof(kIdrTwo);
411 in_buffer_.AppendData(kIdrTwo);
412 }
413
414 protected:
415 rtc::Buffer in_buffer_;
416 RTPFragmentationHeader fragmentation_header_;
417 std::unique_ptr<RtpPacketizer> packetizer_;
418 };
419
420 TEST_F(RtpPacketizerH264TestSpsRewriting, FuASps) {
421 const size_t kHeaderOverhead = kFuAHeaderSize + 1;
422
423 // Set size to fragment SPS into two FU-A packets.
424 packetizer_.reset(RtpPacketizer::Create(
425 kRtpVideoH264, sizeof(kOriginalSps) - 2 + kHeaderOverhead, nullptr,
426 kEmptyFrame));
427
428 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(),
429 &fragmentation_header_);
430
431 bool last_packet = true;
432 uint8_t buffer[sizeof(kOriginalSps) + kHeaderOverhead] = {};
433 size_t num_bytes = 0;
434
435 EXPECT_TRUE(packetizer_->NextPacket(buffer, &num_bytes, &last_packet));
436 size_t offset = H264::kNaluTypeSize;
437 size_t length = num_bytes - kFuAHeaderSize;
438 std::vector<uint8_t> expected_payload(&kRewrittenSps[offset],
439 &kRewrittenSps[offset + length]);
440 EXPECT_THAT(expected_payload,
441 ::testing::ElementsAreArray(&buffer[kFuAHeaderSize], length));
442 offset += length;
443
444 EXPECT_TRUE(packetizer_->NextPacket(buffer, &num_bytes, &last_packet));
445 length = num_bytes - kFuAHeaderSize;
446 expected_payload = std::vector<uint8_t>(&kRewrittenSps[offset],
447 &kRewrittenSps[offset + length]);
448 EXPECT_THAT(expected_payload,
449 ::testing::ElementsAreArray(&buffer[kFuAHeaderSize], length));
450 offset += length;
451
452 EXPECT_EQ(offset, sizeof(kRewrittenSps));
453 }
454
455 TEST_F(RtpPacketizerH264TestSpsRewriting, StapASps) {
456 const size_t kHeaderOverhead = kFuAHeaderSize + 1;
457 const size_t kExpectedTotalSize = H264::kNaluTypeSize + // Stap-A type.
458 sizeof(kRewrittenSps) + sizeof(kIdrOne) +
459 sizeof(kIdrTwo) + (kLengthFieldLength * 3);
460
461 // Set size to include SPS and the rest of the packets in a Stap-A package.
462 packetizer_.reset(RtpPacketizer::Create(kRtpVideoH264,
463 kExpectedTotalSize + kHeaderOverhead,
464 nullptr, kEmptyFrame));
465
466 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(),
467 &fragmentation_header_);
468
469 bool last_packet = true;
470 uint8_t buffer[kExpectedTotalSize + kHeaderOverhead] = {};
471 size_t num_bytes = 0;
472
473 EXPECT_TRUE(packetizer_->NextPacket(buffer, &num_bytes, &last_packet));
474 EXPECT_EQ(kExpectedTotalSize, num_bytes);
475
476 std::vector<uint8_t> expected_payload(kRewrittenSps,
477 &kRewrittenSps[sizeof(kRewrittenSps)]);
478 EXPECT_THAT(expected_payload,
479 ::testing::ElementsAreArray(
480 &buffer[H264::kNaluTypeSize + kLengthFieldLength],
481 sizeof(kRewrittenSps)));
482 }
483
382 class RtpDepacketizerH264Test : public ::testing::Test { 484 class RtpDepacketizerH264Test : public ::testing::Test {
383 protected: 485 protected:
384 RtpDepacketizerH264Test() 486 RtpDepacketizerH264Test()
385 : depacketizer_(RtpDepacketizer::Create(kRtpVideoH264)) {} 487 : depacketizer_(RtpDepacketizer::Create(kRtpVideoH264)) {}
386 488
387 void ExpectPacket(RtpDepacketizer::ParsedPayload* parsed_payload, 489 void ExpectPacket(RtpDepacketizer::ParsedPayload* parsed_payload,
388 const uint8_t* data, 490 const uint8_t* data,
389 size_t length) { 491 size_t length) {
390 ASSERT_TRUE(parsed_payload != NULL); 492 ASSERT_TRUE(parsed_payload != NULL);
391 EXPECT_THAT(std::vector<uint8_t>( 493 EXPECT_THAT(std::vector<uint8_t>(
(...skipping 15 matching lines...) Expand all
407 EXPECT_EQ(kRtpVideoH264, payload.type.Video.codec); 509 EXPECT_EQ(kRtpVideoH264, payload.type.Video.codec);
408 EXPECT_TRUE(payload.type.Video.isFirstPacket); 510 EXPECT_TRUE(payload.type.Video.isFirstPacket);
409 EXPECT_EQ(kH264SingleNalu, 511 EXPECT_EQ(kH264SingleNalu,
410 payload.type.Video.codecHeader.H264.packetization_type); 512 payload.type.Video.codecHeader.H264.packetization_type);
411 EXPECT_EQ(kIdr, payload.type.Video.codecHeader.H264.nalu_type); 513 EXPECT_EQ(kIdr, payload.type.Video.codecHeader.H264.nalu_type);
412 } 514 }
413 515
414 TEST_F(RtpDepacketizerH264Test, TestSingleNaluSpsWithResolution) { 516 TEST_F(RtpDepacketizerH264Test, TestSingleNaluSpsWithResolution) {
415 uint8_t packet[] = {kSps, 0x7A, 0x00, 0x1F, 0xBC, 0xD9, 0x40, 0x50, 517 uint8_t packet[] = {kSps, 0x7A, 0x00, 0x1F, 0xBC, 0xD9, 0x40, 0x50,
416 0x05, 0xBA, 0x10, 0x00, 0x00, 0x03, 0x00, 0xC0, 518 0x05, 0xBA, 0x10, 0x00, 0x00, 0x03, 0x00, 0xC0,
417 0x00, 0x00, 0x2A, 0xE0, 0xF1, 0x83, 0x19, 0x60}; 519 0x00, 0x00, 0x03, 0x2A, 0xE0, 0xF1, 0x83, 0x25};
418 RtpDepacketizer::ParsedPayload payload; 520 RtpDepacketizer::ParsedPayload payload;
419 521
420 ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet))); 522 ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
421 ExpectPacket(&payload, packet, sizeof(packet)); 523 ExpectPacket(&payload, packet, sizeof(packet));
422 EXPECT_EQ(kVideoFrameKey, payload.frame_type); 524 EXPECT_EQ(kVideoFrameKey, payload.frame_type);
423 EXPECT_EQ(kRtpVideoH264, payload.type.Video.codec); 525 EXPECT_EQ(kRtpVideoH264, payload.type.Video.codec);
424 EXPECT_TRUE(payload.type.Video.isFirstPacket); 526 EXPECT_TRUE(payload.type.Video.isFirstPacket);
425 EXPECT_EQ(kH264SingleNalu, 527 EXPECT_EQ(kH264SingleNalu,
426 payload.type.Video.codecHeader.H264.packetization_type); 528 payload.type.Video.codecHeader.H264.packetization_type);
427 EXPECT_EQ(1280u, payload.type.Video.width); 529 EXPECT_EQ(1280u, payload.type.Video.width);
(...skipping 14 matching lines...) Expand all
442 EXPECT_EQ(kRtpVideoH264, payload.type.Video.codec); 544 EXPECT_EQ(kRtpVideoH264, payload.type.Video.codec);
443 EXPECT_TRUE(payload.type.Video.isFirstPacket); 545 EXPECT_TRUE(payload.type.Video.isFirstPacket);
444 EXPECT_EQ(kH264StapA, payload.type.Video.codecHeader.H264.packetization_type); 546 EXPECT_EQ(kH264StapA, payload.type.Video.codecHeader.H264.packetization_type);
445 // NALU type for aggregated packets is the type of the first packet only. 547 // NALU type for aggregated packets is the type of the first packet only.
446 EXPECT_EQ(kSps, payload.type.Video.codecHeader.H264.nalu_type); 548 EXPECT_EQ(kSps, payload.type.Video.codecHeader.H264.nalu_type);
447 } 549 }
448 550
449 TEST_F(RtpDepacketizerH264Test, TestStapANaluSpsWithResolution) { 551 TEST_F(RtpDepacketizerH264Test, TestStapANaluSpsWithResolution) {
450 uint8_t packet[] = {kStapA, // F=0, NRI=0, Type=24. 552 uint8_t packet[] = {kStapA, // F=0, NRI=0, Type=24.
451 // Length (2 bytes), nal header, payload. 553 // Length (2 bytes), nal header, payload.
452 0, 24, kSps, 0x7A, 0x00, 0x1F, 0xBC, 0xD9, 554 0x00, 0x19, kSps, 0x7A, 0x00, 0x1F, 0xBC, 0xD9, 0x40,
453 0x40, 0x50, 0x05, 0xBA, 0x10, 0x00, 0x00, 0x03, 555 0x50, 0x05, 0xBA, 0x10, 0x00, 0x00, 0x03, 0x00, 0xC0,
454 0x00, 0xC0, 0x00, 0x00, 0x2A, 0xE0, 0xF1, 0x83, 556 0x00, 0x00, 0x03, 0x2A, 0xE0, 0xF1, 0x83, 0x25, 0x80,
455 0x19, 0x60, 0, 0x03, kIdr, 0xFF, 0x00, 0, 557 0x00, 0x03, kIdr, 0xFF, 0x00, 0x00, 0x04, kIdr, 0xFF,
456 0x04, kIdr, 0xFF, 0x00, 0x11}; 558 0x00, 0x11};
559
457 RtpDepacketizer::ParsedPayload payload; 560 RtpDepacketizer::ParsedPayload payload;
458 561
459 ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet))); 562 ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
460 ExpectPacket(&payload, packet, sizeof(packet)); 563 ExpectPacket(&payload, packet, sizeof(packet));
461 EXPECT_EQ(kVideoFrameKey, payload.frame_type); 564 EXPECT_EQ(kVideoFrameKey, payload.frame_type);
462 EXPECT_EQ(kRtpVideoH264, payload.type.Video.codec); 565 EXPECT_EQ(kRtpVideoH264, payload.type.Video.codec);
463 EXPECT_TRUE(payload.type.Video.isFirstPacket); 566 EXPECT_TRUE(payload.type.Video.isFirstPacket);
464 EXPECT_EQ(kH264StapA, payload.type.Video.codecHeader.H264.packetization_type); 567 EXPECT_EQ(kH264StapA, payload.type.Video.codecHeader.H264.packetization_type);
465 EXPECT_EQ(1280u, payload.type.Video.width); 568 EXPECT_EQ(1280u, payload.type.Video.width);
466 EXPECT_EQ(720u, payload.type.Video.height); 569 EXPECT_EQ(720u, payload.type.Video.height);
467 } 570 }
468 571
572 TEST_F(RtpDepacketizerH264Test, DepacketizeWithRewriting) {
573 rtc::Buffer in_buffer;
574 rtc::Buffer out_buffer;
575
576 uint8_t kHeader[2] = {kStapA};
577 in_buffer.AppendData(kHeader, 1);
578 out_buffer.AppendData(kHeader, 1);
579
580 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kOriginalSps));
581 in_buffer.AppendData(kHeader, 2);
582 in_buffer.AppendData(kOriginalSps);
583 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kRewrittenSps));
584 out_buffer.AppendData(kHeader, 2);
585 out_buffer.AppendData(kRewrittenSps);
586
587 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kIdrOne));
588 in_buffer.AppendData(kHeader, 2);
589 in_buffer.AppendData(kIdrOne);
590 out_buffer.AppendData(kHeader, 2);
591 out_buffer.AppendData(kIdrOne);
592
593 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kIdrTwo));
594 in_buffer.AppendData(kHeader, 2);
595 in_buffer.AppendData(kIdrTwo);
596 out_buffer.AppendData(kHeader, 2);
597 out_buffer.AppendData(kIdrTwo);
598
599 RtpDepacketizer::ParsedPayload payload;
600 EXPECT_TRUE(
601 depacketizer_->Parse(&payload, in_buffer.data(), in_buffer.size()));
602
603 std::vector<uint8_t> expected_packet_payload(
604 out_buffer.data(), &out_buffer.data()[out_buffer.size()]);
605
606 EXPECT_THAT(
607 expected_packet_payload,
608 ::testing::ElementsAreArray(payload.payload, payload.payload_length));
609 }
610
611 TEST_F(RtpDepacketizerH264Test, DepacketizeWithDoubleRewriting) {
612 rtc::Buffer in_buffer;
613 rtc::Buffer out_buffer;
614
615 uint8_t kHeader[2] = {kStapA};
616 in_buffer.AppendData(kHeader, 1);
617 out_buffer.AppendData(kHeader, 1);
618
619 // First SPS will be kept...
620 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kOriginalSps));
621 in_buffer.AppendData(kHeader, 2);
622 in_buffer.AppendData(kOriginalSps);
623 out_buffer.AppendData(kHeader, 2);
624 out_buffer.AppendData(kOriginalSps);
625
626 // ...only the second one will be rewritten.
627 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kOriginalSps));
628 in_buffer.AppendData(kHeader, 2);
629 in_buffer.AppendData(kOriginalSps);
630 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kRewrittenSps));
631 out_buffer.AppendData(kHeader, 2);
632 out_buffer.AppendData(kRewrittenSps);
633
634 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kIdrOne));
635 in_buffer.AppendData(kHeader, 2);
636 in_buffer.AppendData(kIdrOne);
637 out_buffer.AppendData(kHeader, 2);
638 out_buffer.AppendData(kIdrOne);
639
640 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kIdrTwo));
641 in_buffer.AppendData(kHeader, 2);
642 in_buffer.AppendData(kIdrTwo);
643 out_buffer.AppendData(kHeader, 2);
644 out_buffer.AppendData(kIdrTwo);
645
646 RtpDepacketizer::ParsedPayload payload;
647 EXPECT_TRUE(
648 depacketizer_->Parse(&payload, in_buffer.data(), in_buffer.size()));
649
650 std::vector<uint8_t> expected_packet_payload(
651 out_buffer.data(), &out_buffer.data()[out_buffer.size()]);
652
653 EXPECT_THAT(
654 expected_packet_payload,
655 ::testing::ElementsAreArray(payload.payload, payload.payload_length));
656 }
657
469 TEST_F(RtpDepacketizerH264Test, TestStapADelta) { 658 TEST_F(RtpDepacketizerH264Test, TestStapADelta) {
470 uint8_t packet[16] = {kStapA, // F=0, NRI=0, Type=24. 659 uint8_t packet[16] = {kStapA, // F=0, NRI=0, Type=24.
471 // Length, nal header, payload. 660 // Length, nal header, payload.
472 0, 0x02, kSlice, 0xFF, 0, 0x03, kSlice, 0xFF, 661 0, 0x02, kSlice, 0xFF, 0, 0x03, kSlice, 0xFF,
473 0x00, 0, 0x04, kSlice, 0xFF, 0x00, 0x11}; 662 0x00, 0, 0x04, kSlice, 0xFF, 0x00, 0x11};
474 RtpDepacketizer::ParsedPayload payload; 663 RtpDepacketizer::ParsedPayload payload;
475 664
476 ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet))); 665 ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
477 ExpectPacket(&payload, packet, sizeof(packet)); 666 ExpectPacket(&payload, packet, sizeof(packet));
478 EXPECT_EQ(kVideoFrameDelta, payload.frame_type); 667 EXPECT_EQ(kVideoFrameDelta, payload.frame_type);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 EXPECT_FALSE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload))); 752 EXPECT_FALSE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
564 } 753 }
565 754
566 TEST_F(RtpDepacketizerH264Test, TestShortSpsPacket) { 755 TEST_F(RtpDepacketizerH264Test, TestShortSpsPacket) {
567 const uint8_t kPayload[] = {0x27, 0x80, 0x00}; 756 const uint8_t kPayload[] = {0x27, 0x80, 0x00};
568 RtpDepacketizer::ParsedPayload payload; 757 RtpDepacketizer::ParsedPayload payload;
569 EXPECT_TRUE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload))); 758 EXPECT_TRUE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
570 } 759 }
571 760
572 } // namespace webrtc 761 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc ('k') | webrtc/modules/video_coding/utility/h264_bitstream_parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698