1 /* 2 * Copyright (c) 2011 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 12 /* 13 * This file conatins unit tests for the ModuleRTPUtility. 14 */ 15 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" 20 21 namespace webrtc { 22 23 using ModuleRTPUtility::RTPPayloadParser; 24 using ModuleRTPUtility::RTPPayload; 25 using ModuleRTPUtility::RTPPayloadVP8; 26 27 // Payload descriptor 28 // 0 1 2 3 4 5 6 7 29 // +-+-+-+-+-+-+-+-+ 30 // |X|R|N|S|PartID | (REQUIRED) 31 // +-+-+-+-+-+-+-+-+ 32 // X: |I|L|T|K| RSV | (OPTIONAL) 33 // +-+-+-+-+-+-+-+-+ 34 // I: | PictureID | (OPTIONAL) 35 // +-+-+-+-+-+-+-+-+ 36 // L: | TL0PICIDX | (OPTIONAL) 37 // +-+-+-+-+-+-+-+-+ 38 // T/K: |TID:Y| KEYIDX | (OPTIONAL) 39 // +-+-+-+-+-+-+-+-+ 40 // 41 // Payload header 42 // 0 1 2 3 4 5 6 7 43 // +-+-+-+-+-+-+-+-+ 44 // |Size0|H| VER |P| 45 // +-+-+-+-+-+-+-+-+ 46 // | Size1 | 47 // +-+-+-+-+-+-+-+-+ 48 // | Size2 | 49 // +-+-+-+-+-+-+-+-+ 50 // | Bytes 4..N of | 51 // | VP8 payload | 52 // : : 53 // +-+-+-+-+-+-+-+-+ 54 // | OPTIONAL RTP | 55 // | padding | 56 // : : 57 // +-+-+-+-+-+-+-+-+ 58 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); 64 } 65 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); 72 } 73 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. 78 79 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 4); 80 81 RTPPayload parsedPacket; 82 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket)); 83 84 EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType); 85 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type); 86 87 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 4 /*PartID*/); 88 VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/); 89 90 EXPECT_EQ(payload + 1, parsedPacket.info.VP8.data); 91 EXPECT_EQ(4 - 1, parsedPacket.info.VP8.dataLength); 92 } 93 94 TEST(ParseVP8Test, PictureID) { 95 uint8_t payload[10] = {0}; 96 payload[0] = 0xA0; 97 payload[1] = 0x80; 98 payload[2] = 17; 99 100 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10); 101 102 RTPPayload parsedPacket; 103 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket)); 104 105 EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType); 106 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type); 107 108 VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/); 109 VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/); 110 111 EXPECT_EQ(17, parsedPacket.info.VP8.pictureID); 112 113 EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data); 114 EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength); 115 116 117 // Re-use payload, but change to long PictureID. 118 payload[2] = 0x80 | 17; 119 payload[3] = 17; 120 RTPPayloadParser rtpPayloadParser2(kRtpVideoVp8, payload, 10); 121 122 ASSERT_TRUE(rtpPayloadParser2.Parse(parsedPacket)); 123 124 VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/); 125 VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/); 126 127 EXPECT_EQ((17<<8) + 17, parsedPacket.info.VP8.pictureID); 128 129 EXPECT_EQ(payload + 4, parsedPacket.info.VP8.data); 130 EXPECT_EQ(10 - 4, parsedPacket.info.VP8.dataLength); 131 } 132 133 TEST(ParseVP8Test, Tl0PicIdx) { 134 uint8_t payload[13] = {0}; 135 payload[0] = 0x90; 136 payload[1] = 0x40; 137 payload[2] = 17; 138 139 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 13); 140 141 RTPPayload parsedPacket; 142 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket)); 143 144 EXPECT_EQ(ModuleRTPUtility::kIFrame, parsedPacket.frameType); 145 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type); 146 147 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 0 /*PartID*/); 148 VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 1 /*L*/, 0 /*T*/, 0 /*K*/); 149 150 EXPECT_EQ(17, parsedPacket.info.VP8.tl0PicIdx); 151 152 EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data); 153 EXPECT_EQ(13 - 3, parsedPacket.info.VP8.dataLength); 154 } 155 156 TEST(ParseVP8Test, TIDAndLayerSync) { 157 uint8_t payload[10] = {0}; 158 payload[0] = 0x88; 159 payload[1] = 0x20; 160 payload[2] = 0x80; // TID(2) + LayerSync(false) 161 162 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10); 163 164 RTPPayload parsedPacket; 165 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket)); 166 167 EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType); 168 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type); 169 170 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/); 171 VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 1 /*T*/, 0 /*K*/); 172 173 EXPECT_EQ(2, parsedPacket.info.VP8.tID); 174 EXPECT_FALSE(parsedPacket.info.VP8.layerSync); 175 176 EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data); 177 EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength); 178 } 179 180 TEST(ParseVP8Test, KeyIdx) { 181 uint8_t payload[10] = {0}; 182 payload[0] = 0x88; 183 payload[1] = 0x10; // K = 1. 184 payload[2] = 0x11; // KEYIDX = 17 decimal. 185 186 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10); 187 188 RTPPayload parsedPacket; 189 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket)); 190 191 EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType); 192 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type); 193 194 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/); 195 VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/, 1 /*K*/); 196 197 EXPECT_EQ(17, parsedPacket.info.VP8.keyIdx); 198 199 EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data); 200 EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength); 201 } 202 203 TEST(ParseVP8Test, MultipleExtensions) { 204 uint8_t payload[10] = {0}; 205 payload[0] = 0x88; 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). 211 212 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10); 213 214 RTPPayload parsedPacket; 215 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket)); 216 217 EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType); 218 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type); 219 220 VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/); 221 VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 1 /*L*/, 1 /*T*/, 1 /*K*/); 222 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); 227 228 EXPECT_EQ(payload + 6, parsedPacket.info.VP8.data); 229 EXPECT_EQ(10 - 6, parsedPacket.info.VP8.dataLength); 230 } 231 232 TEST(ParseVP8Test, TooShortHeader) { 233 uint8_t payload[4] = {0}; 234 payload[0] = 0x88; 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. 238 239 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 4); 240 241 RTPPayload parsedPacket; 242 EXPECT_FALSE(rtpPayloadParser.Parse(parsedPacket)); 243 } 244 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); 256 bool last; 257 int send_bytes; 258 ASSERT_EQ(0, packetizer.NextPacket(packet, &send_bytes, &last)); 259 ASSERT_TRUE(last); 260 261 RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, packet, send_bytes); 262 263 RTPPayload parsedPacket; 264 ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket)); 265 266 EXPECT_EQ(ModuleRTPUtility::kIFrame, parsedPacket.frameType); 267 EXPECT_EQ(kRtpVideoVp8, parsedPacket.type); 268 269 VerifyBasicHeader(parsedPacket.info.VP8, 270 inputHeader.nonReference /*N*/, 271 1 /*S*/, 272 0 /*PartID*/); 273 VerifyExtensions(parsedPacket.info.VP8, 274 1 /*I*/, 275 0 /*L*/, 276 1 /*T*/, 277 1 /*K*/); 278 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); 283 284 EXPECT_EQ(packet + 5, parsedPacket.info.VP8.data); 285 EXPECT_EQ(send_bytes - 5, parsedPacket.info.VP8.dataLength); 286 } 287 288 } // namespace 289