OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 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 "webrtc/modules/rtp_rtcp/source/rtcp_packet/rpsi.h" | 11 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/rpsi.h" |
12 | 12 |
13 #include "testing/gmock/include/gmock/gmock.h" | 13 #include "testing/gmock/include/gmock/gmock.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 #include "webrtc/base/checks.h" |
15 | 16 |
16 #include "webrtc/test/rtcp_packet_parser.h" | 17 using testing::ElementsAreArray; |
17 | 18 using testing::make_tuple; |
18 using webrtc::rtcp::RawPacket; | 19 using webrtc::rtcp::RawPacket; |
19 using webrtc::rtcp::Rpsi; | 20 using webrtc::rtcp::Rpsi; |
20 using webrtc::test::RtcpPacketParser; | 21 using webrtc::RTCPUtility::RtcpCommonHeader; |
| 22 using webrtc::RTCPUtility::RtcpParseCommonHeader; |
21 | 23 |
22 namespace webrtc { | 24 namespace webrtc { |
| 25 namespace { |
| 26 const uint32_t kSenderSsrc = 0x12345678; |
| 27 const uint32_t kRemoteSsrc = 0x23456789; |
| 28 // 10000|01 100001|0 1000011 (7 bits = 1 byte in native string). |
| 29 const uint64_t kPictureId = 0x106143; |
| 30 const uint8_t kPayloadType = 100; |
| 31 // Manually created Rpsi packet matching constants above. |
| 32 const uint8_t kPacket[] = {0x83, 206, 0x00, 0x04, |
| 33 0x12, 0x34, 0x56, 0x78, |
| 34 0x23, 0x45, 0x67, 0x89, |
| 35 24, 100, 0xc1, 0xc2, |
| 36 0x43, 0, 0, 0}; |
| 37 |
| 38 bool ParseRpsi(const uint8_t* buffer, size_t length, Rpsi* rpsi) { |
| 39 RtcpCommonHeader header; |
| 40 EXPECT_TRUE(RtcpParseCommonHeader(buffer, length, &header)); |
| 41 EXPECT_EQ(length, header.BlockSize()); |
| 42 return rpsi->Parse(header, buffer + RtcpCommonHeader::kHeaderSizeBytes); |
| 43 } |
| 44 // Testing function when test only interested if parse is successful. |
| 45 bool ParseRpsi(const uint8_t* buffer, size_t length) { |
| 46 Rpsi rpsi; |
| 47 return ParseRpsi(buffer, length, &rpsi); |
| 48 } |
| 49 } // namespace |
| 50 |
| 51 TEST(RtcpPacketRpsiTest, Parse) { |
| 52 Rpsi mutable_parsed; |
| 53 EXPECT_TRUE(ParseRpsi(kPacket, sizeof(kPacket), &mutable_parsed)); |
| 54 const Rpsi& parsed = mutable_parsed; // Read values from constant object. |
| 55 |
| 56 EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc()); |
| 57 EXPECT_EQ(kRemoteSsrc, parsed.media_ssrc()); |
| 58 EXPECT_EQ(kPayloadType, parsed.payload_type()); |
| 59 EXPECT_EQ(kPictureId, parsed.picture_id()); |
| 60 } |
| 61 |
| 62 TEST(RtcpPacketRpsiTest, Create) { |
| 63 Rpsi rpsi; |
| 64 rpsi.From(kSenderSsrc); |
| 65 rpsi.To(kRemoteSsrc); |
| 66 rpsi.WithPayloadType(kPayloadType); |
| 67 rpsi.WithPictureId(kPictureId); |
| 68 |
| 69 rtc::scoped_ptr<RawPacket> packet = rpsi.Build(); |
| 70 |
| 71 EXPECT_THAT(make_tuple(packet->Buffer(), packet->Length()), |
| 72 ElementsAreArray(kPacket)); |
| 73 } |
| 74 |
| 75 TEST(RtcpPacketRpsiTest, ParseFailsOnTooSmallPacket) { |
| 76 Rpsi rpsi; |
| 77 rpsi.From(kSenderSsrc); |
| 78 rpsi.To(kRemoteSsrc); |
| 79 |
| 80 rtc::scoped_ptr<RawPacket> packet = rpsi.Build(); |
| 81 packet->MutableBuffer()[3]--; // Reduce size field by one word (4 bytes). |
| 82 |
| 83 EXPECT_FALSE(ParseRpsi(packet->Buffer(), packet->Length() - 4)); |
| 84 } |
| 85 |
| 86 TEST(RtcpPacketRpsiTest, ParseFailsOnFractionalPaddingBytes) { |
| 87 Rpsi rpsi; |
| 88 rpsi.From(kSenderSsrc); |
| 89 rpsi.To(kRemoteSsrc); |
| 90 rpsi.WithPictureId(kPictureId); |
| 91 rtc::scoped_ptr<RawPacket> packet = rpsi.Build(); |
| 92 uint8_t* padding_bits = packet->MutableBuffer() + 12; |
| 93 uint8_t saved_padding_bits = *padding_bits; |
| 94 ASSERT_TRUE(ParseRpsi(packet->Buffer(), packet->Length())); |
| 95 |
| 96 for (uint8_t i = 1; i < 8; ++i) { |
| 97 *padding_bits = saved_padding_bits + i; |
| 98 EXPECT_FALSE(ParseRpsi(packet->Buffer(), packet->Length())); |
| 99 } |
| 100 } |
| 101 |
| 102 TEST(RtcpPacketRpsiTest, ParseFailsOnTooBigPadding) { |
| 103 Rpsi rpsi; |
| 104 rpsi.From(kSenderSsrc); |
| 105 rpsi.To(kRemoteSsrc); |
| 106 rpsi.WithPictureId(1); // Small picture id that occupy just 1 byte. |
| 107 rtc::scoped_ptr<RawPacket> packet = rpsi.Build(); |
| 108 uint8_t* padding_bits = packet->MutableBuffer() + 12; |
| 109 ASSERT_TRUE(ParseRpsi(packet->Buffer(), packet->Length())); |
| 110 |
| 111 *padding_bits += 8; |
| 112 EXPECT_FALSE(ParseRpsi(packet->Buffer(), packet->Length())); |
| 113 } |
| 114 |
| 115 // For raw rpsi packet extract how many bytes are used to store picture_id. |
| 116 size_t UsedBytes(const RawPacket& packet) { // Works for small packets only. |
| 117 RTC_CHECK_EQ(packet.Buffer()[2], 0); // Assume packet is small. |
| 118 size_t total_rpsi_payload_bytes = 4 * (packet.Buffer()[3] - 2) - 2; |
| 119 uint8_t padding_bits = packet.Buffer()[12]; |
| 120 RTC_CHECK_EQ(padding_bits % 8, 0); |
| 121 return total_rpsi_payload_bytes - (padding_bits / 8); |
| 122 } |
23 | 123 |
24 TEST(RtcpPacketRpsiTest, WithOneByteNativeString) { | 124 TEST(RtcpPacketRpsiTest, WithOneByteNativeString) { |
25 Rpsi rpsi; | 125 Rpsi rpsi; |
26 // 1000001 (7 bits = 1 byte in native string). | 126 // 1000001 (7 bits = 1 byte in native string). |
27 const uint64_t kPictureId = 0x41; | 127 const uint64_t kPictureId = 0x41; |
28 const uint16_t kNumberOfValidBytes = 1; | 128 const uint16_t kNumberOfValidBytes = 1; |
29 rpsi.WithPayloadType(100); | |
30 rpsi.WithPictureId(kPictureId); | 129 rpsi.WithPictureId(kPictureId); |
31 | 130 |
32 rtc::scoped_ptr<RawPacket> packet(rpsi.Build()); | 131 rtc::scoped_ptr<RawPacket> packet = rpsi.Build(); |
33 RtcpPacketParser parser; | 132 EXPECT_EQ(kNumberOfValidBytes, UsedBytes(*packet)); |
34 parser.Parse(packet->Buffer(), packet->Length()); | 133 |
35 EXPECT_EQ(100, parser.rpsi()->PayloadType()); | 134 Rpsi parsed; |
36 EXPECT_EQ(kNumberOfValidBytes * 8, parser.rpsi()->NumberOfValidBits()); | 135 EXPECT_TRUE(ParseRpsi(packet->Buffer(), packet->Length(), &parsed)); |
37 EXPECT_EQ(kPictureId, parser.rpsi()->PictureId()); | 136 EXPECT_EQ(kPictureId, parsed.picture_id()); |
38 } | 137 } |
39 | 138 |
40 TEST(RtcpPacketRpsiTest, WithTwoByteNativeString) { | 139 TEST(RtcpPacketRpsiTest, WithTwoByteNativeString) { |
41 Rpsi rpsi; | 140 Rpsi rpsi; |
42 // |1 0000001 (7 bits = 1 byte in native string). | 141 // |1 0000001 (7 bits = 1 byte in native string). |
43 const uint64_t kPictureId = 0x81; | 142 const uint64_t kPictureId = 0x81; |
44 const uint16_t kNumberOfValidBytes = 2; | 143 const uint16_t kNumberOfValidBytes = 2; |
45 rpsi.WithPictureId(kPictureId); | 144 rpsi.WithPictureId(kPictureId); |
46 | 145 |
47 rtc::scoped_ptr<RawPacket> packet(rpsi.Build()); | 146 rtc::scoped_ptr<RawPacket> packet = rpsi.Build(); |
48 RtcpPacketParser parser; | 147 EXPECT_EQ(kNumberOfValidBytes, UsedBytes(*packet)); |
49 parser.Parse(packet->Buffer(), packet->Length()); | 148 |
50 EXPECT_EQ(kNumberOfValidBytes * 8, parser.rpsi()->NumberOfValidBits()); | 149 Rpsi parsed; |
51 EXPECT_EQ(kPictureId, parser.rpsi()->PictureId()); | 150 EXPECT_TRUE(ParseRpsi(packet->Buffer(), packet->Length(), &parsed)); |
| 151 EXPECT_EQ(kPictureId, parsed.picture_id()); |
52 } | 152 } |
53 | 153 |
54 TEST(RtcpPacketRpsiTest, WithThreeByteNativeString) { | 154 TEST(RtcpPacketRpsiTest, WithThreeByteNativeString) { |
55 Rpsi rpsi; | 155 Rpsi rpsi; |
56 // 10000|00 100000|0 1000000 (7 bits = 1 byte in native string). | 156 // 10000|00 100000|0 1000000 (7 bits = 1 byte in native string). |
57 const uint64_t kPictureId = 0x102040; | 157 const uint64_t kPictureId = 0x102040; |
58 const uint16_t kNumberOfValidBytes = 3; | 158 const uint16_t kNumberOfValidBytes = 3; |
59 rpsi.WithPictureId(kPictureId); | 159 rpsi.WithPictureId(kPictureId); |
60 | 160 |
61 rtc::scoped_ptr<RawPacket> packet(rpsi.Build()); | 161 rtc::scoped_ptr<RawPacket> packet = rpsi.Build(); |
62 RtcpPacketParser parser; | 162 EXPECT_EQ(kNumberOfValidBytes, UsedBytes(*packet)); |
63 parser.Parse(packet->Buffer(), packet->Length()); | 163 |
64 EXPECT_EQ(kNumberOfValidBytes * 8, parser.rpsi()->NumberOfValidBits()); | 164 Rpsi parsed; |
65 EXPECT_EQ(kPictureId, parser.rpsi()->PictureId()); | 165 EXPECT_TRUE(ParseRpsi(packet->Buffer(), packet->Length(), &parsed)); |
| 166 EXPECT_EQ(kPictureId, parsed.picture_id()); |
66 } | 167 } |
67 | 168 |
68 TEST(RtcpPacketRpsiTest, WithFourByteNativeString) { | 169 TEST(RtcpPacketRpsiTest, WithFourByteNativeString) { |
69 Rpsi rpsi; | 170 Rpsi rpsi; |
70 // 1000|001 00001|01 100001|1 1000010 (7 bits = 1 byte in native string). | 171 // 1000|001 00001|01 100001|1 1000010 (7 bits = 1 byte in native string). |
71 const uint64_t kPictureId = 0x84161C2; | 172 const uint64_t kPictureId = 0x84161C2; |
72 const uint16_t kNumberOfValidBytes = 4; | 173 const uint16_t kNumberOfValidBytes = 4; |
73 rpsi.WithPictureId(kPictureId); | 174 rpsi.WithPictureId(kPictureId); |
74 | 175 |
75 rtc::scoped_ptr<RawPacket> packet(rpsi.Build()); | 176 rtc::scoped_ptr<RawPacket> packet = rpsi.Build(); |
76 RtcpPacketParser parser; | 177 EXPECT_EQ(kNumberOfValidBytes, UsedBytes(*packet)); |
77 parser.Parse(packet->Buffer(), packet->Length()); | 178 |
78 EXPECT_EQ(kNumberOfValidBytes * 8, parser.rpsi()->NumberOfValidBits()); | 179 Rpsi parsed; |
79 EXPECT_EQ(kPictureId, parser.rpsi()->PictureId()); | 180 EXPECT_TRUE(ParseRpsi(packet->Buffer(), packet->Length(), &parsed)); |
| 181 EXPECT_EQ(kPictureId, parsed.picture_id()); |
80 } | 182 } |
81 | 183 |
82 TEST(RtcpPacketRpsiTest, WithMaxPictureId) { | 184 TEST(RtcpPacketRpsiTest, WithMaxPictureId) { |
83 Rpsi rpsi; | 185 Rpsi rpsi; |
84 // 1 1111111| 1111111 1|111111 11|11111 111|1111 1111|111 11111| | 186 // 1 1111111| 1111111 1|111111 11|11111 111|1111 1111|111 11111| |
85 // 11 111111|1 1111111 (7 bits = 1 byte in native string). | 187 // 11 111111|1 1111111 (7 bits = 1 byte in native string). |
86 const uint64_t kPictureId = 0xffffffffffffffff; | 188 const uint64_t kPictureId = 0xffffffffffffffff; |
87 const uint16_t kNumberOfValidBytes = 10; | 189 const uint16_t kNumberOfValidBytes = 10; |
88 rpsi.WithPictureId(kPictureId); | 190 rpsi.WithPictureId(kPictureId); |
89 | 191 |
90 rtc::scoped_ptr<RawPacket> packet(rpsi.Build()); | 192 rtc::scoped_ptr<RawPacket> packet = rpsi.Build(); |
91 RtcpPacketParser parser; | 193 EXPECT_EQ(kNumberOfValidBytes, UsedBytes(*packet)); |
92 parser.Parse(packet->Buffer(), packet->Length()); | 194 |
93 EXPECT_EQ(kNumberOfValidBytes * 8, parser.rpsi()->NumberOfValidBits()); | 195 Rpsi parsed; |
94 EXPECT_EQ(kPictureId, parser.rpsi()->PictureId()); | 196 EXPECT_TRUE(ParseRpsi(packet->Buffer(), packet->Length(), &parsed)); |
| 197 EXPECT_EQ(kPictureId, parsed.picture_id()); |
95 } | 198 } |
96 | |
97 } // namespace webrtc | 199 } // namespace webrtc |
OLD | NEW |