1use bytes::{BufMut, Bytes, BytesMut};
2
3use super::h264::ANNEXB_NALUSTART_CODE;
4use crate::packetizer::{Depacketizer, Payloader};
5use shared::error::{Error, Result};
6
7#[cfg(test)]
8mod h265_test;
9
10pub static ANNEXB_3_NALUSTART_CODE: Bytes = Bytes::from_static(&[0x00, 0x00, 0x01]);
11pub static SING_PAYLOAD_HDR: Bytes = Bytes::from_static(&[0x1C, 0x01]);
12pub static AGGR_PAYLOAD_HDR: Bytes = Bytes::from_static(&[0x60, 0x01]);
13pub static FRAG_PAYLOAD_HDR: Bytes = Bytes::from_static(&[0x62, 0x01]);
14pub static FU_HDR_IDR_S: u8 = 0x93;
15pub static FU_HDR_IDR_M: u8 = 0x13;
16pub static FU_HDR_IDR_E: u8 = 0x53;
17pub static FU_HDR_P_S: u8 = 0x81;
18pub static FU_HDR_P_M: u8 = 0x01;
19pub static FU_HDR_P_E: u8 = 0x41;
20pub static FU_HDR_B_S: u8 = 0x80;
21pub static FU_HDR_B_M: u8 = 0x00;
22pub static FU_HDR_B_E: u8 = 0x40;
23pub const RTP_OUTBOUND_MTU: usize = 1200;
24pub const H265FRAGMENTATION_UNIT_HEADER_SIZE: usize = 1;
25pub const NAL_HEADER_SIZE: usize = 2;
26
27#[derive(PartialEq, Hash, Debug, Copy, Clone)]
28pub enum UnitType {
29 VPS = 32,
30 SPS = 33,
31 PPS = 34,
32 CRA = 21,
33 SEI = 39,
34 IDR = 19,
35 PFR = 1,
36 BFR = 0,
37 IGNORE = -1,
38}
39impl UnitType {
40 pub fn for_id(id: u8) -> Result<UnitType> {
41 if id > 64 {
42 Err(Error::ErrUnhandledNaluType)
43 } else {
44 let t = match id {
45 32 => UnitType::VPS,
46 33 => UnitType::SPS,
47 34 => UnitType::PPS,
48 21 => UnitType::CRA,
49 39 => UnitType::SEI,
50 19 => UnitType::IDR,
51 1 => UnitType::PFR,
52 0 => UnitType::BFR,
53 _ => UnitType::IGNORE, };
55 Ok(t)
56 }
57 }
58}
59
60#[derive(Default, Debug, Clone)]
61pub struct HevcPayloader {
62 vps_nalu: Option<Bytes>,
63 sps_nalu: Option<Bytes>,
64 pps_nalu: Option<Bytes>,
65}
66
67impl HevcPayloader {
68 pub fn parse(nalu: &Bytes) -> (Vec<usize>, usize) {
69 let finder = memchr::memmem::Finder::new(&ANNEXB_NALUSTART_CODE);
70 let nals = finder.find_iter(nalu).collect::<Vec<usize>>();
71 if nals.is_empty() {
72 let finder = memchr::memmem::Finder::new(&ANNEXB_3_NALUSTART_CODE);
73 return (finder.find_iter(nalu).collect::<Vec<usize>>(), 3);
74 }
75 (nals, 4)
76 }
77
78 fn emit(&mut self, nalu: &Bytes, mtu: usize, payloads: &mut Vec<Bytes>) {
79 if nalu.is_empty() {
80 return;
81 }
82 let payload_header = H265NALUHeader::new(nalu[0], nalu[1]);
83 let payload_nalu_type = payload_header.nalu_type();
84 let nalu_type = UnitType::for_id(payload_nalu_type).unwrap_or(UnitType::IGNORE);
85 if nalu_type == UnitType::IGNORE {
86 return;
87 } else if nalu_type == UnitType::VPS {
88 self.vps_nalu.replace(nalu.clone());
89 } else if nalu_type == UnitType::SPS {
90 self.sps_nalu.replace(nalu.clone());
91 } else if nalu_type == UnitType::PPS {
92 self.pps_nalu.replace(nalu.clone());
93 }
94 if let (Some(vps_nalu), Some(sps_nalu), Some(pps_nalu)) =
95 (&self.vps_nalu, &self.sps_nalu, &self.pps_nalu)
96 {
97 let vps_len = (vps_nalu.len() as u16).to_be_bytes();
99 let sps_len = (sps_nalu.len() as u16).to_be_bytes();
100 let pps_len = (pps_nalu.len() as u16).to_be_bytes();
101
102 let mut aggr_nalu = BytesMut::new();
104 aggr_nalu.extend_from_slice(&AGGR_PAYLOAD_HDR);
105 aggr_nalu.extend_from_slice(&vps_len);
106 aggr_nalu.extend_from_slice(vps_nalu);
107 aggr_nalu.extend_from_slice(&sps_len);
108 aggr_nalu.extend_from_slice(sps_nalu);
109 aggr_nalu.extend_from_slice(&pps_len);
110 aggr_nalu.extend_from_slice(pps_nalu);
111 if aggr_nalu.len() <= mtu {
112 payloads.push(Bytes::from(aggr_nalu));
113 self.vps_nalu.take();
114 self.sps_nalu.take();
115 self.pps_nalu.take();
116 return;
117 }
118 } else if nalu_type == UnitType::VPS
119 || nalu_type == UnitType::SPS
120 || nalu_type == UnitType::PPS
121 {
122 return;
123 }
124 if nalu.len() <= mtu {
131 payloads.push(nalu.clone());
132 return;
133 }
134 let max_fragment_size =
135 mtu as isize - NAL_HEADER_SIZE as isize - H265FRAGMENTATION_UNIT_HEADER_SIZE as isize;
136 let nalu_data = nalu;
137 let mut nalu_data_index = 2;
138 let nalu_data_length = nalu.len() as isize - nalu_data_index;
139 let mut nalu_data_remaining = nalu_data_length;
140 if std::cmp::min(max_fragment_size, nalu_data_remaining) <= 0 {
141 return;
142 }
143 while nalu_data_remaining > 0 {
144 let current_fragment_size = std::cmp::min(max_fragment_size, nalu_data_remaining);
145 let mut out = BytesMut::with_capacity(
147 H265FRAGMENTATION_UNIT_HEADER_SIZE + current_fragment_size as usize,
148 );
149 out.extend_from_slice(&FRAG_PAYLOAD_HDR);
150 let is_first = nalu_data_index == 2;
151 let is_last = !is_first && current_fragment_size < max_fragment_size;
152 if nalu_type == UnitType::IDR {
160 if is_first {
161 out.put_u8(FU_HDR_IDR_S);
162 } else if is_last {
163 out.put_u8(FU_HDR_IDR_E);
164 } else {
165 out.put_u8(FU_HDR_IDR_M);
166 }
167 } else if nalu_type == UnitType::PFR {
168 if is_first {
169 out.put_u8(FU_HDR_P_S);
170 } else if is_last {
171 out.put_u8(FU_HDR_P_E);
172 } else {
173 out.put_u8(FU_HDR_P_M);
174 }
175 } else if nalu_type == UnitType::BFR {
176 if is_first {
177 out.put_u8(FU_HDR_B_S);
178 } else if is_last {
179 out.put_u8(FU_HDR_B_E);
180 } else {
181 out.put_u8(FU_HDR_B_M);
182 }
183 }
184
185 out.extend_from_slice(
186 &nalu_data
187 [nalu_data_index as usize..(nalu_data_index + current_fragment_size) as usize],
188 );
189 payloads.push(out.freeze());
191
192 nalu_data_remaining -= current_fragment_size;
193 nalu_data_index += current_fragment_size;
194 }
195 }
196}
197
198impl Payloader for HevcPayloader {
199 fn payload(&mut self, mtu: usize, payload: &Bytes) -> Result<Vec<Bytes>> {
201 if payload.is_empty() || mtu == 0 {
202 return Ok(vec![]);
203 }
204
205 let mut payloads = vec![];
206
207 let (nal_idxs, offset) = HevcPayloader::parse(payload);
208 let nal_len = nal_idxs.len();
209 for (i, start) in nal_idxs.iter().enumerate() {
210 let end = if (i + 1) < nal_len {
211 nal_idxs[i + 1]
212 } else {
213 payload.len()
214 };
215 self.emit(&payload.slice((start + offset)..end), mtu, &mut payloads);
224 }
225
226 Ok(payloads)
227 }
228
229 fn clone_to(&self) -> Box<dyn Payloader> {
230 Box::new(self.clone())
231 }
232}
233
234const H265NALU_HEADER_SIZE: usize = 2;
238const H265NALU_AGGREGATION_PACKET_TYPE: u8 = 48;
240const H265NALU_FRAGMENTATION_UNIT_TYPE: u8 = 49;
242const H265NALU_PACI_PACKET_TYPE: u8 = 50;
244
245#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
261pub struct H265NALUHeader(pub u16);
262
263impl H265NALUHeader {
264 pub fn new(high_byte: u8, low_byte: u8) -> Self {
265 H265NALUHeader(((high_byte as u16) << 8) | low_byte as u16)
266 }
267
268 pub fn f(&self) -> bool {
270 (self.0 >> 15) != 0
271 }
272
273 pub fn nalu_type(&self) -> u8 {
275 const MASK: u16 = 0b01111110 << 8;
277 ((self.0 & MASK) >> (8 + 1)) as u8
278 }
279
280 pub fn is_type_vcl_unit(&self) -> bool {
282 const MSB_MASK: u8 = 0b00100000;
284 (self.nalu_type() & MSB_MASK) == 0
285 }
286
287 pub fn layer_id(&self) -> u8 {
289 const MASK: u16 = (0b00000001 << 8) | 0b11111000;
291 ((self.0 & MASK) >> 3) as u8
292 }
293
294 pub fn tid(&self) -> u8 {
296 const MASK: u16 = 0b00000111;
297 (self.0 & MASK) as u8
298 }
299
300 pub fn is_aggregation_packet(&self) -> bool {
302 self.nalu_type() == H265NALU_AGGREGATION_PACKET_TYPE
303 }
304
305 pub fn is_fragmentation_unit(&self) -> bool {
307 self.nalu_type() == H265NALU_FRAGMENTATION_UNIT_TYPE
308 }
309
310 pub fn is_paci_packet(&self) -> bool {
312 self.nalu_type() == H265NALU_PACI_PACKET_TYPE
313 }
314}
315
316#[derive(Default, Debug, Clone, PartialEq, Eq)]
338pub struct H265SingleNALUnitPacket {
339 payload_header: H265NALUHeader,
341 donl: Option<u16>,
343 payload: Bytes,
345
346 might_need_donl: bool,
347}
348
349impl H265SingleNALUnitPacket {
350 pub fn with_donl(&mut self, value: bool) {
353 self.might_need_donl = value;
354 }
355
356 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
358 if payload.len() <= H265NALU_HEADER_SIZE {
359 return Err(Error::ErrShortPacket);
360 }
361
362 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
363 if payload_header.f() {
364 return Err(Error::ErrH265CorruptedPacket);
365 }
366 if payload_header.is_fragmentation_unit()
367 || payload_header.is_paci_packet()
368 || payload_header.is_aggregation_packet()
369 {
370 return Err(Error::ErrInvalidH265PacketType);
371 }
372
373 let mut payload = payload.slice(2..);
374
375 if self.might_need_donl {
376 if payload.len() <= 2 {
378 return Err(Error::ErrShortPacket);
379 }
380
381 let donl = ((payload[0] as u16) << 8) | (payload[1] as u16);
382 self.donl = Some(donl);
383 payload = payload.slice(2..);
384 }
385
386 self.payload_header = payload_header;
387 self.payload = payload;
388
389 Ok(())
390 }
391
392 pub fn payload_header(&self) -> H265NALUHeader {
394 self.payload_header
395 }
396
397 pub fn donl(&self) -> Option<u16> {
399 self.donl
400 }
401
402 pub fn payload(&self) -> Bytes {
404 self.payload.clone()
405 }
406}
407
408#[derive(Default, Debug, Clone, PartialEq, Eq)]
431pub struct H265AggregationUnitFirst {
432 donl: Option<u16>,
433 nal_unit_size: u16,
434 nal_unit: Bytes,
435}
436
437impl H265AggregationUnitFirst {
438 pub fn donl(&self) -> Option<u16> {
442 self.donl
443 }
444
445 pub fn nalu_size(&self) -> u16 {
447 self.nal_unit_size
448 }
449
450 pub fn nal_unit(&self) -> Bytes {
452 self.nal_unit.clone()
453 }
454}
455
456#[derive(Default, Debug, Clone, PartialEq, Eq)]
475pub struct H265AggregationUnit {
476 dond: Option<u8>,
477 nal_unit_size: u16,
478 nal_unit: Bytes,
479}
480
481impl H265AggregationUnit {
482 pub fn dond(&self) -> Option<u8> {
486 self.dond
487 }
488
489 pub fn nalu_size(&self) -> u16 {
491 self.nal_unit_size
492 }
493
494 pub fn nal_unit(&self) -> Bytes {
496 self.nal_unit.clone()
497 }
498}
499
500#[derive(Default, Debug, Clone, PartialEq, Eq)]
519pub struct H265AggregationPacket {
520 first_unit: Option<H265AggregationUnitFirst>,
521 other_units: Vec<H265AggregationUnit>,
522
523 might_need_donl: bool,
524}
525
526impl H265AggregationPacket {
527 pub fn with_donl(&mut self, value: bool) {
530 self.might_need_donl = value;
531 }
532
533 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
535 if payload.len() <= H265NALU_HEADER_SIZE {
536 return Err(Error::ErrShortPacket);
537 }
538
539 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
540 if payload_header.f() {
541 return Err(Error::ErrH265CorruptedPacket);
542 }
543 if !payload_header.is_aggregation_packet() {
544 return Err(Error::ErrInvalidH265PacketType);
545 }
546
547 let mut payload = payload.slice(2..);
549 let mut first_unit = H265AggregationUnitFirst::default();
550
551 if self.might_need_donl {
552 if payload.len() < 2 {
553 return Err(Error::ErrShortPacket);
554 }
555
556 let donl = ((payload[0] as u16) << 8) | (payload[1] as u16);
557 first_unit.donl = Some(donl);
558
559 payload = payload.slice(2..);
560 }
561 if payload.len() < 2 {
562 return Err(Error::ErrShortPacket);
563 }
564 first_unit.nal_unit_size = ((payload[0] as u16) << 8) | (payload[1] as u16);
565 payload = payload.slice(2..);
566
567 if payload.len() < first_unit.nal_unit_size as usize {
568 return Err(Error::ErrShortPacket);
569 }
570
571 first_unit.nal_unit = payload.slice(..first_unit.nal_unit_size as usize);
572 payload = payload.slice(first_unit.nal_unit_size as usize..);
573
574 let mut units = vec![]; loop {
577 let mut unit = H265AggregationUnit::default();
578
579 if self.might_need_donl {
580 if payload.is_empty() {
581 break;
582 }
583
584 let dond = payload[0];
585 unit.dond = Some(dond);
586
587 payload = payload.slice(1..);
588 }
589
590 if payload.len() < 2 {
591 break;
592 }
593 unit.nal_unit_size = ((payload[0] as u16) << 8) | (payload[1] as u16);
594 payload = payload.slice(2..);
595
596 if payload.len() < unit.nal_unit_size as usize {
597 break;
598 }
599
600 unit.nal_unit = payload.slice(..unit.nal_unit_size as usize);
601 payload = payload.slice(unit.nal_unit_size as usize..);
602
603 units.push(unit);
604 }
605
606 if units.is_empty() {
608 return Err(Error::ErrShortPacket);
609 }
610
611 self.first_unit = Some(first_unit);
612 self.other_units = units;
613
614 Ok(())
615 }
616
617 pub fn first_unit(&self) -> Option<&H265AggregationUnitFirst> {
619 self.first_unit.as_ref()
620 }
621
622 pub fn other_units(&self) -> &[H265AggregationUnit] {
624 self.other_units.as_slice()
625 }
626}
627
628#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
637pub struct H265FragmentationUnitHeader(pub u8);
638
639impl H265FragmentationUnitHeader {
640 pub fn s(&self) -> bool {
642 const MASK: u8 = 0b10000000;
643 ((self.0 & MASK) >> 7) != 0
644 }
645
646 pub fn e(&self) -> bool {
648 const MASK: u8 = 0b01000000;
649 ((self.0 & MASK) >> 6) != 0
650 }
651
652 pub fn fu_type(&self) -> u8 {
654 const MASK: u8 = 0b00111111;
655 self.0 & MASK
656 }
657}
658
659#[derive(Default, Debug, Clone, PartialEq, Eq)]
680pub struct H265FragmentationUnitPacket {
681 payload_header: H265NALUHeader,
683 fu_header: H265FragmentationUnitHeader,
685 donl: Option<u16>,
687 payload: Bytes,
689
690 might_need_donl: bool,
691}
692
693impl H265FragmentationUnitPacket {
694 pub fn with_donl(&mut self, value: bool) {
697 self.might_need_donl = value;
698 }
699
700 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
702 const TOTAL_HEADER_SIZE: usize = H265NALU_HEADER_SIZE + H265FRAGMENTATION_UNIT_HEADER_SIZE;
703 if payload.len() <= TOTAL_HEADER_SIZE {
704 return Err(Error::ErrShortPacket);
705 }
706
707 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
708 if payload_header.f() {
709 return Err(Error::ErrH265CorruptedPacket);
710 }
711 if !payload_header.is_fragmentation_unit() {
712 return Err(Error::ErrInvalidH265PacketType);
713 }
714
715 let fu_header = H265FragmentationUnitHeader(payload[2]);
716 let mut payload = payload.slice(3..);
717
718 if fu_header.s() && self.might_need_donl {
719 if payload.len() <= 2 {
720 return Err(Error::ErrShortPacket);
721 }
722
723 let donl = ((payload[0] as u16) << 8) | (payload[1] as u16);
724 self.donl = Some(donl);
725 payload = payload.slice(2..);
726 }
727
728 self.payload_header = payload_header;
729 self.fu_header = fu_header;
730 self.payload = payload;
731
732 Ok(())
733 }
734
735 pub fn payload_header(&self) -> H265NALUHeader {
737 self.payload_header
738 }
739
740 pub fn fu_header(&self) -> H265FragmentationUnitHeader {
742 self.fu_header
743 }
744
745 pub fn donl(&self) -> Option<u16> {
747 self.donl
748 }
749
750 pub fn payload(&self) -> Bytes {
752 self.payload.clone()
753 }
754}
755
756#[derive(Default, Debug, Clone, PartialEq, Eq)]
782pub struct H265PACIPacket {
783 payload_header: H265NALUHeader,
785
786 paci_header_fields: u16,
788
789 phes: Bytes,
791
792 payload: Bytes,
794}
795
796impl H265PACIPacket {
797 pub fn payload_header(&self) -> H265NALUHeader {
799 self.payload_header
800 }
801
802 pub fn a(&self) -> bool {
804 const MASK: u16 = 0b10000000 << 8;
805 (self.paci_header_fields & MASK) != 0
806 }
807
808 pub fn ctype(&self) -> u8 {
810 const MASK: u16 = 0b01111110 << 8;
811 ((self.paci_header_fields & MASK) >> (8 + 1)) as u8
812 }
813
814 pub fn phs_size(&self) -> u8 {
816 const MASK: u16 = (0b00000001 << 8) | 0b11110000;
817 ((self.paci_header_fields & MASK) >> 4) as u8
818 }
819
820 pub fn f0(&self) -> bool {
822 const MASK: u16 = 0b00001000;
823 (self.paci_header_fields & MASK) != 0
824 }
825
826 pub fn f1(&self) -> bool {
828 const MASK: u16 = 0b00000100;
829 (self.paci_header_fields & MASK) != 0
830 }
831
832 pub fn f2(&self) -> bool {
834 const MASK: u16 = 0b00000010;
835 (self.paci_header_fields & MASK) != 0
836 }
837
838 pub fn y(&self) -> bool {
840 const MASK: u16 = 0b00000001;
841 (self.paci_header_fields & MASK) != 0
842 }
843
844 pub fn phes(&self) -> Bytes {
846 self.phes.clone()
847 }
848
849 pub fn payload(&self) -> Bytes {
851 self.payload.clone()
852 }
853
854 pub fn tsci(&self) -> Option<H265TSCI> {
856 if !self.f0() || self.phs_size() < 3 {
857 return None;
858 }
859
860 Some(H265TSCI(
861 ((self.phes[0] as u32) << 16) | ((self.phes[1] as u32) << 8) | self.phes[0] as u32,
862 ))
863 }
864
865 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
867 const TOTAL_HEADER_SIZE: usize = H265NALU_HEADER_SIZE + 2;
868 if payload.len() <= TOTAL_HEADER_SIZE {
869 return Err(Error::ErrShortPacket);
870 }
871
872 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
873 if payload_header.f() {
874 return Err(Error::ErrH265CorruptedPacket);
875 }
876 if !payload_header.is_paci_packet() {
877 return Err(Error::ErrInvalidH265PacketType);
878 }
879
880 let paci_header_fields = ((payload[2] as u16) << 8) | (payload[3] as u16);
881 let mut payload = payload.slice(4..);
882
883 self.paci_header_fields = paci_header_fields;
884 let header_extension_size = self.phs_size();
885
886 if payload.len() < header_extension_size as usize + 1 {
887 self.paci_header_fields = 0;
888 return Err(Error::ErrShortPacket);
889 }
890
891 self.payload_header = payload_header;
892
893 if header_extension_size > 0 {
894 self.phes = payload.slice(..header_extension_size as usize);
895 }
896
897 payload = payload.slice(header_extension_size as usize..);
898 self.payload = payload;
899
900 Ok(())
901 }
902}
903
904#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
915pub struct H265TSCI(pub u32);
916
917impl H265TSCI {
918 pub fn tl0picidx(&self) -> u8 {
920 const M1: u32 = 0xFFFF0000;
921 const M2: u32 = 0xFF00;
922 ((((self.0 & M1) >> 16) & M2) >> 8) as u8
923 }
924
925 pub fn irap_pic_id(&self) -> u8 {
927 const M1: u32 = 0xFFFF0000;
928 const M2: u32 = 0x00FF;
929 (((self.0 & M1) >> 16) & M2) as u8
930 }
931
932 pub fn s(&self) -> bool {
934 const M1: u32 = 0xFF00;
935 const M2: u32 = 0b10000000;
936 (((self.0 & M1) >> 8) & M2) != 0
937 }
938
939 pub fn e(&self) -> bool {
941 const M1: u32 = 0xFF00;
942 const M2: u32 = 0b01000000;
943 (((self.0 & M1) >> 8) & M2) != 0
944 }
945
946 pub fn res(&self) -> u8 {
948 const M1: u32 = 0xFF00;
949 const M2: u32 = 0b00111111;
950 (((self.0 & M1) >> 8) & M2) as u8
951 }
952}
953
954#[derive(Debug, Clone, PartialEq, Eq)]
958pub enum H265Payload {
959 H265SingleNALUnitPacket(H265SingleNALUnitPacket),
960 H265FragmentationUnitPacket(H265FragmentationUnitPacket),
961 H265AggregationPacket(H265AggregationPacket),
962 H265PACIPacket(H265PACIPacket),
963}
964
965impl Default for H265Payload {
966 fn default() -> Self {
967 H265Payload::H265SingleNALUnitPacket(H265SingleNALUnitPacket::default())
968 }
969}
970
971#[derive(Default, Debug, Clone, PartialEq, Eq)]
976pub struct H265Packet {
977 payload: H265Payload,
978 might_need_donl: bool,
979}
980
981impl H265Packet {
982 pub fn with_donl(&mut self, value: bool) {
985 self.might_need_donl = value;
986 }
987
988 pub fn payload(&self) -> &H265Payload {
995 &self.payload
996 }
997}
998
999impl Depacketizer for H265Packet {
1000 fn depacketize(&mut self, payload: &Bytes) -> Result<Bytes> {
1002 if payload.len() <= H265NALU_HEADER_SIZE {
1003 return Err(Error::ErrShortPacket);
1004 }
1005
1006 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
1007 if payload_header.f() {
1008 return Err(Error::ErrH265CorruptedPacket);
1009 }
1010
1011 if payload_header.is_paci_packet() {
1012 let mut decoded = H265PACIPacket::default();
1013 decoded.depacketize(payload)?;
1014
1015 self.payload = H265Payload::H265PACIPacket(decoded);
1016 } else if payload_header.is_fragmentation_unit() {
1017 let mut decoded = H265FragmentationUnitPacket::default();
1018 decoded.with_donl(self.might_need_donl);
1019
1020 decoded.depacketize(payload)?;
1021
1022 self.payload = H265Payload::H265FragmentationUnitPacket(decoded);
1023 } else if payload_header.is_aggregation_packet() {
1024 let mut decoded = H265AggregationPacket::default();
1025 decoded.with_donl(self.might_need_donl);
1026
1027 decoded.depacketize(payload)?;
1028
1029 self.payload = H265Payload::H265AggregationPacket(decoded);
1030 } else {
1031 let mut decoded = H265SingleNALUnitPacket::default();
1032 decoded.with_donl(self.might_need_donl);
1033
1034 decoded.depacketize(payload)?;
1035
1036 self.payload = H265Payload::H265SingleNALUnitPacket(decoded);
1037 }
1038
1039 Ok(payload.clone())
1040 }
1041
1042 fn is_partition_head(&self, _payload: &Bytes) -> bool {
1044 true
1046 }
1047
1048 fn is_partition_tail(&self, marker: bool, _payload: &Bytes) -> bool {
1049 marker
1050 }
1051}