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.
12 * This file conatins unit tests for the RtpUtility.
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h"
17 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
18 #include "webrtc/typedefs.h"
22 using RtpUtility::RTPPayloadParser;
23 using RtpUtility::RTPPayload;
24 using RtpUtility::RTPPayloadVP8;
29 // |X|R|N|S|PartID | (REQUIRED)
31 // X: |I|L|T|K| RSV | (OPTIONAL)
33 // I: | PictureID | (OPTIONAL)
35 // L: | TL0PICIDX | (OPTIONAL)
37 // T/K: |TID:Y| KEYIDX | (OPTIONAL)
58 void VerifyBasicHeader(const RTPPayloadVP8 &header,
59 bool N, bool S, int PartID) {
60 EXPECT_EQ(N, header.nonReferenceFrame);
61 EXPECT_EQ(S, header.beginningOfPartition);
62 EXPECT_EQ(PartID, header.partitionID);
65 void VerifyExtensions(const RTPPayloadVP8 &header,
66 bool I, bool L, bool T, bool K) {
67 EXPECT_EQ(I, header.hasPictureID);
68 EXPECT_EQ(L, header.hasTl0PicIdx);
69 EXPECT_EQ(T, header.hasTID);
70 EXPECT_EQ(K, header.hasKeyIdx);
73 TEST(ParseVP8Test, BasicHeader) {
74 uint8_t payload[4] = {0};
75 payload[0] = 0x14; // Binary 0001 0100; S = 1, PartID = 4.
76 payload[1] = 0x01; // P frame.
78 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 4);
80 RTPPayload parsedPacket;
81 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
83 EXPECT_EQ(RtpUtility::kPFrame, parsedPacket.frameType);
84 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
86 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 4 /*PartID*/);
87 VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
89 EXPECT_EQ(payload + 1, parsedPacket.info.VP8.data);
90 EXPECT_EQ(4 - 1, parsedPacket.info.VP8.dataLength);
93 TEST(ParseVP8Test, PictureID) {
94 uint8_t payload[10] = {0};
99 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10);
101 RTPPayload parsedPacket;
102 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
104 EXPECT_EQ(RtpUtility::kPFrame, parsedPacket.frameType);
105 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
107 VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/);
108 VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
110 EXPECT_EQ(17, parsedPacket.info.VP8.pictureID);
112 EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
113 EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
116 // Re-use payload, but change to long PictureID.
117 payload[2] = 0x80 | 17;
119 RTPPayloadParser rtpPayloadParser2(kRtpVideoVp8, payload, 10);
121 ASSERT_TRUE(rtpPayloadParser2.Parse(parsedPacket));
123 VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/);
124 VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
126 EXPECT_EQ((17<<8) + 17, parsedPacket.info.VP8.pictureID);
128 EXPECT_EQ(payload + 4, parsedPacket.info.VP8.data);
129 EXPECT_EQ(10 - 4, parsedPacket.info.VP8.dataLength);
132 TEST(ParseVP8Test, Tl0PicIdx) {
133 uint8_t payload[13] = {0};
138 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 13);
140 RTPPayload parsedPacket;
141 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
143 EXPECT_EQ(RtpUtility::kIFrame, parsedPacket.frameType);
144 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
146 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 0 /*PartID*/);
147 VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 1 /*L*/, 0 /*T*/, 0 /*K*/);
149 EXPECT_EQ(17, parsedPacket.info.VP8.tl0PicIdx);
151 EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
152 EXPECT_EQ(13 - 3, parsedPacket.info.VP8.dataLength);
155 TEST(ParseVP8Test, TIDAndLayerSync) {
156 uint8_t payload[10] = {0};
159 payload[2] = 0x80; // TID(2) + LayerSync(false)
161 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10);
163 RTPPayload parsedPacket;
164 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
166 EXPECT_EQ(RtpUtility::kPFrame, parsedPacket.frameType);
167 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
169 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
170 VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 1 /*T*/, 0 /*K*/);
172 EXPECT_EQ(2, parsedPacket.info.VP8.tID);
173 EXPECT_FALSE(parsedPacket.info.VP8.layerSync);
175 EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
176 EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
179 TEST(ParseVP8Test, KeyIdx) {
180 uint8_t payload[10] = {0};
182 payload[1] = 0x10; // K = 1.
183 payload[2] = 0x11; // KEYIDX = 17 decimal.
185 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10);
187 RTPPayload parsedPacket;
188 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
190 EXPECT_EQ(RtpUtility::kPFrame, parsedPacket.frameType);
191 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
193 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
194 VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/, 1 /*K*/);
196 EXPECT_EQ(17, parsedPacket.info.VP8.keyIdx);
198 EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
199 EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
202 TEST(ParseVP8Test, MultipleExtensions) {
203 uint8_t payload[10] = {0};
205 payload[1] = 0x80 | 0x40 | 0x20 | 0x10;
206 payload[2] = 0x80 | 17; // PictureID, high 7 bits.
207 payload[3] = 17; // PictureID, low 8 bits.
208 payload[4] = 42; // Tl0PicIdx.
209 payload[5] = 0x40 | 0x20 | 0x11; // TID(1) + LayerSync(true) + KEYIDX(17).
211 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10);
213 RTPPayload parsedPacket;
214 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
216 EXPECT_EQ(RtpUtility::kPFrame, parsedPacket.frameType);
217 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
219 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
220 VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 1 /*L*/, 1 /*T*/, 1 /*K*/);
222 EXPECT_EQ((17<<8) + 17, parsedPacket.info.VP8.pictureID);
223 EXPECT_EQ(42, parsedPacket.info.VP8.tl0PicIdx);
224 EXPECT_EQ(1, parsedPacket.info.VP8.tID);
225 EXPECT_EQ(17, parsedPacket.info.VP8.keyIdx);
227 EXPECT_EQ(payload + 6, parsedPacket.info.VP8.data);
228 EXPECT_EQ(10 - 6, parsedPacket.info.VP8.dataLength);
231 TEST(ParseVP8Test, TooShortHeader) {
232 uint8_t payload[4] = {0};
234 payload[1] = 0x80 | 0x40 | 0x20 | 0x10; // All extensions are enabled...
235 payload[2] = 0x80 | 17; // ... but only 2 bytes PictureID is provided.
236 payload[3] = 17; // PictureID, low 8 bits.
238 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 4);
240 RTPPayload parsedPacket;
241 EXPECT_FALSE(rtpPayloadParser.Parse(parsedPacket));
244 TEST(ParseVP8Test, TestWithPacketizer) {
245 uint8_t payload[10] = {0};
246 uint8_t packet[20] = {0};
247 RTPVideoHeaderVP8 inputHeader;
248 inputHeader.nonReference = true;
249 inputHeader.pictureId = 300;
250 inputHeader.temporalIdx = 1;
251 inputHeader.layerSync = false;
252 inputHeader.tl0PicIdx = kNoTl0PicIdx; // Disable.
253 inputHeader.keyIdx = 31;
254 RtpPacketizerVp8 packetizer(inputHeader, 20);
255 packetizer.SetPayloadData(payload, 10, NULL);
258 ASSERT_TRUE(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(RtpUtility::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);