2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
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.
13 * This file conatins unit tests for the ModuleRTPUtility.
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h"
18 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
19 #include "webrtc/typedefs.h"
23 using ModuleRTPUtility::RTPPayloadParser;
24 using ModuleRTPUtility::RTPPayload;
25 using ModuleRTPUtility::RTPPayloadVP8;
30 // |X|R|N|S|PartID | (REQUIRED)
32 // X: |I|L|T|K| RSV | (OPTIONAL)
34 // I: | PictureID | (OPTIONAL)
36 // L: | TL0PICIDX | (OPTIONAL)
38 // T/K: |TID:Y| KEYIDX | (OPTIONAL)
59 void VerifyBasicHeader(const RTPPayloadVP8 &header,
60 bool N, bool S, int PartID) {
61 EXPECT_EQ(N, header.nonReferenceFrame);
62 EXPECT_EQ(S, header.beginningOfPartition);
63 EXPECT_EQ(PartID, header.partitionID);
66 void VerifyExtensions(const RTPPayloadVP8 &header,
67 bool I, bool L, bool T, bool K) {
68 EXPECT_EQ(I, header.hasPictureID);
69 EXPECT_EQ(L, header.hasTl0PicIdx);
70 EXPECT_EQ(T, header.hasTID);
71 EXPECT_EQ(K, header.hasKeyIdx);
74 TEST(ParseVP8Test, BasicHeader) {
75 uint8_t payload[4] = {0};
76 payload[0] = 0x14; // Binary 0001 0100; S = 1, PartID = 4.
77 payload[1] = 0x01; // P frame.
79 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 4);
81 RTPPayload parsedPacket;
82 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
84 EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
85 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
87 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 4 /*PartID*/);
88 VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
90 EXPECT_EQ(payload + 1, parsedPacket.info.VP8.data);
91 EXPECT_EQ(4 - 1, parsedPacket.info.VP8.dataLength);
94 TEST(ParseVP8Test, PictureID) {
95 uint8_t payload[10] = {0};
100 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10);
102 RTPPayload parsedPacket;
103 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
105 EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
106 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
108 VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/);
109 VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
111 EXPECT_EQ(17, parsedPacket.info.VP8.pictureID);
113 EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
114 EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
117 // Re-use payload, but change to long PictureID.
118 payload[2] = 0x80 | 17;
120 RTPPayloadParser rtpPayloadParser2(kRtpVideoVp8, payload, 10);
122 ASSERT_TRUE(rtpPayloadParser2.Parse(parsedPacket));
124 VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/);
125 VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
127 EXPECT_EQ((17<<8) + 17, parsedPacket.info.VP8.pictureID);
129 EXPECT_EQ(payload + 4, parsedPacket.info.VP8.data);
130 EXPECT_EQ(10 - 4, parsedPacket.info.VP8.dataLength);
133 TEST(ParseVP8Test, Tl0PicIdx) {
134 uint8_t payload[13] = {0};
139 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 13);
141 RTPPayload parsedPacket;
142 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
144 EXPECT_EQ(ModuleRTPUtility::kIFrame, parsedPacket.frameType);
145 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
147 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 0 /*PartID*/);
148 VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 1 /*L*/, 0 /*T*/, 0 /*K*/);
150 EXPECT_EQ(17, parsedPacket.info.VP8.tl0PicIdx);
152 EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
153 EXPECT_EQ(13 - 3, parsedPacket.info.VP8.dataLength);
156 TEST(ParseVP8Test, TIDAndLayerSync) {
157 uint8_t payload[10] = {0};
160 payload[2] = 0x80; // TID(2) + LayerSync(false)
162 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10);
164 RTPPayload parsedPacket;
165 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
167 EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
168 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
170 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
171 VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 1 /*T*/, 0 /*K*/);
173 EXPECT_EQ(2, parsedPacket.info.VP8.tID);
174 EXPECT_FALSE(parsedPacket.info.VP8.layerSync);
176 EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
177 EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
180 TEST(ParseVP8Test, KeyIdx) {
181 uint8_t payload[10] = {0};
183 payload[1] = 0x10; // K = 1.
184 payload[2] = 0x11; // KEYIDX = 17 decimal.
186 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10);
188 RTPPayload parsedPacket;
189 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
191 EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
192 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
194 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
195 VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/, 1 /*K*/);
197 EXPECT_EQ(17, parsedPacket.info.VP8.keyIdx);
199 EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
200 EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
203 TEST(ParseVP8Test, MultipleExtensions) {
204 uint8_t payload[10] = {0};
206 payload[1] = 0x80 | 0x40 | 0x20 | 0x10;
207 payload[2] = 0x80 | 17; // PictureID, high 7 bits.
208 payload[3] = 17; // PictureID, low 8 bits.
209 payload[4] = 42; // Tl0PicIdx.
210 payload[5] = 0x40 | 0x20 | 0x11; // TID(1) + LayerSync(true) + KEYIDX(17).
212 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10);
214 RTPPayload parsedPacket;
215 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
217 EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
218 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
220 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
221 VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 1 /*L*/, 1 /*T*/, 1 /*K*/);
223 EXPECT_EQ((17<<8) + 17, parsedPacket.info.VP8.pictureID);
224 EXPECT_EQ(42, parsedPacket.info.VP8.tl0PicIdx);
225 EXPECT_EQ(1, parsedPacket.info.VP8.tID);
226 EXPECT_EQ(17, parsedPacket.info.VP8.keyIdx);
228 EXPECT_EQ(payload + 6, parsedPacket.info.VP8.data);
229 EXPECT_EQ(10 - 6, parsedPacket.info.VP8.dataLength);
232 TEST(ParseVP8Test, TooShortHeader) {
233 uint8_t payload[4] = {0};
235 payload[1] = 0x80 | 0x40 | 0x20 | 0x10; // All extensions are enabled...
236 payload[2] = 0x80 | 17; // ... but only 2 bytes PictureID is provided.
237 payload[3] = 17; // PictureID, low 8 bits.
239 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 4);
241 RTPPayload parsedPacket;
242 EXPECT_FALSE(rtpPayloadParser.Parse(parsedPacket));
245 TEST(ParseVP8Test, TestWithPacketizer) {
246 uint8_t payload[10] = {0};
247 uint8_t packet[20] = {0};
248 RTPVideoHeaderVP8 inputHeader;
249 inputHeader.nonReference = true;
250 inputHeader.pictureId = 300;
251 inputHeader.temporalIdx = 1;
252 inputHeader.layerSync = false;
253 inputHeader.tl0PicIdx = kNoTl0PicIdx; // Disable.
254 inputHeader.keyIdx = 31;
255 RtpFormatVp8 packetizer(payload, 10, inputHeader, 20);
258 ASSERT_EQ(0, packetizer.NextPacket(packet, &send_bytes, &last));
261 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, packet, send_bytes);
263 RTPPayload parsedPacket;
264 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
266 EXPECT_EQ(ModuleRTPUtility::kIFrame, parsedPacket.frameType);
267 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
269 VerifyBasicHeader(parsedPacket.info.VP8,
270 inputHeader.nonReference /*N*/,
273 VerifyExtensions(parsedPacket.info.VP8,
279 EXPECT_EQ(inputHeader.pictureId, parsedPacket.info.VP8.pictureID);
280 EXPECT_EQ(inputHeader.temporalIdx, parsedPacket.info.VP8.tID);
281 EXPECT_EQ(inputHeader.layerSync, parsedPacket.info.VP8.layerSync);
282 EXPECT_EQ(inputHeader.keyIdx, parsedPacket.info.VP8.keyIdx);
284 EXPECT_EQ(packet + 5, parsedPacket.info.VP8.data);
285 EXPECT_EQ(send_bytes - 5, parsedPacket.info.VP8.dataLength);