1 /*
2 * Copyright (c) 2020 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 "modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h"
12
13 #include <cstdint>
14 #include <vector>
15
16 #include "absl/types/optional.h"
17 #include "api/array_view.h"
18 #include "common_video/h264/h264_common.h"
19 #include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
20 #include "modules/rtp_rtcp/source/byte_io.h"
21 #include "modules/rtp_rtcp/source/rtp_format_h264.h"
22 #include "rtc_base/copy_on_write_buffer.h"
23 #include "test/gmock.h"
24 #include "test/gtest.h"
25
26 namespace webrtc {
27 namespace {
28
29 using ::testing::Each;
30 using ::testing::ElementsAre;
31 using ::testing::ElementsAreArray;
32 using ::testing::Eq;
33 using ::testing::IsEmpty;
34 using ::testing::SizeIs;
35
36 enum Nalu {
37 kSlice = 1,
38 kIdr = 5,
39 kSei = 6,
40 kSps = 7,
41 kPps = 8,
42 kStapA = 24,
43 kFuA = 28
44 };
45
46 constexpr uint8_t kOriginalSps[] = {kSps, 0x00, 0x00, 0x03, 0x03,
47 0xF4, 0x05, 0x03, 0xC7, 0xC0};
48 constexpr uint8_t kRewrittenSps[] = {kSps, 0x00, 0x00, 0x03, 0x03,
49 0xF4, 0x05, 0x03, 0xC7, 0xE0,
50 0x1B, 0x41, 0x10, 0x8D, 0x00};
51 constexpr uint8_t kIdrOne[] = {kIdr, 0xFF, 0x00, 0x00, 0x04};
52 constexpr uint8_t kIdrTwo[] = {kIdr, 0xFF, 0x00, 0x11};
53
TEST(VideoRtpDepacketizerH264Test,SingleNalu)54 TEST(VideoRtpDepacketizerH264Test, SingleNalu) {
55 uint8_t packet[2] = {0x05, 0xFF}; // F=0, NRI=0, Type=5 (IDR).
56 rtc::CopyOnWriteBuffer rtp_payload(packet);
57
58 VideoRtpDepacketizerH264 depacketizer;
59 absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
60 depacketizer.Parse(rtp_payload);
61 ASSERT_TRUE(parsed);
62
63 EXPECT_EQ(parsed->video_payload, rtp_payload);
64 EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameKey);
65 EXPECT_EQ(parsed->video_header.codec, kVideoCodecH264);
66 EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
67 const RTPVideoHeaderH264& h264 =
68 absl::get<RTPVideoHeaderH264>(parsed->video_header.video_type_header);
69 EXPECT_EQ(h264.packetization_type, kH264SingleNalu);
70 EXPECT_EQ(h264.nalu_type, kIdr);
71 }
72
TEST(VideoRtpDepacketizerH264Test,SingleNaluSpsWithResolution)73 TEST(VideoRtpDepacketizerH264Test, SingleNaluSpsWithResolution) {
74 uint8_t packet[] = {kSps, 0x7A, 0x00, 0x1F, 0xBC, 0xD9, 0x40, 0x50,
75 0x05, 0xBA, 0x10, 0x00, 0x00, 0x03, 0x00, 0xC0,
76 0x00, 0x00, 0x03, 0x2A, 0xE0, 0xF1, 0x83, 0x25};
77 rtc::CopyOnWriteBuffer rtp_payload(packet);
78
79 VideoRtpDepacketizerH264 depacketizer;
80 absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
81 depacketizer.Parse(rtp_payload);
82 ASSERT_TRUE(parsed);
83
84 EXPECT_EQ(parsed->video_payload, rtp_payload);
85 EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameKey);
86 EXPECT_EQ(parsed->video_header.codec, kVideoCodecH264);
87 EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
88 EXPECT_EQ(parsed->video_header.width, 1280u);
89 EXPECT_EQ(parsed->video_header.height, 720u);
90 const auto& h264 =
91 absl::get<RTPVideoHeaderH264>(parsed->video_header.video_type_header);
92 EXPECT_EQ(h264.packetization_type, kH264SingleNalu);
93 }
94
TEST(VideoRtpDepacketizerH264Test,StapAKey)95 TEST(VideoRtpDepacketizerH264Test, StapAKey) {
96 // clang-format off
97 const NaluInfo kExpectedNalus[] = { {H264::kSps, 0, -1},
98 {H264::kPps, 1, 2},
99 {H264::kIdr, -1, 0} };
100 uint8_t packet[] = {kStapA, // F=0, NRI=0, Type=24.
101 // Length, nal header, payload.
102 0, 0x18, kExpectedNalus[0].type,
103 0x7A, 0x00, 0x1F, 0xBC, 0xD9, 0x40, 0x50, 0x05, 0xBA,
104 0x10, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x03,
105 0x2A, 0xE0, 0xF1, 0x83, 0x25,
106 0, 0xD, kExpectedNalus[1].type,
107 0x69, 0xFC, 0x0, 0x0, 0x3, 0x0, 0x7, 0xFF, 0xFF, 0xFF,
108 0xF6, 0x40,
109 0, 0xB, kExpectedNalus[2].type,
110 0x85, 0xB8, 0x0, 0x4, 0x0, 0x0, 0x13, 0x93, 0x12, 0x0};
111 // clang-format on
112 rtc::CopyOnWriteBuffer rtp_payload(packet);
113
114 VideoRtpDepacketizerH264 depacketizer;
115 absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
116 depacketizer.Parse(rtp_payload);
117 ASSERT_TRUE(parsed);
118
119 EXPECT_EQ(parsed->video_payload, rtp_payload);
120 EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameKey);
121 EXPECT_EQ(parsed->video_header.codec, kVideoCodecH264);
122 EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
123 const auto& h264 =
124 absl::get<RTPVideoHeaderH264>(parsed->video_header.video_type_header);
125 EXPECT_EQ(h264.packetization_type, kH264StapA);
126 // NALU type for aggregated packets is the type of the first packet only.
127 EXPECT_EQ(h264.nalu_type, kSps);
128 ASSERT_EQ(h264.nalus_length, 3u);
129 for (size_t i = 0; i < h264.nalus_length; ++i) {
130 EXPECT_EQ(h264.nalus[i].type, kExpectedNalus[i].type)
131 << "Failed parsing nalu " << i;
132 EXPECT_EQ(h264.nalus[i].sps_id, kExpectedNalus[i].sps_id)
133 << "Failed parsing nalu " << i;
134 EXPECT_EQ(h264.nalus[i].pps_id, kExpectedNalus[i].pps_id)
135 << "Failed parsing nalu " << i;
136 }
137 }
138
TEST(VideoRtpDepacketizerH264Test,StapANaluSpsWithResolution)139 TEST(VideoRtpDepacketizerH264Test, StapANaluSpsWithResolution) {
140 uint8_t packet[] = {kStapA, // F=0, NRI=0, Type=24.
141 // Length (2 bytes), nal header, payload.
142 0x00, 0x19, kSps, 0x7A, 0x00, 0x1F, 0xBC, 0xD9, 0x40,
143 0x50, 0x05, 0xBA, 0x10, 0x00, 0x00, 0x03, 0x00, 0xC0,
144 0x00, 0x00, 0x03, 0x2A, 0xE0, 0xF1, 0x83, 0x25, 0x80,
145 0x00, 0x03, kIdr, 0xFF, 0x00, 0x00, 0x04, kIdr, 0xFF,
146 0x00, 0x11};
147 rtc::CopyOnWriteBuffer rtp_payload(packet);
148
149 VideoRtpDepacketizerH264 depacketizer;
150 absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
151 depacketizer.Parse(rtp_payload);
152 ASSERT_TRUE(parsed);
153
154 EXPECT_EQ(parsed->video_payload, rtp_payload);
155 EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameKey);
156 EXPECT_EQ(parsed->video_header.codec, kVideoCodecH264);
157 EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
158 EXPECT_EQ(parsed->video_header.width, 1280u);
159 EXPECT_EQ(parsed->video_header.height, 720u);
160 const auto& h264 =
161 absl::get<RTPVideoHeaderH264>(parsed->video_header.video_type_header);
162 EXPECT_EQ(h264.packetization_type, kH264StapA);
163 }
164
TEST(VideoRtpDepacketizerH264Test,EmptyStapARejected)165 TEST(VideoRtpDepacketizerH264Test, EmptyStapARejected) {
166 uint8_t lone_empty_packet[] = {kStapA, 0x00, 0x00};
167 uint8_t leading_empty_packet[] = {kStapA, 0x00, 0x00, 0x00, 0x04,
168 kIdr, 0xFF, 0x00, 0x11};
169 uint8_t middle_empty_packet[] = {kStapA, 0x00, 0x03, kIdr, 0xFF, 0x00, 0x00,
170 0x00, 0x00, 0x04, kIdr, 0xFF, 0x00, 0x11};
171 uint8_t trailing_empty_packet[] = {kStapA, 0x00, 0x03, kIdr,
172 0xFF, 0x00, 0x00, 0x00};
173
174 VideoRtpDepacketizerH264 depacketizer;
175 EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(lone_empty_packet)));
176 EXPECT_FALSE(
177 depacketizer.Parse(rtc::CopyOnWriteBuffer(leading_empty_packet)));
178 EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(middle_empty_packet)));
179 EXPECT_FALSE(
180 depacketizer.Parse(rtc::CopyOnWriteBuffer(trailing_empty_packet)));
181 }
182
TEST(VideoRtpDepacketizerH264Test,DepacketizeWithRewriting)183 TEST(VideoRtpDepacketizerH264Test, DepacketizeWithRewriting) {
184 rtc::CopyOnWriteBuffer in_buffer;
185 rtc::Buffer out_buffer;
186
187 uint8_t kHeader[2] = {kStapA};
188 in_buffer.AppendData(kHeader, 1);
189 out_buffer.AppendData(kHeader, 1);
190
191 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kOriginalSps));
192 in_buffer.AppendData(kHeader, 2);
193 in_buffer.AppendData(kOriginalSps);
194 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kRewrittenSps));
195 out_buffer.AppendData(kHeader, 2);
196 out_buffer.AppendData(kRewrittenSps);
197
198 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kIdrOne));
199 in_buffer.AppendData(kHeader, 2);
200 in_buffer.AppendData(kIdrOne);
201 out_buffer.AppendData(kHeader, 2);
202 out_buffer.AppendData(kIdrOne);
203
204 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kIdrTwo));
205 in_buffer.AppendData(kHeader, 2);
206 in_buffer.AppendData(kIdrTwo);
207 out_buffer.AppendData(kHeader, 2);
208 out_buffer.AppendData(kIdrTwo);
209
210 VideoRtpDepacketizerH264 depacketizer;
211 auto parsed = depacketizer.Parse(in_buffer);
212 ASSERT_TRUE(parsed);
213 EXPECT_THAT(rtc::MakeArrayView(parsed->video_payload.cdata(),
214 parsed->video_payload.size()),
215 ElementsAreArray(out_buffer));
216 }
217
TEST(VideoRtpDepacketizerH264Test,DepacketizeWithDoubleRewriting)218 TEST(VideoRtpDepacketizerH264Test, DepacketizeWithDoubleRewriting) {
219 rtc::CopyOnWriteBuffer in_buffer;
220 rtc::Buffer out_buffer;
221
222 uint8_t kHeader[2] = {kStapA};
223 in_buffer.AppendData(kHeader, 1);
224 out_buffer.AppendData(kHeader, 1);
225
226 // First SPS will be kept...
227 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kOriginalSps));
228 in_buffer.AppendData(kHeader, 2);
229 in_buffer.AppendData(kOriginalSps);
230 out_buffer.AppendData(kHeader, 2);
231 out_buffer.AppendData(kOriginalSps);
232
233 // ...only the second one will be rewritten.
234 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kOriginalSps));
235 in_buffer.AppendData(kHeader, 2);
236 in_buffer.AppendData(kOriginalSps);
237 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kRewrittenSps));
238 out_buffer.AppendData(kHeader, 2);
239 out_buffer.AppendData(kRewrittenSps);
240
241 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kIdrOne));
242 in_buffer.AppendData(kHeader, 2);
243 in_buffer.AppendData(kIdrOne);
244 out_buffer.AppendData(kHeader, 2);
245 out_buffer.AppendData(kIdrOne);
246
247 ByteWriter<uint16_t>::WriteBigEndian(kHeader, sizeof(kIdrTwo));
248 in_buffer.AppendData(kHeader, 2);
249 in_buffer.AppendData(kIdrTwo);
250 out_buffer.AppendData(kHeader, 2);
251 out_buffer.AppendData(kIdrTwo);
252
253 VideoRtpDepacketizerH264 depacketizer;
254 auto parsed = depacketizer.Parse(in_buffer);
255 ASSERT_TRUE(parsed);
256 std::vector<uint8_t> expected_packet_payload(
257 out_buffer.data(), &out_buffer.data()[out_buffer.size()]);
258 EXPECT_THAT(rtc::MakeArrayView(parsed->video_payload.cdata(),
259 parsed->video_payload.size()),
260 ElementsAreArray(out_buffer));
261 }
262
TEST(VideoRtpDepacketizerH264Test,StapADelta)263 TEST(VideoRtpDepacketizerH264Test, StapADelta) {
264 uint8_t packet[16] = {kStapA, // F=0, NRI=0, Type=24.
265 // Length, nal header, payload.
266 0, 0x02, kSlice, 0xFF, 0, 0x03, kSlice, 0xFF, 0x00, 0,
267 0x04, kSlice, 0xFF, 0x00, 0x11};
268 rtc::CopyOnWriteBuffer rtp_payload(packet);
269
270 VideoRtpDepacketizerH264 depacketizer;
271 absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
272 depacketizer.Parse(rtp_payload);
273 ASSERT_TRUE(parsed);
274
275 EXPECT_EQ(parsed->video_payload.size(), rtp_payload.size());
276 EXPECT_EQ(parsed->video_payload.cdata(), rtp_payload.cdata());
277
278 EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameDelta);
279 EXPECT_EQ(parsed->video_header.codec, kVideoCodecH264);
280 EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
281 const RTPVideoHeaderH264& h264 =
282 absl::get<RTPVideoHeaderH264>(parsed->video_header.video_type_header);
283 EXPECT_EQ(h264.packetization_type, kH264StapA);
284 // NALU type for aggregated packets is the type of the first packet only.
285 EXPECT_EQ(h264.nalu_type, kSlice);
286 }
287
TEST(VideoRtpDepacketizerH264Test,FuA)288 TEST(VideoRtpDepacketizerH264Test, FuA) {
289 // clang-format off
290 uint8_t packet1[] = {
291 kFuA, // F=0, NRI=0, Type=28.
292 kH264SBit | kIdr, // FU header.
293 0x85, 0xB8, 0x0, 0x4, 0x0, 0x0, 0x13, 0x93, 0x12, 0x0 // Payload.
294 };
295 // clang-format on
296 const uint8_t kExpected1[] = {kIdr, 0x85, 0xB8, 0x0, 0x4, 0x0,
297 0x0, 0x13, 0x93, 0x12, 0x0};
298
299 uint8_t packet2[] = {
300 kFuA, // F=0, NRI=0, Type=28.
301 kIdr, // FU header.
302 0x02 // Payload.
303 };
304 const uint8_t kExpected2[] = {0x02};
305
306 uint8_t packet3[] = {
307 kFuA, // F=0, NRI=0, Type=28.
308 kH264EBit | kIdr, // FU header.
309 0x03 // Payload.
310 };
311 const uint8_t kExpected3[] = {0x03};
312
313 VideoRtpDepacketizerH264 depacketizer;
314 absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed1 =
315 depacketizer.Parse(rtc::CopyOnWriteBuffer(packet1));
316 ASSERT_TRUE(parsed1);
317 // We expect that the first packet is one byte shorter since the FU-A header
318 // has been replaced by the original nal header.
319 EXPECT_THAT(rtc::MakeArrayView(parsed1->video_payload.cdata(),
320 parsed1->video_payload.size()),
321 ElementsAreArray(kExpected1));
322 EXPECT_EQ(parsed1->video_header.frame_type, VideoFrameType::kVideoFrameKey);
323 EXPECT_EQ(parsed1->video_header.codec, kVideoCodecH264);
324 EXPECT_TRUE(parsed1->video_header.is_first_packet_in_frame);
325 {
326 const RTPVideoHeaderH264& h264 =
327 absl::get<RTPVideoHeaderH264>(parsed1->video_header.video_type_header);
328 EXPECT_EQ(h264.packetization_type, kH264FuA);
329 EXPECT_EQ(h264.nalu_type, kIdr);
330 ASSERT_EQ(h264.nalus_length, 1u);
331 EXPECT_EQ(h264.nalus[0].type, static_cast<H264::NaluType>(kIdr));
332 EXPECT_EQ(h264.nalus[0].sps_id, -1);
333 EXPECT_EQ(h264.nalus[0].pps_id, 0);
334 }
335
336 // Following packets will be 2 bytes shorter since they will only be appended
337 // onto the first packet.
338 auto parsed2 = depacketizer.Parse(rtc::CopyOnWriteBuffer(packet2));
339 EXPECT_THAT(rtc::MakeArrayView(parsed2->video_payload.cdata(),
340 parsed2->video_payload.size()),
341 ElementsAreArray(kExpected2));
342 EXPECT_FALSE(parsed2->video_header.is_first_packet_in_frame);
343 EXPECT_EQ(parsed2->video_header.codec, kVideoCodecH264);
344 {
345 const RTPVideoHeaderH264& h264 =
346 absl::get<RTPVideoHeaderH264>(parsed2->video_header.video_type_header);
347 EXPECT_EQ(h264.packetization_type, kH264FuA);
348 EXPECT_EQ(h264.nalu_type, kIdr);
349 // NALU info is only expected for the first FU-A packet.
350 EXPECT_EQ(h264.nalus_length, 0u);
351 }
352
353 auto parsed3 = depacketizer.Parse(rtc::CopyOnWriteBuffer(packet3));
354 EXPECT_THAT(rtc::MakeArrayView(parsed3->video_payload.cdata(),
355 parsed3->video_payload.size()),
356 ElementsAreArray(kExpected3));
357 EXPECT_FALSE(parsed3->video_header.is_first_packet_in_frame);
358 EXPECT_EQ(parsed3->video_header.codec, kVideoCodecH264);
359 {
360 const RTPVideoHeaderH264& h264 =
361 absl::get<RTPVideoHeaderH264>(parsed3->video_header.video_type_header);
362 EXPECT_EQ(h264.packetization_type, kH264FuA);
363 EXPECT_EQ(h264.nalu_type, kIdr);
364 // NALU info is only expected for the first FU-A packet.
365 ASSERT_EQ(h264.nalus_length, 0u);
366 }
367 }
368
TEST(VideoRtpDepacketizerH264Test,EmptyPayload)369 TEST(VideoRtpDepacketizerH264Test, EmptyPayload) {
370 rtc::CopyOnWriteBuffer empty;
371 VideoRtpDepacketizerH264 depacketizer;
372 EXPECT_FALSE(depacketizer.Parse(empty));
373 }
374
TEST(VideoRtpDepacketizerH264Test,TruncatedFuaNalu)375 TEST(VideoRtpDepacketizerH264Test, TruncatedFuaNalu) {
376 const uint8_t kPayload[] = {0x9c};
377 VideoRtpDepacketizerH264 depacketizer;
378 EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload)));
379 }
380
TEST(VideoRtpDepacketizerH264Test,TruncatedSingleStapANalu)381 TEST(VideoRtpDepacketizerH264Test, TruncatedSingleStapANalu) {
382 const uint8_t kPayload[] = {0xd8, 0x27};
383 VideoRtpDepacketizerH264 depacketizer;
384 EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload)));
385 }
386
TEST(VideoRtpDepacketizerH264Test,StapAPacketWithTruncatedNalUnits)387 TEST(VideoRtpDepacketizerH264Test, StapAPacketWithTruncatedNalUnits) {
388 const uint8_t kPayload[] = {0x58, 0xCB, 0xED, 0xDF};
389 VideoRtpDepacketizerH264 depacketizer;
390 EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload)));
391 }
392
TEST(VideoRtpDepacketizerH264Test,TruncationJustAfterSingleStapANalu)393 TEST(VideoRtpDepacketizerH264Test, TruncationJustAfterSingleStapANalu) {
394 const uint8_t kPayload[] = {0x38, 0x27, 0x27};
395 VideoRtpDepacketizerH264 depacketizer;
396 EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload)));
397 }
398
TEST(VideoRtpDepacketizerH264Test,ShortSpsPacket)399 TEST(VideoRtpDepacketizerH264Test, ShortSpsPacket) {
400 const uint8_t kPayload[] = {0x27, 0x80, 0x00};
401 VideoRtpDepacketizerH264 depacketizer;
402 EXPECT_TRUE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload)));
403 }
404
TEST(VideoRtpDepacketizerH264Test,SeiPacket)405 TEST(VideoRtpDepacketizerH264Test, SeiPacket) {
406 const uint8_t kPayload[] = {
407 kSei, // F=0, NRI=0, Type=6.
408 0x03, 0x03, 0x03, 0x03 // Payload.
409 };
410 VideoRtpDepacketizerH264 depacketizer;
411 auto parsed = depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload));
412 ASSERT_TRUE(parsed);
413 const RTPVideoHeaderH264& h264 =
414 absl::get<RTPVideoHeaderH264>(parsed->video_header.video_type_header);
415 EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameDelta);
416 EXPECT_EQ(h264.packetization_type, kH264SingleNalu);
417 EXPECT_EQ(h264.nalu_type, kSei);
418 ASSERT_EQ(h264.nalus_length, 1u);
419 EXPECT_EQ(h264.nalus[0].type, static_cast<H264::NaluType>(kSei));
420 EXPECT_EQ(h264.nalus[0].sps_id, -1);
421 EXPECT_EQ(h264.nalus[0].pps_id, -1);
422 }
423
424 } // namespace
425 } // namespace webrtc
426