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