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 |
(...skipping 17 matching lines...) Expand all Loading... |
28 VCMPacket GetDefaultPacket() { | 28 VCMPacket GetDefaultPacket() { |
29 VCMPacket packet; | 29 VCMPacket packet; |
30 packet.codec = kVideoCodecH264; | 30 packet.codec = kVideoCodecH264; |
31 packet.video_header.codecHeader.H264.nalus_length = 0; | 31 packet.video_header.codecHeader.H264.nalus_length = 0; |
32 packet.video_header.is_first_packet_in_frame = false; | 32 packet.video_header.is_first_packet_in_frame = false; |
33 packet.video_header.codecHeader.H264.packetization_type = kH264SingleNalu; | 33 packet.video_header.codecHeader.H264.packetization_type = kH264SingleNalu; |
34 | 34 |
35 return packet; | 35 return packet; |
36 } | 36 } |
37 | 37 |
38 void AddSps(VCMPacket* packet, int sps_id, std::vector<uint8_t>* data) { | 38 void AddSps(VCMPacket* packet, uint8_t sps_id, std::vector<uint8_t>* data) { |
39 NaluInfo info; | 39 NaluInfo info; |
40 info.type = H264::NaluType::kSps; | 40 info.type = H264::NaluType::kSps; |
41 info.sps_id = sps_id; | 41 info.sps_id = sps_id; |
42 info.pps_id = -1; | 42 info.pps_id = -1; |
43 info.offset = data->size(); | |
44 info.size = 2; | |
45 data->push_back(H264::NaluType::kSps); | 43 data->push_back(H264::NaluType::kSps); |
46 data->push_back(sps_id); // The sps data, just a single byte. | 44 data->push_back(sps_id); // The sps data, just a single byte. |
47 | 45 |
48 packet->video_header.codecHeader.H264 | 46 packet->video_header.codecHeader.H264 |
49 .nalus[packet->video_header.codecHeader.H264.nalus_length++] = info; | 47 .nalus[packet->video_header.codecHeader.H264.nalus_length++] = info; |
50 } | 48 } |
51 | 49 |
52 void AddPps(VCMPacket* packet, | 50 void AddPps(VCMPacket* packet, |
53 int sps_id, | 51 uint8_t sps_id, |
54 int pps_id, | 52 uint8_t pps_id, |
55 std::vector<uint8_t>* data) { | 53 std::vector<uint8_t>* data) { |
56 NaluInfo info; | 54 NaluInfo info; |
57 info.type = H264::NaluType::kPps; | 55 info.type = H264::NaluType::kPps; |
58 info.sps_id = sps_id; | 56 info.sps_id = sps_id; |
59 info.pps_id = pps_id; | 57 info.pps_id = pps_id; |
60 info.offset = data->size(); | |
61 info.size = 2; | |
62 data->push_back(H264::NaluType::kPps); | 58 data->push_back(H264::NaluType::kPps); |
63 data->push_back(pps_id); // The pps data, just a single byte. | 59 data->push_back(pps_id); // The pps data, just a single byte. |
64 | 60 |
65 packet->video_header.codecHeader.H264 | 61 packet->video_header.codecHeader.H264 |
66 .nalus[packet->video_header.codecHeader.H264.nalus_length++] = info; | 62 .nalus[packet->video_header.codecHeader.H264.nalus_length++] = info; |
67 } | 63 } |
68 | 64 |
69 void AddIdr(VCMPacket* packet, int pps_id) { | 65 void AddIdr(VCMPacket* packet, int pps_id) { |
70 NaluInfo info; | 66 NaluInfo info; |
71 info.type = H264::NaluType::kIdr; | 67 info.type = H264::NaluType::kIdr; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 std::vector<uint8_t> data; | 189 std::vector<uint8_t> data; |
194 VCMPacket sps_pps_packet = GetDefaultPacket(); | 190 VCMPacket sps_pps_packet = GetDefaultPacket(); |
195 | 191 |
196 // Insert SPS/PPS | 192 // Insert SPS/PPS |
197 AddSps(&sps_pps_packet, 0, &data); | 193 AddSps(&sps_pps_packet, 0, &data); |
198 AddPps(&sps_pps_packet, 0, 1, &data); | 194 AddPps(&sps_pps_packet, 0, 1, &data); |
199 sps_pps_packet.dataPtr = data.data(); | 195 sps_pps_packet.dataPtr = data.data(); |
200 sps_pps_packet.sizeBytes = data.size(); | 196 sps_pps_packet.sizeBytes = data.size(); |
201 EXPECT_EQ(H264SpsPpsTracker::kInsert, | 197 EXPECT_EQ(H264SpsPpsTracker::kInsert, |
202 tracker_.CopyAndFixBitstream(&sps_pps_packet)); | 198 tracker_.CopyAndFixBitstream(&sps_pps_packet)); |
| 199 delete[] sps_pps_packet.dataPtr; |
203 data.clear(); | 200 data.clear(); |
204 | 201 |
205 // Insert first packet of the IDR | 202 // Insert first packet of the IDR |
206 VCMPacket idr_packet = GetDefaultPacket(); | 203 VCMPacket idr_packet = GetDefaultPacket(); |
207 idr_packet.video_header.is_first_packet_in_frame = true; | 204 idr_packet.video_header.is_first_packet_in_frame = true; |
208 AddIdr(&idr_packet, 1); | 205 AddIdr(&idr_packet, 1); |
209 data.insert(data.end(), {1, 2, 3}); | 206 data.insert(data.end(), {1, 2, 3}); |
210 idr_packet.dataPtr = data.data(); | 207 idr_packet.dataPtr = data.data(); |
211 idr_packet.sizeBytes = data.size(); | 208 idr_packet.sizeBytes = data.size(); |
212 EXPECT_EQ(H264SpsPpsTracker::kInsert, | 209 EXPECT_EQ(H264SpsPpsTracker::kInsert, |
213 tracker_.CopyAndFixBitstream(&idr_packet)); | 210 tracker_.CopyAndFixBitstream(&idr_packet)); |
214 | 211 |
215 std::vector<uint8_t> expected; | 212 std::vector<uint8_t> expected; |
216 expected.insert(expected.end(), start_code, start_code + sizeof(start_code)); | 213 expected.insert(expected.end(), start_code, start_code + sizeof(start_code)); |
217 expected.insert(expected.end(), {H264::NaluType::kSps, 0}); | |
218 expected.insert(expected.end(), start_code, start_code + sizeof(start_code)); | |
219 expected.insert(expected.end(), {H264::NaluType::kPps, 1}); | |
220 expected.insert(expected.end(), start_code, start_code + sizeof(start_code)); | |
221 expected.insert(expected.end(), {1, 2, 3}); | 214 expected.insert(expected.end(), {1, 2, 3}); |
222 EXPECT_EQ(memcmp(idr_packet.dataPtr, expected.data(), expected.size()), 0); | 215 EXPECT_EQ(memcmp(idr_packet.dataPtr, expected.data(), expected.size()), 0); |
223 delete[] idr_packet.dataPtr; | 216 delete[] idr_packet.dataPtr; |
224 } | 217 } |
225 | 218 |
226 TEST_F(TestH264SpsPpsTracker, SpsPpsIdrInStapA) { | 219 TEST_F(TestH264SpsPpsTracker, SpsPpsIdrInStapA) { |
227 std::vector<uint8_t> data; | 220 std::vector<uint8_t> data; |
228 VCMPacket packet = GetDefaultPacket(); | 221 VCMPacket packet = GetDefaultPacket(); |
229 packet.video_header.codecHeader.H264.packetization_type = kH264StapA; | 222 packet.video_header.codecHeader.H264.packetization_type = kH264StapA; |
230 packet.video_header.is_first_packet_in_frame = true; // Always true for StapA | 223 packet.video_header.is_first_packet_in_frame = true; // Always true for StapA |
231 | 224 |
232 data.insert(data.end(), {0}); // First byte is ignored | 225 data.insert(data.end(), {0}); // First byte is ignored |
233 data.insert(data.end(), {0, 2}); // Length of segment | 226 data.insert(data.end(), {0, 2}); // Length of segment |
234 AddSps(&packet, 13, &data); | 227 AddSps(&packet, 13, &data); |
235 data.insert(data.end(), {0, 2}); // Length of segment | 228 data.insert(data.end(), {0, 2}); // Length of segment |
236 AddPps(&packet, 13, 27, &data); | 229 AddPps(&packet, 13, 27, &data); |
237 data.insert(data.end(), {0, 5}); // Length of segment | 230 data.insert(data.end(), {0, 5}); // Length of segment |
238 AddIdr(&packet, 27); | 231 AddIdr(&packet, 27); |
239 data.insert(data.end(), {1, 2, 3, 2, 1}); | 232 data.insert(data.end(), {1, 2, 3, 2, 1}); |
240 | 233 |
241 packet.dataPtr = data.data(); | 234 packet.dataPtr = data.data(); |
242 packet.sizeBytes = data.size(); | 235 packet.sizeBytes = data.size(); |
243 EXPECT_EQ(H264SpsPpsTracker::kInsert, tracker_.CopyAndFixBitstream(&packet)); | 236 EXPECT_EQ(H264SpsPpsTracker::kInsert, tracker_.CopyAndFixBitstream(&packet)); |
244 | 237 |
245 std::vector<uint8_t> expected; | 238 std::vector<uint8_t> expected; |
246 // The SPS/PPS is repeated because this packet both contains the SPS/PPS | |
247 // and it is the first packet of an IDR, which will cause the SPS/PPS to be | |
248 // prepended to the bitstream. | |
249 expected.insert(expected.end(), start_code, start_code + sizeof(start_code)); | 239 expected.insert(expected.end(), start_code, start_code + sizeof(start_code)); |
250 expected.insert(expected.end(), {H264::NaluType::kSps, 13}); | 240 expected.insert(expected.end(), {H264::NaluType::kSps, 13}); |
251 expected.insert(expected.end(), start_code, start_code + sizeof(start_code)); | 241 expected.insert(expected.end(), start_code, start_code + sizeof(start_code)); |
252 expected.insert(expected.end(), {H264::NaluType::kPps, 27}); | |
253 expected.insert(expected.end(), start_code, start_code + sizeof(start_code)); | |
254 expected.insert(expected.end(), {H264::NaluType::kSps, 13}); | |
255 expected.insert(expected.end(), start_code, start_code + sizeof(start_code)); | |
256 expected.insert(expected.end(), {H264::NaluType::kPps, 27}); | 242 expected.insert(expected.end(), {H264::NaluType::kPps, 27}); |
257 expected.insert(expected.end(), start_code, start_code + sizeof(start_code)); | 243 expected.insert(expected.end(), start_code, start_code + sizeof(start_code)); |
258 expected.insert(expected.end(), {1, 2, 3, 2, 1}); | 244 expected.insert(expected.end(), {1, 2, 3, 2, 1}); |
259 | 245 |
260 EXPECT_EQ(memcmp(packet.dataPtr, expected.data(), expected.size()), 0); | 246 EXPECT_EQ(memcmp(packet.dataPtr, expected.data(), expected.size()), 0); |
261 delete[] packet.dataPtr; | 247 delete[] packet.dataPtr; |
262 } | 248 } |
263 | 249 |
264 TEST_F(TestH264SpsPpsTracker, SpsPpsOutOfBand) { | 250 TEST_F(TestH264SpsPpsTracker, SpsPpsOutOfBand) { |
265 constexpr uint8_t kData[] = {1, 2, 3}; | 251 constexpr uint8_t kData[] = {1, 2, 3}; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 // that information is set on the first IDR packet. | 323 // that information is set on the first IDR packet. |
338 VCMPacket sps_pps_packet = GetDefaultPacket(); | 324 VCMPacket sps_pps_packet = GetDefaultPacket(); |
339 AddSps(&sps_pps_packet, 0, &data); | 325 AddSps(&sps_pps_packet, 0, &data); |
340 AddPps(&sps_pps_packet, 0, 1, &data); | 326 AddPps(&sps_pps_packet, 0, 1, &data); |
341 sps_pps_packet.dataPtr = data.data(); | 327 sps_pps_packet.dataPtr = data.data(); |
342 sps_pps_packet.sizeBytes = data.size(); | 328 sps_pps_packet.sizeBytes = data.size(); |
343 sps_pps_packet.width = 320; | 329 sps_pps_packet.width = 320; |
344 sps_pps_packet.height = 240; | 330 sps_pps_packet.height = 240; |
345 EXPECT_EQ(H264SpsPpsTracker::kInsert, | 331 EXPECT_EQ(H264SpsPpsTracker::kInsert, |
346 tracker_.CopyAndFixBitstream(&sps_pps_packet)); | 332 tracker_.CopyAndFixBitstream(&sps_pps_packet)); |
| 333 delete[] sps_pps_packet.dataPtr; |
347 | 334 |
348 VCMPacket idr_packet = GetDefaultPacket(); | 335 VCMPacket idr_packet = GetDefaultPacket(); |
349 idr_packet.video_header.is_first_packet_in_frame = true; | 336 idr_packet.video_header.is_first_packet_in_frame = true; |
350 AddIdr(&idr_packet, 1); | 337 AddIdr(&idr_packet, 1); |
351 data.insert(data.end(), {1, 2, 3}); | 338 data.insert(data.end(), {1, 2, 3}); |
352 idr_packet.dataPtr = data.data(); | 339 idr_packet.dataPtr = data.data(); |
353 idr_packet.sizeBytes = data.size(); | 340 idr_packet.sizeBytes = data.size(); |
354 EXPECT_EQ(H264SpsPpsTracker::kInsert, | 341 EXPECT_EQ(H264SpsPpsTracker::kInsert, |
355 tracker_.CopyAndFixBitstream(&idr_packet)); | 342 tracker_.CopyAndFixBitstream(&idr_packet)); |
356 | 343 |
357 EXPECT_EQ(320, idr_packet.width); | 344 EXPECT_EQ(320, idr_packet.width); |
358 EXPECT_EQ(240, idr_packet.height); | 345 EXPECT_EQ(240, idr_packet.height); |
359 delete[] idr_packet.dataPtr; | 346 delete[] idr_packet.dataPtr; |
360 } | 347 } |
361 | 348 |
362 } // namespace video_coding | 349 } // namespace video_coding |
363 } // namespace webrtc | 350 } // namespace webrtc |
OLD | NEW |