xref: /webrtc/rtp/src/codecs/h265/h265_test.rs (revision e17b8def)
1 use super::*;
2 
3 #[test]
test_h265_nalu_header() -> Result<()>4 fn test_h265_nalu_header() -> Result<()> {
5     #[derive(Default)]
6     struct TestType {
7         raw_header: Bytes,
8 
9         fbit: bool,
10         typ: u8,
11         layer_id: u8,
12         tid: u8,
13 
14         is_ap: bool,
15         is_fu: bool,
16         is_paci: bool,
17     }
18 
19     let tests = vec![
20         // fbit
21         TestType {
22             raw_header: Bytes::from_static(&[0x80, 0x00]),
23             typ: 0,
24             layer_id: 0,
25             tid: 0,
26             fbit: true,
27             ..Default::default()
28         },
29         // VPS_NUT
30         TestType {
31             raw_header: Bytes::from_static(&[0x40, 0x01]),
32             typ: 32,
33             layer_id: 0,
34             tid: 1,
35             ..Default::default()
36         },
37         // SPS_NUT
38         TestType {
39             raw_header: Bytes::from_static(&[0x42, 0x01]),
40             typ: 33,
41             layer_id: 0,
42             tid: 1,
43             ..Default::default()
44         },
45         // PPS_NUT
46         TestType {
47             raw_header: Bytes::from_static(&[0x44, 0x01]),
48             typ: 34,
49             layer_id: 0,
50             tid: 1,
51             ..Default::default()
52         },
53         // PREFIX_SEI_NUT
54         TestType {
55             raw_header: Bytes::from_static(&[0x4e, 0x01]),
56             typ: 39,
57             layer_id: 0,
58             tid: 1,
59             ..Default::default()
60         },
61         // Fragmentation Unit
62         TestType {
63             raw_header: Bytes::from_static(&[0x62, 0x01]),
64             typ: H265NALU_FRAGMENTATION_UNIT_TYPE,
65             layer_id: 0,
66             tid: 1,
67             is_fu: true,
68             ..Default::default()
69         },
70     ];
71 
72     for cur in tests {
73         let header = H265NALUHeader::new(cur.raw_header[0], cur.raw_header[1]);
74 
75         assert_eq!(header.f(), cur.fbit, "invalid F bit");
76         assert_eq!(header.nalu_type(), cur.typ, "invalid type");
77 
78         // For any type < 32, NAL is a VLC NAL unit.
79         assert_eq!(
80             header.is_type_vcl_unit(),
81             (header.nalu_type() < 32),
82             "invalid IsTypeVCLUnit"
83         );
84         assert_eq!(
85             header.is_aggregation_packet(),
86             cur.is_ap,
87             "invalid type (aggregation packet)"
88         );
89         assert_eq!(
90             header.is_fragmentation_unit(),
91             cur.is_fu,
92             "invalid type (fragmentation unit)"
93         );
94         assert_eq!(header.is_paci_packet(), cur.is_paci, "invalid type (PACI)");
95         assert_eq!(header.layer_id(), cur.layer_id, "invalid layer_id");
96         assert_eq!(header.tid(), cur.tid, "invalid tid");
97     }
98 
99     Ok(())
100 }
101 
102 #[test]
test_h265_fu_header() -> Result<()>103 fn test_h265_fu_header() -> Result<()> {
104     #[derive(Default)]
105     struct TestType {
106         header: H265FragmentationUnitHeader,
107 
108         s: bool,
109         e: bool,
110         typ: u8,
111     }
112 
113     let tests = vec![
114         // Start | IDR_W_RADL
115         TestType {
116             header: H265FragmentationUnitHeader(0x93),
117             s: true,
118             e: false,
119             typ: 19,
120         },
121         // Continuation | IDR_W_RADL
122         TestType {
123             header: H265FragmentationUnitHeader(0x13),
124             s: false,
125             e: false,
126             typ: 19,
127         },
128         // End | IDR_W_RADL
129         TestType {
130             header: H265FragmentationUnitHeader(0x53),
131             s: false,
132             e: true,
133             typ: 19,
134         },
135         // Start | TRAIL_R
136         TestType {
137             header: H265FragmentationUnitHeader(0x81),
138             s: true,
139             e: false,
140             typ: 1,
141         },
142         // Continuation | TRAIL_R
143         TestType {
144             header: H265FragmentationUnitHeader(0x01),
145             s: false,
146             e: false,
147             typ: 1,
148         },
149         // End | TRAIL_R
150         TestType {
151             header: H265FragmentationUnitHeader(0x41),
152             s: false,
153             e: true,
154             typ: 1,
155         },
156     ];
157 
158     for cur in tests {
159         assert_eq!(cur.header.s(), cur.s, "invalid s field");
160         assert_eq!(cur.header.e(), cur.e, "invalid e field");
161         assert_eq!(cur.header.fu_type(), cur.typ, "invalid FuType field");
162     }
163 
164     Ok(())
165 }
166 
167 #[test]
test_h265_single_nalunit_packet() -> Result<()>168 fn test_h265_single_nalunit_packet() -> Result<()> {
169     #[derive(Default)]
170     struct TestType {
171         raw: Bytes,
172         with_donl: bool,
173         expected_packet: Option<H265SingleNALUnitPacket>,
174         expected_err: Option<Error>,
175     }
176 
177     let tests = vec![
178         TestType {
179             raw: Bytes::from_static(&[]),
180             expected_err: Some(Error::ErrShortPacket),
181             ..Default::default()
182         },
183         TestType {
184             raw: Bytes::from_static(&[0x62]),
185             expected_err: Some(Error::ErrShortPacket),
186             ..Default::default()
187         },
188         TestType {
189             raw: Bytes::from_static(&[0x62, 0x01, 0x93]),
190             expected_err: Some(Error::ErrShortPacket),
191             ..Default::default()
192         },
193         // FBit enabled in H265NALUHeader
194         TestType {
195             raw: Bytes::from_static(&[0x80, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]),
196             expected_err: Some(Error::ErrH265CorruptedPacket),
197             ..Default::default()
198         },
199         // Type '49' in H265NALUHeader
200         TestType {
201             raw: Bytes::from_static(&[0x62, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]),
202             expected_err: Some(Error::ErrInvalidH265PacketType),
203             ..Default::default()
204         },
205         // Type '50' in H265NALUHeader
206         TestType {
207             raw: Bytes::from_static(&[0x64, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]),
208             expected_err: Some(Error::ErrInvalidH265PacketType),
209             ..Default::default()
210         },
211         TestType {
212             raw: Bytes::from_static(&[0x01, 0x01, 0xab, 0xcd, 0xef]),
213             expected_packet: Some(H265SingleNALUnitPacket {
214                 payload_header: H265NALUHeader::new(0x01, 0x01),
215                 payload: Bytes::from_static(&[0xab, 0xcd, 0xef]),
216                 ..Default::default()
217             }),
218             ..Default::default()
219         },
220         // DONL, payload too small
221         TestType {
222             raw: Bytes::from_static(&[0x01, 0x01, 0x93, 0xaf]),
223             expected_err: Some(Error::ErrShortPacket),
224             with_donl: true,
225             ..Default::default()
226         },
227         TestType {
228             raw: Bytes::from_static(&[0x01, 0x01, 0xaa, 0xbb, 0xcc]),
229             expected_packet: Some(H265SingleNALUnitPacket {
230                 payload_header: H265NALUHeader::new(0x01, 0x01),
231                 donl: Some((0xaa << 8) | 0xbb),
232                 payload: Bytes::from_static(&[0xcc]),
233                 ..Default::default()
234             }),
235             with_donl: true,
236             ..Default::default()
237         },
238     ];
239 
240     for cur in tests {
241         let mut parsed = H265SingleNALUnitPacket::default();
242         if cur.with_donl {
243             parsed.with_donl(cur.with_donl);
244         }
245 
246         let result = parsed.depacketize(&cur.raw);
247 
248         if cur.expected_err.is_some() && result.is_ok() {
249             panic!("should error");
250         } else if cur.expected_err.is_none() && result.is_err() {
251             panic!("should not error");
252         }
253 
254         if let Some(expected_packet) = cur.expected_packet {
255             assert_eq!(
256                 parsed.payload_header(),
257                 expected_packet.payload_header(),
258                 "invalid payload header"
259             );
260             assert_eq!(parsed.donl(), expected_packet.donl(), "invalid DONL");
261 
262             assert_eq!(
263                 parsed.payload(),
264                 expected_packet.payload(),
265                 "invalid payload"
266             );
267         }
268     }
269 
270     Ok(())
271 }
272 
273 #[test]
test_h265_aggregation_packet() -> Result<()>274 fn test_h265_aggregation_packet() -> Result<()> {
275     #[derive(Default)]
276     struct TestType {
277         raw: Bytes,
278         with_donl: bool,
279         expected_packet: Option<H265AggregationPacket>,
280         expected_err: Option<Error>,
281     }
282 
283     let tests = vec![
284         TestType {
285             raw: Bytes::from_static(&[]),
286             expected_err: Some(Error::ErrShortPacket),
287             ..Default::default()
288         },
289         TestType {
290             raw: Bytes::from_static(&[0x62]),
291             expected_err: Some(Error::ErrShortPacket),
292             ..Default::default()
293         },
294         TestType {
295             raw: Bytes::from_static(&[0x62, 0x01, 0x93]),
296             expected_err: Some(Error::ErrShortPacket),
297             ..Default::default()
298         },
299         // FBit enabled in H265NALUHeader
300         TestType {
301             raw: Bytes::from_static(&[0x80, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]),
302             expected_err: Some(Error::ErrH265CorruptedPacket),
303             ..Default::default()
304         },
305         // Type '48' in H265NALUHeader
306         TestType {
307             raw: Bytes::from_static(&[0xE0, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]),
308             expected_err: Some(Error::ErrInvalidH265PacketType),
309             ..Default::default()
310         },
311         // Small payload
312         TestType {
313             raw: Bytes::from_static(&[0x60, 0x01, 0x00, 0x1]),
314             expected_err: Some(Error::ErrShortPacket),
315             ..Default::default()
316         },
317         // Small payload
318         TestType {
319             raw: Bytes::from_static(&[0x60, 0x01, 0x00]),
320             expected_err: Some(Error::ErrShortPacket),
321             with_donl: true,
322             ..Default::default()
323         },
324         // Small payload
325         TestType {
326             raw: Bytes::from_static(&[0x60, 0x01, 0x00, 0x1]),
327             expected_err: Some(Error::ErrShortPacket),
328             with_donl: true,
329             ..Default::default()
330         },
331         // Small payload
332         TestType {
333             raw: Bytes::from_static(&[0x60, 0x01, 0x00, 0x01, 0x02]),
334             expected_err: Some(Error::ErrShortPacket),
335             with_donl: true,
336             ..Default::default()
337         },
338         // Single Aggregation Unit
339         TestType {
340             raw: Bytes::from_static(&[0x60, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00]),
341             expected_err: Some(Error::ErrShortPacket),
342             with_donl: true,
343             ..Default::default()
344         },
345         // Incomplete second Aggregation Unit
346         TestType {
347             raw: Bytes::from_static(&[
348                 0x60, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, // DONL
349                 0x00,
350             ]),
351             expected_err: Some(Error::ErrShortPacket),
352             with_donl: true,
353             ..Default::default()
354         },
355         // Incomplete second Aggregation Unit
356         TestType {
357             raw: Bytes::from_static(&[
358                 0x60, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00,
359                 // DONL, NAL Unit size (2 bytes)
360                 0x00, 0x55, 0x55,
361             ]),
362             expected_err: Some(Error::ErrShortPacket),
363             with_donl: true,
364             ..Default::default()
365         },
366         // Valid Second Aggregation Unit
367         TestType {
368             raw: Bytes::from_static(&[
369                 0x60, 0x01, 0xcc, 0xdd, 0x00, 0x02, 0xff, 0xee,
370                 // DONL, NAL Unit size (2 bytes), Payload
371                 0x77, 0x00, 0x01, 0xaa,
372             ]),
373             with_donl: true,
374             expected_packet: Some(H265AggregationPacket {
375                 first_unit: Some(H265AggregationUnitFirst {
376                     donl: Some(0xccdd),
377                     nal_unit_size: 2,
378                     nal_unit: Bytes::from_static(&[0xff, 0xee]),
379                 }),
380                 other_units: vec![H265AggregationUnit {
381                     dond: Some(0x77),
382                     nal_unit_size: 1,
383                     nal_unit: Bytes::from_static(&[0xaa]),
384                 }],
385                 might_need_donl: false,
386             }),
387             ..Default::default()
388         },
389     ];
390 
391     for cur in tests {
392         let mut parsed = H265AggregationPacket::default();
393         if cur.with_donl {
394             parsed.with_donl(cur.with_donl);
395         }
396 
397         let result = parsed.depacketize(&cur.raw);
398 
399         if cur.expected_err.is_some() && result.is_ok() {
400             panic!("should error");
401         } else if cur.expected_err.is_none() && result.is_err() {
402             panic!("should not error");
403         }
404 
405         if let Some(expected_packet) = cur.expected_packet {
406             if let (Some(first_unit), Some(parsed_first_unit)) =
407                 (expected_packet.first_unit(), parsed.first_unit())
408             {
409                 assert_eq!(
410                     parsed_first_unit.nal_unit_size, first_unit.nal_unit_size,
411                     "invalid first unit NALUSize"
412                 );
413                 assert_eq!(
414                     parsed_first_unit.donl(),
415                     first_unit.donl(),
416                     "invalid first unit DONL"
417                 );
418                 assert_eq!(
419                     parsed_first_unit.nal_unit(),
420                     first_unit.nal_unit(),
421                     "invalid first unit NalUnit"
422                 );
423             }
424 
425             assert_eq!(
426                 parsed.other_units().len(),
427                 expected_packet.other_units().len(),
428                 "number of other units mismatch"
429             );
430 
431             for ndx in 0..expected_packet.other_units().len() {
432                 assert_eq!(
433                     parsed.other_units()[ndx].nalu_size(),
434                     expected_packet.other_units()[ndx].nalu_size(),
435                     "invalid unit NALUSize"
436                 );
437 
438                 assert_eq!(
439                     parsed.other_units()[ndx].dond(),
440                     expected_packet.other_units()[ndx].dond(),
441                     "invalid unit DOND"
442                 );
443 
444                 assert_eq!(
445                     parsed.other_units()[ndx].nal_unit(),
446                     expected_packet.other_units()[ndx].nal_unit(),
447                     "invalid first unit NalUnit"
448                 );
449             }
450 
451             assert_eq!(
452                 parsed.other_units(),
453                 expected_packet.other_units(),
454                 "invalid payload"
455             );
456         }
457     }
458 
459     Ok(())
460 }
461 
462 #[test]
test_h265_fragmentation_unit_packet() -> Result<()>463 fn test_h265_fragmentation_unit_packet() -> Result<()> {
464     #[derive(Default)]
465     struct TestType {
466         raw: Bytes,
467         with_donl: bool,
468         expected_fu: Option<H265FragmentationUnitPacket>,
469         expected_err: Option<Error>,
470     }
471     let tests = vec![
472         TestType {
473             raw: Bytes::from_static(&[]),
474             expected_err: Some(Error::ErrShortPacket),
475             ..Default::default()
476         },
477         TestType {
478             raw: Bytes::from_static(&[0x62]),
479             expected_err: Some(Error::ErrShortPacket),
480             ..Default::default()
481         },
482         TestType {
483             raw: Bytes::from_static(&[0x62, 0x01]),
484             expected_err: Some(Error::ErrShortPacket),
485             ..Default::default()
486         },
487         TestType {
488             raw: Bytes::from_static(&[0x62, 0x01, 0x93]),
489             expected_err: Some(Error::ErrShortPacket),
490             ..Default::default()
491         },
492         // FBit enabled in H265NALUHeader
493         TestType {
494             raw: Bytes::from_static(&[0x80, 0x01, 0x93, 0xaf]),
495             expected_err: Some(Error::ErrH265CorruptedPacket),
496             ..Default::default()
497         },
498         // Type not '49' in H265NALUHeader
499         TestType {
500             raw: Bytes::from_static(&[0x40, 0x01, 0x93, 0xaf]),
501             expected_err: Some(Error::ErrInvalidH265PacketType),
502             ..Default::default()
503         },
504         TestType {
505             raw: Bytes::from_static(&[0x62, 0x01, 0x93, 0xaf]),
506             expected_fu: Some(H265FragmentationUnitPacket {
507                 payload_header: H265NALUHeader::new(0x62, 0x01),
508                 fu_header: H265FragmentationUnitHeader(0x93),
509                 donl: None,
510                 payload: Bytes::from_static(&[0xaf]),
511                 might_need_donl: false,
512             }),
513             ..Default::default()
514         },
515         TestType {
516             raw: Bytes::from_static(&[0x62, 0x01, 0x93, 0xcc]),
517             with_donl: true,
518             expected_err: Some(Error::ErrShortPacket),
519             ..Default::default()
520         },
521         TestType {
522             raw: Bytes::from_static(&[0x62, 0x01, 0x93, 0xcc, 0xdd, 0xaf, 0x0d, 0x5a]),
523             with_donl: true,
524             expected_fu: Some(H265FragmentationUnitPacket {
525                 payload_header: H265NALUHeader::new(0x62, 0x01),
526                 fu_header: H265FragmentationUnitHeader(0x93),
527                 donl: Some((0xcc << 8) | 0xdd),
528                 payload: Bytes::from_static(&[0xaf, 0x0d, 0x5a]),
529                 might_need_donl: false,
530             }),
531             ..Default::default()
532         },
533     ];
534 
535     for cur in tests {
536         let mut parsed = H265FragmentationUnitPacket::default();
537         if cur.with_donl {
538             parsed.with_donl(cur.with_donl);
539         }
540 
541         let result = parsed.depacketize(&cur.raw);
542 
543         if cur.expected_err.is_some() && result.is_ok() {
544             panic!("should error");
545         } else if cur.expected_err.is_none() && result.is_err() {
546             panic!("should not error");
547         }
548 
549         if let Some(expected_fu) = &cur.expected_fu {
550             assert_eq!(
551                 parsed.payload_header(),
552                 expected_fu.payload_header(),
553                 "invalid payload header"
554             );
555             assert_eq!(
556                 parsed.fu_header(),
557                 expected_fu.fu_header(),
558                 "invalid FU header"
559             );
560             assert_eq!(parsed.donl(), expected_fu.donl(), "invalid DONL");
561             assert_eq!(parsed.payload(), expected_fu.payload(), "invalid Payload");
562         }
563     }
564 
565     Ok(())
566 }
567 
568 #[test]
test_h265_temporal_scalability_control_information() -> Result<()>569 fn test_h265_temporal_scalability_control_information() -> Result<()> {
570     #[derive(Default)]
571     struct TestType {
572         value: H265TSCI,
573         expected_tl0picidx: u8,
574         expected_irap_pic_id: u8,
575         expected_s: bool,
576         expected_e: bool,
577         expected_res: u8,
578     }
579 
580     let tests = vec![
581         TestType {
582             value: H265TSCI(((0xCA) << 24) | ((0xFE) << 16)),
583             expected_tl0picidx: 0xCA,
584             expected_irap_pic_id: 0xFE,
585             ..Default::default()
586         },
587         TestType {
588             value: H265TSCI((1) << 15),
589             expected_s: true,
590             ..Default::default()
591         },
592         TestType {
593             value: H265TSCI((1) << 14),
594             expected_e: true,
595             ..Default::default()
596         },
597         TestType {
598             value: H265TSCI((0x0A) << 8),
599             expected_res: 0x0A,
600             ..Default::default()
601         },
602         // Sets RES, and force sets S and E to 0.
603         TestType {
604             value: H265TSCI(((0xAA) << 8) & (u32::MAX ^ ((1) << 15)) & (u32::MAX ^ ((1) << 14))),
605             expected_res: 0xAA & 0b00111111,
606             ..Default::default()
607         },
608     ];
609 
610     for cur in tests {
611         assert_eq!(
612             cur.value.tl0picidx(),
613             cur.expected_tl0picidx,
614             "invalid TL0PICIDX"
615         );
616         assert_eq!(
617             cur.value.irap_pic_id(),
618             cur.expected_irap_pic_id,
619             "invalid IrapPicID"
620         );
621         assert_eq!(cur.value.s(), cur.expected_s, "invalid S");
622         assert_eq!(cur.value.e(), cur.expected_e, "invalid E");
623         assert_eq!(cur.value.res(), cur.expected_res, "invalid RES");
624     }
625 
626     Ok(())
627 }
628 
629 #[test]
test_h265_paci_packet() -> Result<()>630 fn test_h265_paci_packet() -> Result<()> {
631     #[derive(Default)]
632     struct TestType {
633         raw: Bytes,
634         expected_fu: Option<H265PACIPacket>,
635         expected_err: Option<Error>,
636     }
637 
638     let tests = vec![
639         TestType {
640             raw: Bytes::from_static(&[]),
641             expected_err: Some(Error::ErrShortPacket),
642             ..Default::default()
643         },
644         TestType {
645             raw: Bytes::from_static(&[0x62, 0x01, 0x93]),
646             expected_err: Some(Error::ErrShortPacket),
647             ..Default::default()
648         },
649         // FBit enabled in H265NALUHeader
650         TestType {
651             raw: Bytes::from_static(&[0x80, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]),
652             expected_err: Some(Error::ErrH265CorruptedPacket),
653             ..Default::default()
654         },
655         // Type not '50' in H265NALUHeader
656         TestType {
657             raw: Bytes::from_static(&[0x40, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]),
658             expected_err: Some(Error::ErrInvalidH265PacketType),
659             ..Default::default()
660         },
661         // Invalid header extension size
662         TestType {
663             raw: Bytes::from_static(&[0x64, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]),
664             expected_err: Some(Error::ErrInvalidH265PacketType),
665             ..Default::default()
666         },
667         // No Header Extension
668         TestType {
669             raw: Bytes::from_static(&[0x64, 0x01, 0x64, 0x00, 0xab, 0xcd, 0xef]),
670             expected_fu: Some(H265PACIPacket {
671                 payload_header: H265NALUHeader::new(0x64, 0x01),
672                 paci_header_fields: ((0x64) << 8),
673                 phes: Bytes::from_static(&[]),
674                 payload: Bytes::from_static(&[0xab, 0xcd, 0xef]),
675             }),
676             ..Default::default()
677         },
678         // Header Extension 1 byte
679         TestType {
680             raw: Bytes::from_static(&[0x64, 0x01, 0x64, 0x10, 0xff, 0xab, 0xcd, 0xef]),
681             expected_fu: Some(H265PACIPacket {
682                 payload_header: H265NALUHeader::new(0x64, 0x01),
683                 paci_header_fields: ((0x64) << 8) | (0x10),
684                 phes: Bytes::from_static(&[0xff]),
685                 payload: Bytes::from_static(&[0xab, 0xcd, 0xef]),
686             }),
687             ..Default::default()
688         },
689         // Header Extension TSCI
690         TestType {
691             raw: Bytes::from_static(&[
692                 0x64, 0x01, 0x64, 0b00111000, 0xaa, 0xbb, 0x80, 0xab, 0xcd, 0xef,
693             ]),
694             expected_fu: Some(H265PACIPacket {
695                 payload_header: H265NALUHeader::new(0x64, 0x01),
696                 paci_header_fields: ((0x64) << 8) | (0b00111000),
697                 phes: Bytes::from_static(&[0xaa, 0xbb, 0x80]),
698                 payload: Bytes::from_static(&[0xab, 0xcd, 0xef]),
699             }),
700             ..Default::default()
701         },
702     ];
703 
704     for cur in tests {
705         let mut parsed = H265PACIPacket::default();
706 
707         let result = parsed.depacketize(&cur.raw);
708 
709         if cur.expected_err.is_some() && result.is_ok() {
710             panic!("should error");
711         } else if cur.expected_err.is_none() && result.is_err() {
712             panic!("should not error");
713         }
714 
715         if let Some(expected_fu) = &cur.expected_fu {
716             assert_eq!(
717                 parsed.payload_header(),
718                 expected_fu.payload_header(),
719                 "invalid PayloadHeader"
720             );
721             assert_eq!(parsed.a(), expected_fu.a(), "invalid A");
722             assert_eq!(parsed.ctype(), expected_fu.ctype(), "invalid CType");
723             assert_eq!(parsed.phs_size(), expected_fu.phs_size(), "invalid PHSsize");
724             assert_eq!(parsed.f0(), expected_fu.f0(), "invalid F0");
725             assert_eq!(parsed.f1(), expected_fu.f1(), "invalid F1");
726             assert_eq!(parsed.f2(), expected_fu.f2(), "invalid F2");
727             assert_eq!(parsed.y(), expected_fu.y(), "invalid Y");
728             assert_eq!(parsed.phes(), expected_fu.phes(), "invalid PHES");
729             assert_eq!(parsed.payload(), expected_fu.payload(), "invalid Payload");
730             assert_eq!(parsed.tsci(), expected_fu.tsci(), "invalid TSCI");
731         }
732     }
733 
734     Ok(())
735 }
736 
737 #[test]
test_h265_packet() -> Result<()>738 fn test_h265_packet() -> Result<()> {
739     #[derive(Default)]
740     struct TestType {
741         raw: Bytes,
742         with_donl: bool,
743         expected_packet_type: Option<H265Payload>,
744         expected_err: Option<Error>,
745     }
746     let tests = vec![
747         TestType {
748             raw: Bytes::from_static(&[]),
749             expected_err: Some(Error::ErrShortPacket),
750             ..Default::default()
751         },
752         TestType {
753             raw: Bytes::from_static(&[0x62, 0x01, 0x93]),
754             expected_err: Some(Error::ErrShortPacket),
755             ..Default::default()
756         },
757         TestType {
758             raw: Bytes::from_static(&[0x64, 0x01, 0x93, 0xaf]),
759             expected_err: Some(Error::ErrShortPacket),
760             ..Default::default()
761         },
762         TestType {
763             raw: Bytes::from_static(&[0x01, 0x01]),
764             with_donl: true,
765             expected_err: Some(Error::ErrShortPacket),
766             ..Default::default()
767         },
768         // FBit enabled in H265NALUHeader
769         TestType {
770             raw: Bytes::from_static(&[0x80, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]),
771             expected_err: Some(Error::ErrH265CorruptedPacket),
772             ..Default::default()
773         },
774         // Valid H265SingleNALUnitPacket
775         TestType {
776             raw: Bytes::from_static(&[0x01, 0x01, 0xab, 0xcd, 0xef]),
777             expected_packet_type: Some(H265Payload::H265SingleNALUnitPacket(
778                 H265SingleNALUnitPacket::default(),
779             )),
780             ..Default::default()
781         },
782         // Invalid H265SingleNALUnitPacket
783         TestType {
784             raw: Bytes::from_static(&[0x01, 0x01, 0x93, 0xaf]),
785             expected_err: Some(Error::ErrShortPacket),
786             with_donl: true,
787             ..Default::default()
788         },
789         // Valid H265PACIPacket
790         TestType {
791             raw: Bytes::from_static(&[
792                 0x64, 0x01, 0x64, 0b00111000, 0xaa, 0xbb, 0x80, 0xab, 0xcd, 0xef,
793             ]),
794             expected_packet_type: Some(H265Payload::H265PACIPacket(H265PACIPacket::default())),
795             ..Default::default()
796         },
797         // Valid H265FragmentationUnitPacket
798         TestType {
799             raw: Bytes::from_static(&[0x62, 0x01, 0x93, 0xcc, 0xdd, 0xaf, 0x0d, 0x5a]),
800             expected_packet_type: Some(H265Payload::H265FragmentationUnitPacket(
801                 H265FragmentationUnitPacket::default(),
802             )),
803             with_donl: true,
804             ..Default::default()
805         },
806         // Valid H265AggregationPacket
807         TestType {
808             raw: Bytes::from_static(&[
809                 0x60, 0x01, 0xcc, 0xdd, 0x00, 0x02, 0xff, 0xee, 0x77, 0x00, 0x01, 0xaa,
810             ]),
811             expected_packet_type: Some(H265Payload::H265AggregationPacket(
812                 H265AggregationPacket::default(),
813             )),
814             with_donl: true,
815             ..Default::default()
816         },
817         // Invalid H265AggregationPacket
818         TestType {
819             raw: Bytes::from_static(&[0x60, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00]),
820             expected_err: Some(Error::ErrShortPacket),
821             with_donl: true,
822             ..Default::default()
823         },
824     ];
825 
826     for cur in tests {
827         let mut pck = H265Packet::default();
828         if cur.with_donl {
829             pck.with_donl(true);
830         }
831 
832         let result = pck.depacketize(&cur.raw);
833 
834         if cur.expected_err.is_some() && result.is_ok() {
835             panic!("should error");
836         } else if cur.expected_err.is_none() && result.is_err() {
837             panic!("should not error");
838         }
839 
840         if cur.expected_err.is_some() {
841             continue;
842         }
843 
844         if let Some(expected_packet_type) = &cur.expected_packet_type {
845             //TODO: assert_eq!(pck.packet(), expected_packet_type, "invalid packet type");
846             let pck_packet = pck.payload();
847             match (pck_packet, expected_packet_type) {
848                 (
849                     &H265Payload::H265SingleNALUnitPacket(_),
850                     &H265Payload::H265SingleNALUnitPacket(_),
851                 ) => {}
852                 (
853                     &H265Payload::H265FragmentationUnitPacket(_),
854                     &H265Payload::H265FragmentationUnitPacket(_),
855                 ) => {}
856                 (
857                     &H265Payload::H265AggregationPacket(_),
858                     &H265Payload::H265AggregationPacket(_),
859                 ) => {}
860                 (&H265Payload::H265PACIPacket(_), &H265Payload::H265PACIPacket(_)) => {}
861                 _ => panic!(),
862             };
863         }
864     }
865 
866     Ok(())
867 }
868 
869 #[test]
test_h265_packet_real() -> Result<()>870 fn test_h265_packet_real() -> Result<()> {
871     // Tests decoding of real H265 payloads extracted from a Wireshark dump.
872     let tests = vec![
873         b"\x40\x01\x0c\x01\xff\xff\x01\x60\x00\x00\x03\x00\xb0\x00\x00\x03\x00\x00\x03\x00\x7b\xac\x09".to_vec(),
874         b"\x42\x01\x01\x01\x60\x00\x00\x03\x00\xb0\x00\x00\x03\x00\x00\x03\x00\x7b\xa0\x03\xc0\x80\x10\xe5\x8d\xae\x49\x32\xf4\xdc\x04\x04\x04\x02".to_vec(),
875         b"\x44\x01\xc0\xf2\xf0\x3c\x90".to_vec(),
876         b"\x4e\x01\xe5\x04\x61\x0c\x00\x00\x80".to_vec(),
877         b"\x62\x01\x93\xaf\x0d\x5a\xfe\x67\x77\x29\xc0\x74\xf3\x57\x4c\x16\x94\xaa\x7c\x2a\x64\x5f\xe9\xa5\xb7\x2a\xa3\x95\x9d\x94\xa7\xb4\xd3\xc4\x4a\xb1\xb7\x69\xca\xbe\x75\xc5\x64\xa8\x97\x4b\x8a\xbf\x7e\xf0\x0f\xc3\x22\x60\x67\xab\xae\x96\xd6\x99\xca\x7a\x8d\x35\x93\x1a\x67\x60\xe7\xbe\x7e\x13\x95\x3c\xe0\x11\xc1\xc1\xa7\x48\xef\xf7\x7b\xb0\xeb\x35\x49\x81\x4e\x4e\x54\xf7\x31\x6a\x38\xa1\xa7\x0c\xd6\xbe\x3b\x25\xba\x08\x19\x0b\x49\xfd\x90\xbb\x73\x7a\x45\x8c\xb9\x73\x43\x04\xc5\x5f\xda\x0f\xd5\x70\x4c\x11\xee\x72\xb8\x6a\xb4\x95\x62\x64\xb6\x23\x14\x7e\xdb\x0e\xa5\x0f\x86\x31\xe4\xd1\x64\x56\x43\xf6\xb7\xe7\x1b\x93\x4a\xeb\xd0\xa6\xe3\x1f\xce\xda\x15\x67\x05\xb6\x77\x36\x8b\x27\x5b\xc6\xf2\x95\xb8\x2b\xcc\x9b\x0a\x03\x05\xbe\xc3\xd3\x85\xf5\x69\xb6\x19\x1f\x63\x2d\x8b\x65\x9e\xc3\x9d\xd2\x44\xb3\x7c\x86\x3b\xea\xa8\x5d\x02\xe5\x40\x03\x20\x76\x48\xff\xf6\x2b\x0d\x18\xd6\x4d\x49\x70\x1a\x5e\xb2\x89\xca\xec\x71\x41\x79\x4e\x94\x17\x0c\x57\x51\x55\x14\x61\x40\x46\x4b\x3e\x17\xb2\xc8\xbd\x1c\x06\x13\x91\x72\xf8\xc8\xfc\x6f\xb0\x30\x9a\xec\x3b\xa6\xc9\x33\x0b\xa5\xe5\xf4\x65\x7a\x29\x8b\x76\x62\x81\x12\xaf\x20\x4c\xd9\x21\x23\x9e\xeb\xc9\x0e\x5b\x29\x35\x7f\x41\xcd\xce\xa1\xc4\xbe\x01\x30\xb9\x11\xc3\xb1\xe4\xce\x45\xd2\x5c\xb3\x1e\x69\x78\xba\xb1\x72\xe4\x88\x54\xd8\x5d\xd0\xa8\x3a\x74\xad\xe5\xc7\xc1\x59\x7c\x78\x15\x26\x37\x3d\x50\xae\xb3\xa4\x5b\x6c\x7d\x65\x66\x85\x4d\x16\x9a\x67\x74\xad\x55\x32\x3a\x84\x85\x0b\x6a\xeb\x24\x97\xb4\x20\x4d\xca\x41\x61\x7a\xd1\x7b\x60\xdb\x7f\xd5\x61\x22\xcf\xd1\x7e\x4c\xf3\x85\xfd\x13\x63\xe4\x9d\xed\xac\x13\x0a\xa0\x92\xb7\x34\xde\x65\x0f\xd9\x0f\x9b\xac\xe2\x47\xe8\x5c\xb3\x11\x8e\xc6\x08\x19\xd0\xb0\x85\x52\xc8\x5c\x1b\x08\x0a\xce\xc9\x6b\xa7\xef\x95\x2f\xd0\xb8\x63\xe5\x4c\xd4\xed\x6e\x87\xe9\xd4\x0a\xe6\x11\x44\x63\x00\x94\x18\xe9\x28\xba\xcf\x92\x43\x06\x59\xdd\x37\x4f\xd3\xef\x9d\x31\x5e\x9b\x48\xf9\x1f\x3e\x7b\x95\x3a\xbd\x1f\x71\x55\x0c\x06\xf9\x86\xf8\x3d\x39\x16\x50\xb3\x21\x11\x19\x6f\x70\xa9\x48\xe8\xbb\x0a\x11\x23\xf8\xab\xfe\x44\xe0\xbb\xe8\x64\xfa\x85\xe4\x02\x55\x88\x41\xc6\x30\x7f\x10\xad\x75\x02\x4b\xef\xe1\x0b\x06\x3c\x10\x49\x83\xf9\xd1\x3e\x3e\x67\x86\x4c\xf8\x9d\xde\x5a\xc4\xc8\xcf\xb6\xf4\xb0\xd3\x34\x58\xd4\x7b\x4d\xd3\x37\x63\xb2\x48\x8a\x7e\x20\x00\xde\xb4\x42\x8f\xda\xe9\x43\x9e\x0c\x16\xce\x79\xac\x2c\x70\xc1\x89\x05\x36\x62\x6e\xd9\xbc\xfb\x63\xc6\x79\x89\x3c\x90\x89\x2b\xd1\x8c\xe0\xc2\x54\xc7\xd6\xb4\xe8\x9e\x96\x55\x6e\x7b\xd5\x7f\xac\xd4\xa7\x1c\xa0\xdf\x01\x30\xad\xc0\x9f\x69\x06\x10\x43\x7f\xf4\x5d\x62\xa3\xea\x73\xf2\x14\x79\x19\x13\xea\x59\x14\x79\xa8\xe7\xce\xce\x44\x25\x13\x41\x18\x57\xdd\xce\xe4\xbe\xcc\x20\x80\x29\x71\x73\xa7\x7c\x86\x39\x76\xf4\xa7\x1c\x63\x24\x21\x93\x1e\xb5\x9a\x5c\x8a\x9e\xda\x8b\x9d\x88\x97\xfc\x98\x7d\x26\x74\x04\x1f\xa8\x10\x4f\x45\xcd\x46\xe8\x28\xe4\x8e\x59\x67\x63\x4a\xcf\x1e\xed\xdd\xbb\x79\x2f\x8d\x94\xab\xfc\xdb\xc5\x79\x1a\x4d\xcd\x53\x41\xdf\xd1\x7a\x8f\x46\x3e\x1f\x79\x88\xe3\xee\x9f\xc4\xc1\xe6\x2e\x89\x4d\x28\xc9\xca\x28\xc2\x0a\xc5\xc7\xf1\x22\xcd\xb3\x36\xfa\xe3\x7e\xa6\xcd\x95\x55\x5e\x0e\x1a\x75\x7f\x65\x27\xd3\x37\x4f\x23\xc5\xab\x49\x68\x4e\x02\xb5\xbf\xd7\x95\xc0\x78\x67\xbc\x1a\xe9\xae\x6f\x44\x58\x8a\xc2\xce\x42\x98\x4e\x77\xc7\x2a\xa0\xa7\x7d\xe4\x3b\xd1\x20\x82\x1a\xd3\xe2\xc7\x76\x5d\x06\x46\xb5\x24\xd7\xfb\x57\x63\x2b\x19\x51\x48\x65\x6d\xfb\xe0\x98\xd1\x14\x0e\x17\x64\x29\x34\x6f\x6e\x66\x9e\x8d\xc9\x89\x49\x69\xee\x74\xf3\x35\xe6\x8b\x67\x56\x95\x7f\x1b\xe9\xed\x8c\x0f\xe2\x19\x59\xbf\x03\x35\x55\x3c\x04\xbc\x40\x52\x90\x10\x08\xad\xa7\x65\xe0\x31\xcb\xcf\x3d\xd4\x62\x68\x01\x0d\xed\xf5\x28\x64\x2d\xaa\x7c\x99\x15\x8d\x70\x32\x53\xb8\x9d\x0a\x3c\xbf\x91\x02\x04\xd0\xee\x87\xce\x04\xcc\x3e\xa8\x20\xfd\x97\xdf\xbf\x4a\xbc\xfc\xc9\x7c\x77\x21\xcc\x23\x6f\x59\x38\xd8\xd9\xa0\x0e\xb1\x23\x4e\x04\x3f\x14\x9e\xcc\x05\x54\xab\x20\x69\xed\xa4\xd5\x1d\xb4\x1b\x52\xed\x6a\xea\xeb\x7f\xd1\xbc\xfd\x75\x20\xa0\x1c\x59\x8c\x5a\xa1\x2a\x70\x64\x11\xb1\x7b\xc1\x24\x80\x28\x51\x4c\x94\xa1\x95\x64\x72\xe8\x90\x67\x38\x74\x2b\xab\x38\x46\x12\x71\xce\x19\x98\x98\xf7\x89\xd4\xfe\x2f\x2a\xc5\x61\x20\xd0\xa4\x1a\x51\x3c\x82\xc8\x18\x31\x7a\x10\xe8\x1c\xc6\x95\x5a\xa0\x82\x88\xce\x8f\x4b\x47\x85\x7e\x89\x95\x95\x52\x1e\xac\xce\x45\x57\x61\x38\x97\x2b\x62\xa5\x14\x6f\xc3\xaa\x6c\x35\x83\xc9\xa3\x1e\x30\x89\xf4\xb1\xea\x4f\x39\xde\xde\xc7\x46\x5c\x0e\x85\x41\xec\x6a\xa4\xcb\xee\x70\x9c\x57\xd9\xf4\xa1\xc3\x9c\x2a\x0a\xf0\x5d\x58\xb0\xae\xd4\xdc\xc5\x6a\xa8\x34\xfa\x23\xef\xef\x08\x39\xc3\x3d\xea\x11\x6e\x6a\xe0\x1e\xd0\x52\xa8\xc3\x6e\xc9\x1c\xfc\xd0\x0c\x4c\xea\x0d\x82\xcb\xdd\x29\x1a\xc4\x4f\x6e\xa3\x4d\xcb\x7a\x38\x77\xe5\x15\x6e\xad\xfa\x9d\x2f\x02\xb6\x39\x84\x3a\x60\x8f\x71\x9f\x92\xe5\x24\x4f\xbd\x18\x49\xd5\xef\xbf\x70\xfb\xd1\x4c\x2e\xfc\x2f\x36\xf3\x00\x31\x2e\x90\x18\xcc\xf4\x71\xb9\xe4\xf9\xbe\xcb\x5e\xff\xf3\xe7\xf8\xca\x03\x60\x66\xb3\xc9\x5a\xf9\x74\x09\x02\x57\xb6\x90\x94\xfc\x41\x35\xdc\x35\x3f\x32\x7a\xa6\xa5\xcd\x8a\x8f\xc8\x3d\xc8\x81\xc3\xec\x37\x74\x86\x61\x41\x0d\xc5\xe2\xc8\x0c\x84\x2b\x3b\x71\x58\xde\x1b\xe3\x20\x65\x2e\x76\xf4\x98\xd8\xaa\x78\xe6\xeb\xb8\x85\x0d\xa0\xd0\xf5\x57\x64\x01\x58\x55\x82\xd5\x0f\x2d\x9c\x3e\x2a\xa0\x7e\xaf\x42\xf3\x37\xd1\xb3\xaf\xda\x5b\xa9\xda\xe3\x89\x5d\xf1\xca\xa5\x12\x3d\xe7\x91\x95\x53\x21\x72\xca\x7f\xf6\x79\x59\x21\xcf\x30\x18\xfb\x78\x55\x40\x59\xc3\xf9\xf1\xdd\x58\x44\x5e\x83\x11\x5c\x2d\x1d\x91\xf6\x01\x3d\x3f\xd4\x33\x81\x66\x6c\x40\x7a\x9d\x70\x10\x58\xe6\x53\xad\x85\x11\x99\x3e\x4b\xbc\x31\xc6\x78\x9d\x79\xc5\xde\x9f\x2e\x43\xfa\x76\x84\x2f\xfd\x28\x75\x12\x48\x25\xfd\x15\x8c\x29\x6a\x91\xa4\x63\xc0\xa2\x8c\x41\x3c\xf1\xb0\xf8\xdf\x66\xeb\xbd\x14\x88\xa9\x81\xa7\x35\xc4\x41\x40\x6c\x10\x3f\x09\xbd\xb5\xd3\x7a\xee\x4b\xd5\x86\xff\x36\x03\x6b\x78\xde".to_vec(),
878         b"\x62\x01\x53\x8a\xe9\x25\xe1\x06\x09\x8e\xba\x12\x74\x87\x09\x9a\x95\xe4\x86\x62\x2b\x4b\xf9\xa6\x2e\x7b\x35\x43\xf7\x39\x99\x0f\x3b\x6f\xfd\x1a\x6e\x23\x54\x70\xb5\x1d\x10\x1c\x63\x40\x96\x99\x41\xb6\x96\x0b\x70\x98\xec\x17\xb0\xaa\xdc\x4a\xab\xe8\x3b\xb7\x6b\x00\x1c\x5b\xc3\xe0\xa2\x8b\x7c\x17\xc8\x92\xc9\xb0\x92\xb6\x70\x84\x95\x30".to_vec(),
879         b"\x4e\x01\xe5\x04\x35\xac\x00\x00\x80".to_vec(),
880         b"\x62\x01\x41\xb0\x75\x5c\x27\x46\xef\x8a\xe7\x1d\x50\x38\xb2\x13\x33\xe0\x79\x35\x1b\xc2\xb5\x79\x73\xe7\xc2\x6f\xb9\x1a\x8c\x21\x0e\xa9\x54\x17\x6c\x41\xab\xc8\x16\x57\xec\x5e\xeb\x89\x3b\xa9\x90\x8c\xff\x4d\x46\x8b\xf0\xd9\xc0\xd0\x51\xcf\x8b\x88\xf1\x5f\x1e\x9e\xc1\xb9\x1f\xe3\x06\x45\x35\x8a\x47\xe8\x9a\xf2\x4f\x19\x4c\xf8\xce\x68\x1b\x63\x34\x11\x75\xea\xe5\xb1\x0f\x38\xcc\x05\x09\x8b\x3e\x2b\x88\x84\x9d\xc5\x03\xc3\xc0\x90\x32\xe2\x45\x69\xb1\xe5\xf7\x68\x6b\x16\x90\xa0\x40\xe6\x18\x74\xd8\x68\xf3\x34\x38\x99\xf2\x6c\xb7\x1a\x35\x21\xca\x52\x56\x4c\x7f\xb2\xa3\xd5\xb8\x40\x50\x48\x3e\xdc\xdf\x0b\xf5\x54\x5a\x15\x1a\xe2\xc3\xb4\x94\xda\x3f\xb5\x34\xa2\xca\xbc\x2f\xe0\xa4\xe5\x69\xf4\xbf\x62\x4d\x15\x21\x1b\x11\xfc\x39\xaa\x86\x74\x96\x63\xfd\x07\x53\x26\xf6\x34\x72\xeb\x14\x37\x98\x0d\xf4\x68\x91\x2c\x6b\x46\x83\x88\x82\x04\x8b\x9f\xb8\x32\x73\x75\x8b\xf9\xac\x71\x42\xd1\x2d\xb4\x28\x28\xf5\x78\xe0\x32\xf3\xe1\xfc\x43\x6b\xf9\x92\xf7\x48\xfe\x7f\xc0\x17\xbd\xfd\xba\x2f\x58\x6f\xee\x84\x03\x18\xce\xb0\x9d\x8d\xeb\x22\xf1\xfc\xb1\xcf\xff\x2f\xb2\x9f\x6c\xe5\xb4\x69\xdc\xdd\x20\x93\x00\x30\xad\x56\x04\x66\x7e\xa3\x3c\x18\x4b\x43\x66\x00\x27\x1e\x1c\x09\x11\xd8\xf4\x8a\x9e\xc5\x6a\x94\xe5\xae\x0b\x8a\xbe\x84\xda\xe5\x44\x7f\x38\x1c\xe7\xbb\x03\x19\x66\xe1\x5d\x1d\xc1\xbd\x3d\xc6\xb7\xe3\xff\x7f\x8e\xff\x1e\xf6\x9e\x6f\x58\x27\x74\x65\xef\x02\x5d\xa4\xde\x27\x7f\x51\xe3\x4b\x9e\x3f\x79\x83\xbd\x1b\x8f\x0d\x77\xfb\xbc\xc5\x9f\x15\xa7\x4e\x05\x8a\x24\x97\x66\xb2\x7c\xf6\xe1\x84\x54\xdb\x39\x5e\xf6\x1b\x8f\x05\x73\x1d\xb6\x8e\xd7\x09\x9a\xc5\x92\x80".to_vec(),
881     ];
882 
883     for cur in tests {
884         let mut pck = H265Packet::default();
885         let _ = pck.depacketize(&Bytes::from(cur))?;
886     }
887 
888     Ok(())
889 }
890