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
63impl HevcPayloader {
64 fn aggregation_payload_header(nalus: &[Bytes]) -> [u8; 2] {
65 let mut f = false;
66 let mut layer_id = u8::MAX;
67 let mut tid = u8::MAX;
68
69 for nalu in nalus {
70 let header = H265NALUHeader::new(nalu[0], nalu[1]);
71 f |= header.f();
72 layer_id = layer_id.min(header.layer_id());
73 tid = tid.min(header.tid());
74 }
75
76 let mut raw = (H265NALU_AGGREGATION_PACKET_TYPE as u16) << 9;
77 raw |= (layer_id as u16) << 3;
78 raw |= tid as u16;
79 if f {
80 raw |= 1 << 15;
81 }
82
83 raw.to_be_bytes()
84 }
85
86 fn fragmentation_payload_header(payload_header: H265NALUHeader) -> [u8; 2] {
87 let mut raw = (H265NALU_FRAGMENTATION_UNIT_TYPE as u16) << 9;
88 raw |= (payload_header.layer_id() as u16) << 3;
89 raw |= payload_header.tid() as u16;
90 if payload_header.f() {
91 raw |= 1 << 15;
92 }
93
94 raw.to_be_bytes()
95 }
96
97 fn fu_header(nalu_type: u8, is_first: bool, is_last: bool) -> u8 {
98 let mut header = nalu_type & 0b0011_1111;
99 if is_first {
100 header |= 0b1000_0000;
101 } else if is_last {
102 header |= 0b0100_0000;
103 }
104 header
105 }
106
107 pub fn parse(nalu: &Bytes) -> (Vec<usize>, usize) {
108 let finder = memchr::memmem::Finder::new(&ANNEXB_NALUSTART_CODE);
109 let nals = finder.find_iter(nalu).collect::<Vec<usize>>();
110 if nals.is_empty() {
111 let finder = memchr::memmem::Finder::new(&ANNEXB_3_NALUSTART_CODE);
112 return (finder.find_iter(nalu).collect::<Vec<usize>>(), 3);
113 }
114 (nals, 4)
115 }
116
117 fn flush_aggregation_buffer(nalus: &mut Vec<Bytes>, mtu: usize, payloads: &mut Vec<Bytes>) {
118 match nalus.len() {
119 0 => {}
120 1 => {
121 payloads.push(nalus.pop().expect("single buffered NAL exists"));
122 }
123 _ => {
124 let header = Self::aggregation_payload_header(nalus);
125 let mut aggr_nalu = BytesMut::with_capacity(
126 NAL_HEADER_SIZE + nalus.iter().map(|nalu| 2 + nalu.len()).sum::<usize>(),
127 );
128 aggr_nalu.extend_from_slice(&header);
129 for nalu in nalus.drain(..) {
130 aggr_nalu.extend_from_slice(&(nalu.len() as u16).to_be_bytes());
131 aggr_nalu.extend_from_slice(&nalu);
132 }
133 if aggr_nalu.len() <= mtu {
134 payloads.push(aggr_nalu.freeze());
135 }
136 }
137 }
138 }
139
140 fn emit(nalu: &Bytes, mtu: usize, payloads: &mut Vec<Bytes>) {
141 if nalu.is_empty() {
142 return;
143 }
144 let payload_header = H265NALUHeader::new(nalu[0], nalu[1]);
145 let payload_nalu_type = payload_header.nalu_type();
146
147 if payload_nalu_type >= H265NALU_AGGREGATION_PACKET_TYPE {
148 return;
149 }
150
151 if nalu.len() <= mtu {
153 payloads.push(nalu.clone());
154 return;
155 }
156 let max_fragment_size =
157 mtu as isize - NAL_HEADER_SIZE as isize - H265FRAGMENTATION_UNIT_HEADER_SIZE as isize;
158 let nalu_data = nalu;
159 let mut nalu_data_index = 2;
160 let nalu_data_length = nalu.len() as isize - nalu_data_index;
161 let mut nalu_data_remaining = nalu_data_length;
162 if std::cmp::min(max_fragment_size, nalu_data_remaining) <= 0 {
163 return;
164 }
165 while nalu_data_remaining > 0 {
166 let current_fragment_size = std::cmp::min(max_fragment_size, nalu_data_remaining);
167 let mut out = BytesMut::with_capacity(
168 NAL_HEADER_SIZE
169 + H265FRAGMENTATION_UNIT_HEADER_SIZE
170 + current_fragment_size as usize,
171 );
172 out.extend_from_slice(&Self::fragmentation_payload_header(payload_header));
173 let is_first = nalu_data_index == 2;
174 let is_last = nalu_data_remaining == current_fragment_size;
175 out.put_u8(Self::fu_header(payload_nalu_type, is_first, is_last));
176
177 out.extend_from_slice(
178 &nalu_data
179 [nalu_data_index as usize..(nalu_data_index + current_fragment_size) as usize],
180 );
181 payloads.push(out.freeze());
182
183 nalu_data_remaining -= current_fragment_size;
184 nalu_data_index += current_fragment_size;
185 }
186 }
187}
188
189impl Payloader for HevcPayloader {
190 fn payload(&mut self, mtu: usize, payload: &Bytes) -> Result<Vec<Bytes>> {
192 if payload.is_empty() || mtu == 0 {
193 return Ok(vec![]);
194 }
195
196 let mut payloads = vec![];
197 let mut aggregation_buffer = vec![];
198
199 let (nal_idxs, offset) = HevcPayloader::parse(payload);
200 if nal_idxs.is_empty() {
201 Self::emit(payload, mtu, &mut payloads);
202 return Ok(payloads);
203 }
204 let nal_len = nal_idxs.len();
205 for (i, start) in nal_idxs.iter().enumerate() {
206 let end = if (i + 1) < nal_len {
207 nal_idxs[i + 1]
208 } else {
209 payload.len()
210 };
211 let nalu = payload.slice((start + offset)..end);
212 if nalu.len() < NAL_HEADER_SIZE {
213 continue;
214 }
215
216 let payload_header = H265NALUHeader::new(nalu[0], nalu[1]);
217 if payload_header.is_aggregation_packet()
218 || payload_header.is_fragmentation_unit()
219 || payload_header.is_paci_packet()
220 {
221 continue;
222 }
223
224 if nalu.len() > mtu {
225 Self::flush_aggregation_buffer(&mut aggregation_buffer, mtu, &mut payloads);
226 Self::emit(&nalu, mtu, &mut payloads);
227 continue;
228 }
229
230 let aggregated_size = NAL_HEADER_SIZE
231 + aggregation_buffer
232 .iter()
233 .map(|nalu| 2 + nalu.len())
234 .sum::<usize>()
235 + 2
236 + nalu.len();
237 if !aggregation_buffer.is_empty() && aggregated_size > mtu {
238 Self::flush_aggregation_buffer(&mut aggregation_buffer, mtu, &mut payloads);
239 }
240
241 aggregation_buffer.push(nalu);
242 }
243 Self::flush_aggregation_buffer(&mut aggregation_buffer, mtu, &mut payloads);
244
245 Ok(payloads)
246 }
247
248 fn clone_to(&self) -> Box<dyn Payloader> {
249 Box::new(self.clone())
250 }
251}
252
253const H265NALU_HEADER_SIZE: usize = 2;
257const H265NALU_AGGREGATION_PACKET_TYPE: u8 = 48;
259const H265NALU_FRAGMENTATION_UNIT_TYPE: u8 = 49;
261const H265NALU_PACI_PACKET_TYPE: u8 = 50;
263
264#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
280pub struct H265NALUHeader(pub u16);
281
282impl H265NALUHeader {
283 pub fn new(high_byte: u8, low_byte: u8) -> Self {
284 H265NALUHeader(((high_byte as u16) << 8) | low_byte as u16)
285 }
286
287 pub fn f(&self) -> bool {
289 (self.0 >> 15) != 0
290 }
291
292 pub fn nalu_type(&self) -> u8 {
294 const MASK: u16 = 0b01111110 << 8;
296 ((self.0 & MASK) >> (8 + 1)) as u8
297 }
298
299 pub fn is_type_vcl_unit(&self) -> bool {
301 const MSB_MASK: u8 = 0b00100000;
303 (self.nalu_type() & MSB_MASK) == 0
304 }
305
306 pub fn layer_id(&self) -> u8 {
308 const MASK: u16 = (0b00000001 << 8) | 0b11111000;
310 ((self.0 & MASK) >> 3) as u8
311 }
312
313 pub fn tid(&self) -> u8 {
315 const MASK: u16 = 0b00000111;
316 (self.0 & MASK) as u8
317 }
318
319 pub fn is_aggregation_packet(&self) -> bool {
321 self.nalu_type() == H265NALU_AGGREGATION_PACKET_TYPE
322 }
323
324 pub fn is_fragmentation_unit(&self) -> bool {
326 self.nalu_type() == H265NALU_FRAGMENTATION_UNIT_TYPE
327 }
328
329 pub fn is_paci_packet(&self) -> bool {
331 self.nalu_type() == H265NALU_PACI_PACKET_TYPE
332 }
333}
334
335#[derive(Default, Debug, Clone, PartialEq, Eq)]
357pub struct H265SingleNALUnitPacket {
358 payload_header: H265NALUHeader,
360 donl: Option<u16>,
362 payload: Bytes,
364
365 might_need_donl: bool,
366}
367
368impl H265SingleNALUnitPacket {
369 pub fn with_donl(&mut self, value: bool) {
372 self.might_need_donl = value;
373 }
374
375 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
377 if payload.len() <= H265NALU_HEADER_SIZE {
378 return Err(Error::ErrShortPacket);
379 }
380
381 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
382 if payload_header.f() {
383 return Err(Error::ErrH265CorruptedPacket);
384 }
385 if payload_header.is_fragmentation_unit()
386 || payload_header.is_paci_packet()
387 || payload_header.is_aggregation_packet()
388 {
389 return Err(Error::ErrInvalidH265PacketType);
390 }
391
392 let mut payload = payload.slice(2..);
393
394 if self.might_need_donl {
395 if payload.len() <= 2 {
397 return Err(Error::ErrShortPacket);
398 }
399
400 let donl = ((payload[0] as u16) << 8) | (payload[1] as u16);
401 self.donl = Some(donl);
402 payload = payload.slice(2..);
403 }
404
405 self.payload_header = payload_header;
406 self.payload = payload;
407
408 Ok(())
409 }
410
411 pub fn payload_header(&self) -> H265NALUHeader {
413 self.payload_header
414 }
415
416 pub fn donl(&self) -> Option<u16> {
418 self.donl
419 }
420
421 pub fn payload(&self) -> Bytes {
423 self.payload.clone()
424 }
425}
426
427#[derive(Default, Debug, Clone, PartialEq, Eq)]
450pub struct H265AggregationUnitFirst {
451 donl: Option<u16>,
452 nal_unit_size: u16,
453 nal_unit: Bytes,
454}
455
456impl H265AggregationUnitFirst {
457 pub fn donl(&self) -> Option<u16> {
461 self.donl
462 }
463
464 pub fn nalu_size(&self) -> u16 {
466 self.nal_unit_size
467 }
468
469 pub fn nal_unit(&self) -> Bytes {
471 self.nal_unit.clone()
472 }
473}
474
475#[derive(Default, Debug, Clone, PartialEq, Eq)]
494pub struct H265AggregationUnit {
495 dond: Option<u8>,
496 nal_unit_size: u16,
497 nal_unit: Bytes,
498}
499
500impl H265AggregationUnit {
501 pub fn dond(&self) -> Option<u8> {
505 self.dond
506 }
507
508 pub fn nalu_size(&self) -> u16 {
510 self.nal_unit_size
511 }
512
513 pub fn nal_unit(&self) -> Bytes {
515 self.nal_unit.clone()
516 }
517}
518
519#[derive(Default, Debug, Clone, PartialEq, Eq)]
538pub struct H265AggregationPacket {
539 first_unit: Option<H265AggregationUnitFirst>,
540 other_units: Vec<H265AggregationUnit>,
541
542 might_need_donl: bool,
543}
544
545impl H265AggregationPacket {
546 pub fn with_donl(&mut self, value: bool) {
549 self.might_need_donl = value;
550 }
551
552 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
554 if payload.len() <= H265NALU_HEADER_SIZE {
555 return Err(Error::ErrShortPacket);
556 }
557
558 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
559 if payload_header.f() {
560 return Err(Error::ErrH265CorruptedPacket);
561 }
562 if !payload_header.is_aggregation_packet() {
563 return Err(Error::ErrInvalidH265PacketType);
564 }
565
566 let mut payload = payload.slice(2..);
568 let mut first_unit = H265AggregationUnitFirst::default();
569
570 if self.might_need_donl {
571 if payload.len() < 2 {
572 return Err(Error::ErrShortPacket);
573 }
574
575 let donl = ((payload[0] as u16) << 8) | (payload[1] as u16);
576 first_unit.donl = Some(donl);
577
578 payload = payload.slice(2..);
579 }
580 if payload.len() < 2 {
581 return Err(Error::ErrShortPacket);
582 }
583 first_unit.nal_unit_size = ((payload[0] as u16) << 8) | (payload[1] as u16);
584 payload = payload.slice(2..);
585
586 if payload.len() < first_unit.nal_unit_size as usize {
587 return Err(Error::ErrShortPacket);
588 }
589
590 first_unit.nal_unit = payload.slice(..first_unit.nal_unit_size as usize);
591 payload = payload.slice(first_unit.nal_unit_size as usize..);
592
593 let mut units = vec![]; loop {
596 let mut unit = H265AggregationUnit::default();
597
598 if self.might_need_donl {
599 if payload.is_empty() {
600 break;
601 }
602
603 let dond = payload[0];
604 unit.dond = Some(dond);
605
606 payload = payload.slice(1..);
607 }
608
609 if payload.len() < 2 {
610 break;
611 }
612 unit.nal_unit_size = ((payload[0] as u16) << 8) | (payload[1] as u16);
613 payload = payload.slice(2..);
614
615 if payload.len() < unit.nal_unit_size as usize {
616 break;
617 }
618
619 unit.nal_unit = payload.slice(..unit.nal_unit_size as usize);
620 payload = payload.slice(unit.nal_unit_size as usize..);
621
622 units.push(unit);
623 }
624
625 if units.is_empty() {
627 return Err(Error::ErrShortPacket);
628 }
629
630 self.first_unit = Some(first_unit);
631 self.other_units = units;
632
633 Ok(())
634 }
635
636 pub fn first_unit(&self) -> Option<&H265AggregationUnitFirst> {
638 self.first_unit.as_ref()
639 }
640
641 pub fn other_units(&self) -> &[H265AggregationUnit] {
643 self.other_units.as_slice()
644 }
645}
646
647#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
656pub struct H265FragmentationUnitHeader(pub u8);
657
658impl H265FragmentationUnitHeader {
659 pub fn s(&self) -> bool {
661 const MASK: u8 = 0b10000000;
662 ((self.0 & MASK) >> 7) != 0
663 }
664
665 pub fn e(&self) -> bool {
667 const MASK: u8 = 0b01000000;
668 ((self.0 & MASK) >> 6) != 0
669 }
670
671 pub fn fu_type(&self) -> u8 {
673 const MASK: u8 = 0b00111111;
674 self.0 & MASK
675 }
676}
677
678#[derive(Default, Debug, Clone, PartialEq, Eq)]
699pub struct H265FragmentationUnitPacket {
700 payload_header: H265NALUHeader,
702 fu_header: H265FragmentationUnitHeader,
704 donl: Option<u16>,
706 payload: Bytes,
708
709 might_need_donl: bool,
710}
711
712impl H265FragmentationUnitPacket {
713 pub fn with_donl(&mut self, value: bool) {
716 self.might_need_donl = value;
717 }
718
719 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
721 const TOTAL_HEADER_SIZE: usize = H265NALU_HEADER_SIZE + H265FRAGMENTATION_UNIT_HEADER_SIZE;
722 if payload.len() <= TOTAL_HEADER_SIZE {
723 return Err(Error::ErrShortPacket);
724 }
725
726 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
727 if payload_header.f() {
728 return Err(Error::ErrH265CorruptedPacket);
729 }
730 if !payload_header.is_fragmentation_unit() {
731 return Err(Error::ErrInvalidH265PacketType);
732 }
733
734 let fu_header = H265FragmentationUnitHeader(payload[2]);
735 let mut payload = payload.slice(3..);
736
737 if fu_header.s() && self.might_need_donl {
738 if payload.len() <= 2 {
739 return Err(Error::ErrShortPacket);
740 }
741
742 let donl = ((payload[0] as u16) << 8) | (payload[1] as u16);
743 self.donl = Some(donl);
744 payload = payload.slice(2..);
745 }
746
747 self.payload_header = payload_header;
748 self.fu_header = fu_header;
749 self.payload = payload;
750
751 Ok(())
752 }
753
754 pub fn payload_header(&self) -> H265NALUHeader {
756 self.payload_header
757 }
758
759 pub fn fu_header(&self) -> H265FragmentationUnitHeader {
761 self.fu_header
762 }
763
764 pub fn donl(&self) -> Option<u16> {
766 self.donl
767 }
768
769 pub fn payload(&self) -> Bytes {
771 self.payload.clone()
772 }
773}
774
775#[derive(Default, Debug, Clone, PartialEq, Eq)]
801pub struct H265PACIPacket {
802 payload_header: H265NALUHeader,
804
805 paci_header_fields: u16,
807
808 phes: Bytes,
810
811 payload: Bytes,
813}
814
815impl H265PACIPacket {
816 pub fn payload_header(&self) -> H265NALUHeader {
818 self.payload_header
819 }
820
821 pub fn a(&self) -> bool {
823 const MASK: u16 = 0b10000000 << 8;
824 (self.paci_header_fields & MASK) != 0
825 }
826
827 pub fn ctype(&self) -> u8 {
829 const MASK: u16 = 0b01111110 << 8;
830 ((self.paci_header_fields & MASK) >> (8 + 1)) as u8
831 }
832
833 pub fn phs_size(&self) -> u8 {
835 const MASK: u16 = (0b00000001 << 8) | 0b11110000;
836 ((self.paci_header_fields & MASK) >> 4) as u8
837 }
838
839 pub fn f0(&self) -> bool {
841 const MASK: u16 = 0b00001000;
842 (self.paci_header_fields & MASK) != 0
843 }
844
845 pub fn f1(&self) -> bool {
847 const MASK: u16 = 0b00000100;
848 (self.paci_header_fields & MASK) != 0
849 }
850
851 pub fn f2(&self) -> bool {
853 const MASK: u16 = 0b00000010;
854 (self.paci_header_fields & MASK) != 0
855 }
856
857 pub fn y(&self) -> bool {
859 const MASK: u16 = 0b00000001;
860 (self.paci_header_fields & MASK) != 0
861 }
862
863 pub fn phes(&self) -> Bytes {
865 self.phes.clone()
866 }
867
868 pub fn payload(&self) -> Bytes {
870 self.payload.clone()
871 }
872
873 pub fn tsci(&self) -> Option<H265TSCI> {
875 if !self.f0() || self.phs_size() < 3 {
876 return None;
877 }
878
879 Some(H265TSCI(
880 ((self.phes[0] as u32) << 16) | ((self.phes[1] as u32) << 8) | self.phes[0] as u32,
881 ))
882 }
883
884 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
886 const TOTAL_HEADER_SIZE: usize = H265NALU_HEADER_SIZE + 2;
887 if payload.len() <= TOTAL_HEADER_SIZE {
888 return Err(Error::ErrShortPacket);
889 }
890
891 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
892 if payload_header.f() {
893 return Err(Error::ErrH265CorruptedPacket);
894 }
895 if !payload_header.is_paci_packet() {
896 return Err(Error::ErrInvalidH265PacketType);
897 }
898
899 let paci_header_fields = ((payload[2] as u16) << 8) | (payload[3] as u16);
900 let mut payload = payload.slice(4..);
901
902 self.paci_header_fields = paci_header_fields;
903 let header_extension_size = self.phs_size();
904
905 if payload.len() < header_extension_size as usize + 1 {
906 self.paci_header_fields = 0;
907 return Err(Error::ErrShortPacket);
908 }
909
910 self.payload_header = payload_header;
911
912 if header_extension_size > 0 {
913 self.phes = payload.slice(..header_extension_size as usize);
914 }
915
916 payload = payload.slice(header_extension_size as usize..);
917 self.payload = payload;
918
919 Ok(())
920 }
921}
922
923#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
934pub struct H265TSCI(pub u32);
935
936impl H265TSCI {
937 pub fn tl0picidx(&self) -> u8 {
939 const M1: u32 = 0xFFFF0000;
940 const M2: u32 = 0xFF00;
941 ((((self.0 & M1) >> 16) & M2) >> 8) as u8
942 }
943
944 pub fn irap_pic_id(&self) -> u8 {
946 const M1: u32 = 0xFFFF0000;
947 const M2: u32 = 0x00FF;
948 (((self.0 & M1) >> 16) & M2) as u8
949 }
950
951 pub fn s(&self) -> bool {
953 const M1: u32 = 0xFF00;
954 const M2: u32 = 0b10000000;
955 (((self.0 & M1) >> 8) & M2) != 0
956 }
957
958 pub fn e(&self) -> bool {
960 const M1: u32 = 0xFF00;
961 const M2: u32 = 0b01000000;
962 (((self.0 & M1) >> 8) & M2) != 0
963 }
964
965 pub fn res(&self) -> u8 {
967 const M1: u32 = 0xFF00;
968 const M2: u32 = 0b00111111;
969 (((self.0 & M1) >> 8) & M2) as u8
970 }
971}
972
973#[derive(Debug, Clone, PartialEq, Eq)]
977pub enum H265Payload {
978 H265SingleNALUnitPacket(H265SingleNALUnitPacket),
979 H265FragmentationUnitPacket(H265FragmentationUnitPacket),
980 H265AggregationPacket(H265AggregationPacket),
981 H265PACIPacket(H265PACIPacket),
982}
983
984impl Default for H265Payload {
985 fn default() -> Self {
986 H265Payload::H265SingleNALUnitPacket(H265SingleNALUnitPacket::default())
987 }
988}
989
990#[derive(Default, Debug, Clone, PartialEq, Eq)]
995pub struct H265Packet {
996 payload: H265Payload,
997 might_need_donl: bool,
998}
999
1000impl H265Packet {
1001 pub fn with_donl(&mut self, value: bool) {
1004 self.might_need_donl = value;
1005 }
1006
1007 pub fn payload(&self) -> &H265Payload {
1014 &self.payload
1015 }
1016}
1017
1018impl Depacketizer for H265Packet {
1019 fn depacketize(&mut self, payload: &Bytes) -> Result<Bytes> {
1021 if payload.len() <= H265NALU_HEADER_SIZE {
1022 return Err(Error::ErrShortPacket);
1023 }
1024
1025 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
1026 if payload_header.f() {
1027 return Err(Error::ErrH265CorruptedPacket);
1028 }
1029
1030 if payload_header.is_paci_packet() {
1031 let mut decoded = H265PACIPacket::default();
1032 decoded.depacketize(payload)?;
1033
1034 self.payload = H265Payload::H265PACIPacket(decoded);
1035 } else if payload_header.is_fragmentation_unit() {
1036 let mut decoded = H265FragmentationUnitPacket::default();
1037 decoded.with_donl(self.might_need_donl);
1038
1039 decoded.depacketize(payload)?;
1040
1041 self.payload = H265Payload::H265FragmentationUnitPacket(decoded);
1042 } else if payload_header.is_aggregation_packet() {
1043 let mut decoded = H265AggregationPacket::default();
1044 decoded.with_donl(self.might_need_donl);
1045
1046 decoded.depacketize(payload)?;
1047
1048 self.payload = H265Payload::H265AggregationPacket(decoded);
1049 } else {
1050 let mut decoded = H265SingleNALUnitPacket::default();
1051 decoded.with_donl(self.might_need_donl);
1052
1053 decoded.depacketize(payload)?;
1054
1055 self.payload = H265Payload::H265SingleNALUnitPacket(decoded);
1056 }
1057
1058 Ok(payload.clone())
1059 }
1060
1061 fn is_partition_head(&self, _payload: &Bytes) -> bool {
1063 true
1065 }
1066
1067 fn is_partition_tail(&self, marker: bool, _payload: &Bytes) -> bool {
1068 marker
1069 }
1070}