OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | |
3 * | |
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 | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h" | |
12 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" | |
13 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" | |
14 #include "webrtc/test/gmock.h" | |
15 #include "webrtc/test/gtest.h" | |
16 | |
17 namespace webrtc { | |
18 namespace { | |
19 | |
20 using ::testing::ElementsAreArray; | |
21 using ::testing::make_tuple; | |
22 | |
23 const int8_t kPayloadType = 100; | |
24 const uint32_t kSsrc = 0x12345678; | |
25 const uint16_t kSeqNum = 88; | |
26 const uint32_t kTimestamp = 0x65431278; | |
27 | |
28 } // namespace | |
29 | |
30 TEST(RtpHeaderParser, ParseMinimum) { | |
31 // clang-format off | |
32 const uint8_t kPacket[] = { | |
33 0x80, kPayloadType, 0x00, kSeqNum, | |
34 0x65, 0x43, 0x12, 0x78, // kTimestamp. | |
35 0x12, 0x34, 0x56, 0x78}; // kSsrc. | |
36 // clang-format on | |
37 RtpUtility::RtpHeaderParser parser(kPacket, sizeof(kPacket)); | |
38 RTPHeader header; | |
39 | |
40 EXPECT_TRUE(parser.Parse(&header, nullptr)); | |
41 | |
42 EXPECT_EQ(kPayloadType, header.payloadType); | |
43 EXPECT_EQ(kSeqNum, header.sequenceNumber); | |
44 EXPECT_EQ(kTimestamp, header.timestamp); | |
45 EXPECT_EQ(kSsrc, header.ssrc); | |
46 EXPECT_EQ(0u, header.paddingLength); | |
47 EXPECT_EQ(sizeof(kPacket), header.headerLength); | |
48 } | |
49 | |
50 TEST(RtpHeaderParser, ParseWithExtension) { | |
51 // clang-format off | |
52 const uint8_t kPacket[] = { | |
53 0x90, kPayloadType, 0x00, kSeqNum, | |
54 0x65, 0x43, 0x12, 0x78, // kTimestamp. | |
55 0x12, 0x34, 0x56, 0x78, // kSsrc. | |
56 0xbe, 0xde, 0x00, 0x01, // Extension block of size 1 x 32bit words. | |
57 0x12, 0x01, 0x56, 0xce}; | |
58 // clang-format on | |
59 RtpHeaderExtensionMap extensions; | |
60 extensions.Register<TransmissionOffset>(1); | |
61 RtpUtility::RtpHeaderParser parser(kPacket, sizeof(kPacket)); | |
62 RTPHeader header; | |
63 | |
64 EXPECT_TRUE(parser.Parse(&header, &extensions)); | |
65 | |
66 EXPECT_EQ(kPayloadType, header.payloadType); | |
67 EXPECT_EQ(kSeqNum, header.sequenceNumber); | |
68 EXPECT_EQ(kTimestamp, header.timestamp); | |
69 EXPECT_EQ(kSsrc, header.ssrc); | |
70 | |
71 ASSERT_TRUE(header.extension.hasTransmissionTimeOffset); | |
72 EXPECT_EQ(0x156ce, header.extension.transmissionTimeOffset); | |
73 } | |
74 | |
75 TEST(RtpHeaderParser, ParseWithInvalidSizedExtension) { | |
76 const size_t kPayloadSize = 7; | |
77 // clang-format off | |
78 const uint8_t kPacket[] = { | |
79 0x90, kPayloadType, 0x00, kSeqNum, | |
80 0x65, 0x43, 0x12, 0x78, // kTimestamp. | |
81 0x12, 0x34, 0x56, 0x78, // kSsrc. | |
82 0xbe, 0xde, 0x00, 0x02, // Extension block of size 2 x 32bit words. | |
83 0x16, // (6+1)-bytes, but Transmission Offset expected to be 3-bytes. | |
84 'e', 'x', 't', | |
85 'd', 'a', 't', 'a', | |
86 'p', 'a', 'y', 'l', 'o', 'a', 'd' | |
87 }; | |
88 // clang-format on | |
89 RtpHeaderExtensionMap extensions; | |
90 extensions.Register<TransmissionOffset>(1); | |
91 RtpUtility::RtpHeaderParser parser(kPacket, sizeof(kPacket)); | |
92 RTPHeader header; | |
93 | |
94 EXPECT_TRUE(parser.Parse(&header, &extensions)); | |
95 | |
96 // Extension should be ignored. | |
97 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset); | |
98 // But shouldn't prevent reading payload. | |
99 EXPECT_THAT(sizeof(kPacket) - kPayloadSize, header.headerLength); | |
100 } | |
101 | |
102 TEST(RtpHeaderParser, ParseWithExtensionPadding) { | |
103 // clang-format off | |
104 const uint8_t kPacket[] = { | |
105 0x90, kPayloadType, 0x00, kSeqNum, | |
106 0x65, 0x43, 0x12, 0x78, // kTimestamp. | |
107 0x12, 0x34, 0x56, 0x78, // kSsrc. | |
108 0xbe, 0xde, 0x00, 0x02, // Extension of size 1x32bit word. | |
109 0x02, // A byte of (invalid) padding. | |
110 0x12, 0x1a, 0xda, 0x03, // TransmissionOffset extension. | |
111 0x0f, 0x00, 0x03, // More invalid padding bytes: id=0, but len > 0. | |
112 }; | |
113 // clang-format on | |
114 RtpHeaderExtensionMap extensions; | |
115 extensions.Register<TransmissionOffset>(1); | |
116 RtpUtility::RtpHeaderParser parser(kPacket, sizeof(kPacket)); | |
117 RTPHeader header; | |
118 | |
119 EXPECT_TRUE(parser.Parse(&header, &extensions)); | |
120 | |
121 // Parse should skip padding and read extension. | |
122 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset); | |
123 EXPECT_EQ(0x1ada03, header.extension.transmissionTimeOffset); | |
124 EXPECT_EQ(sizeof(kPacket), header.headerLength); | |
125 } | |
126 | |
127 TEST(RtpHeaderParser, ParseWithOverSizedExtension) { | |
128 // clang-format off | |
129 const uint8_t kPacket[] = { | |
130 0x90, kPayloadType, 0x00, kSeqNum, | |
131 0x65, 0x43, 0x12, 0x78, // kTimestamp. | |
132 0x12, 0x34, 0x56, 0x78, // kSsrc. | |
133 0xbe, 0xde, 0x00, 0x01, // Extension of size 1x32bit word. | |
134 0x00, // Add a byte of padding. | |
135 0x12, // Extension id 1 size (2+1). | |
136 0xda, 0x1a // Only 2 bytes of extension payload. | |
137 }; | |
138 // clang-format on | |
139 RtpHeaderExtensionMap extensions; | |
140 extensions.Register<TransmissionOffset>(1); | |
141 RtpUtility::RtpHeaderParser parser(kPacket, sizeof(kPacket)); | |
142 RTPHeader header; | |
143 | |
144 EXPECT_TRUE(parser.Parse(&header, &extensions)); | |
145 | |
146 // Parse should ignore extension. | |
147 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset); | |
148 EXPECT_EQ(sizeof(kPacket), header.headerLength); | |
149 } | |
150 | |
151 TEST(RtpHeaderParser, ParseAll6Extensions) { | |
152 const uint8_t kAudioLevel = 0x5a; | |
153 // clang-format off | |
154 const uint8_t kPacket[] = { | |
155 0x90, kPayloadType, 0x00, kSeqNum, | |
156 0x65, 0x43, 0x12, 0x78, // kTimestamp. | |
157 0x12, 0x34, 0x56, 0x78, // kSsrc. | |
158 0xbe, 0xde, 0x00, 0x05, // Extension of size 5x32bit word. | |
159 0x40, 0x80|kAudioLevel, // AudioLevel. | |
160 0x22, 0x01, 0x56, 0xce, // TransmissionOffset. | |
161 0x62, 0x12, 0x34, 0x56, // AbsoluteSendTime. | |
162 0x81, 0xce, 0xab, // TransportSequenceNumber. | |
163 0xa0, 0x03, // VideoRotation. | |
164 0xb2, 0x12, 0x48, 0x76, // PlayoutDelayLimits. | |
165 0x00, // Padding to 32bit boundary. | |
sprang_webrtc
2016/11/24 16:34:12
maybe check that this is actual 32bit boundary now
danilchap
2016/11/24 16:50:50
Done.
better check early.
If there is not enough p
| |
166 }; | |
167 // clang-format on | |
168 | |
169 RtpHeaderExtensionMap extensions; | |
170 extensions.Register<TransmissionOffset>(2); | |
171 extensions.Register<AudioLevel>(4); | |
172 extensions.Register<AbsoluteSendTime>(6); | |
173 extensions.Register<TransportSequenceNumber>(8); | |
174 extensions.Register<VideoOrientation>(0xa); | |
175 extensions.Register<PlayoutDelayLimits>(0xb); | |
176 RtpUtility::RtpHeaderParser parser(kPacket, sizeof(kPacket)); | |
177 RTPHeader header; | |
178 | |
179 EXPECT_TRUE(parser.Parse(&header, &extensions)); | |
180 | |
181 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset); | |
182 EXPECT_EQ(0x156ce, header.extension.transmissionTimeOffset); | |
183 | |
184 EXPECT_TRUE(header.extension.hasAudioLevel); | |
185 EXPECT_TRUE(header.extension.voiceActivity); | |
186 EXPECT_EQ(kAudioLevel, header.extension.audioLevel); | |
187 | |
188 EXPECT_TRUE(header.extension.hasAbsoluteSendTime); | |
189 EXPECT_EQ(0x123456U, header.extension.absoluteSendTime); | |
190 | |
191 EXPECT_TRUE(header.extension.hasTransportSequenceNumber); | |
192 EXPECT_EQ(0xceab, header.extension.transportSequenceNumber); | |
193 | |
194 EXPECT_TRUE(header.extension.hasVideoRotation); | |
195 EXPECT_EQ(kVideoRotation_270, header.extension.videoRotation); | |
196 | |
197 EXPECT_EQ(0x124 * PlayoutDelayLimits::kGranularityMs, | |
198 header.extension.playout_delay.min_ms); | |
199 EXPECT_EQ(0x876 * PlayoutDelayLimits::kGranularityMs, | |
200 header.extension.playout_delay.max_ms); | |
201 } | |
202 | |
203 TEST(RtpHeaderParser, ParseWithCsrcsExtensionAndPadding) { | |
204 const uint8_t kPacketPaddingSize = 8; | |
205 const uint32_t kCsrcs[] = {0x34567890, 0x32435465}; | |
206 const size_t kPayloadSize = 7; | |
207 // clang-format off | |
208 const uint8_t kPacket[] = { | |
209 0xb2, kPayloadType, 0x00, kSeqNum, | |
210 0x65, 0x43, 0x12, 0x78, // kTimestamp. | |
211 0x12, 0x34, 0x56, 0x78, // kSsrc. | |
212 0x34, 0x56, 0x78, 0x90, // kCsrcs[0]. | |
213 0x32, 0x43, 0x54, 0x65, // kCsrcs[1]. | |
214 0xbe, 0xde, 0x00, 0x01, // Extension. | |
215 0x12, 0x00, 0x56, 0xce, // TransmissionTimeOffset with id = 1. | |
216 'p', 'a', 'y', 'l', 'o', 'a', 'd', | |
217 'p', 'a', 'd', 'd', 'i', 'n', 'g', kPacketPaddingSize}; | |
218 // clang-format on | |
219 RtpHeaderExtensionMap extensions; | |
220 extensions.Register<TransmissionOffset>(1); | |
221 RtpUtility::RtpHeaderParser parser(kPacket, sizeof(kPacket)); | |
222 RTPHeader header; | |
223 | |
224 EXPECT_TRUE(parser.Parse(&header, &extensions)); | |
225 | |
226 EXPECT_EQ(kPayloadType, header.payloadType); | |
227 EXPECT_EQ(kSeqNum, header.sequenceNumber); | |
228 EXPECT_EQ(kTimestamp, header.timestamp); | |
229 EXPECT_EQ(kSsrc, header.ssrc); | |
230 EXPECT_THAT(make_tuple(header.arrOfCSRCs, header.numCSRCs), | |
231 ElementsAreArray(kCsrcs)); | |
232 EXPECT_EQ(kPacketPaddingSize, header.paddingLength); | |
233 EXPECT_THAT(sizeof(kPacket) - kPayloadSize - kPacketPaddingSize, | |
234 header.headerLength); | |
235 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset); | |
236 EXPECT_EQ(0x56ce, header.extension.transmissionTimeOffset); | |
237 } | |
238 | |
239 } // namespace webrtc | |
OLD | NEW |