1use bytes::{BufMut, Bytes, BytesMut};
14
15use super::h264::ANNEXB_NALUSTART_CODE;
16use crate::packetizer::{Depacketizer, Payloader};
17use shared::error::{Error, Result};
18
19#[cfg(test)]
20mod h265_test;
21
22pub static ANNEXB_3_NALUSTART_CODE: Bytes = Bytes::from_static(&[0x00, 0x00, 0x01]);
24pub static SING_PAYLOAD_HDR: Bytes = Bytes::from_static(&[0x1C, 0x01]);
26pub static AGGR_PAYLOAD_HDR: Bytes = Bytes::from_static(&[0x60, 0x01]);
28pub static FRAG_PAYLOAD_HDR: Bytes = Bytes::from_static(&[0x62, 0x01]);
30pub static FU_HDR_IDR_S: u8 = 0x93;
32pub static FU_HDR_IDR_M: u8 = 0x13;
34pub static FU_HDR_IDR_E: u8 = 0x53;
36pub static FU_HDR_P_S: u8 = 0x81;
38pub static FU_HDR_P_M: u8 = 0x01;
40pub static FU_HDR_P_E: u8 = 0x41;
42pub static FU_HDR_B_S: u8 = 0x80;
44pub static FU_HDR_B_M: u8 = 0x00;
46pub static FU_HDR_B_E: u8 = 0x40;
48pub const RTP_OUTBOUND_MTU: usize = 1200;
51pub const H265FRAGMENTATION_UNIT_HEADER_SIZE: usize = 1;
53pub const NAL_HEADER_SIZE: usize = 2;
55
56#[derive(PartialEq, Hash, Debug, Copy, Clone)]
57pub enum UnitType {
59 VPS = 32,
61 SPS = 33,
63 PPS = 34,
65 CRA = 21,
67 SEI = 39,
69 IDR = 19,
71 PFR = 1,
73 BFR = 0,
75 IGNORE = -1,
77}
78impl UnitType {
79 pub fn for_id(id: u8) -> Result<UnitType> {
85 if id > 64 {
86 Err(Error::ErrUnhandledNaluType)
87 } else {
88 let t = match id {
89 32 => UnitType::VPS,
90 33 => UnitType::SPS,
91 34 => UnitType::PPS,
92 21 => UnitType::CRA,
93 39 => UnitType::SEI,
94 19 => UnitType::IDR,
95 1 => UnitType::PFR,
96 0 => UnitType::BFR,
97 _ => UnitType::IGNORE, };
99 Ok(t)
100 }
101 }
102}
103
104#[derive(Default, Debug, Clone)]
105pub struct HevcPayloader;
107
108impl HevcPayloader {
109 fn aggregation_payload_header(nalus: &[Bytes]) -> [u8; 2] {
110 let mut f = false;
111 let mut layer_id = u8::MAX;
112 let mut tid = u8::MAX;
113
114 for nalu in nalus {
115 let header = H265NALUHeader::new(nalu[0], nalu[1]);
116 f |= header.f();
117 layer_id = layer_id.min(header.layer_id());
118 tid = tid.min(header.tid());
119 }
120
121 let mut raw = (H265NALU_AGGREGATION_PACKET_TYPE as u16) << 9;
122 raw |= (layer_id as u16) << 3;
123 raw |= tid as u16;
124 if f {
125 raw |= 1 << 15;
126 }
127
128 raw.to_be_bytes()
129 }
130
131 fn fragmentation_payload_header(payload_header: H265NALUHeader) -> [u8; 2] {
132 let mut raw = (H265NALU_FRAGMENTATION_UNIT_TYPE as u16) << 9;
133 raw |= (payload_header.layer_id() as u16) << 3;
134 raw |= payload_header.tid() as u16;
135 if payload_header.f() {
136 raw |= 1 << 15;
137 }
138
139 raw.to_be_bytes()
140 }
141
142 fn fu_header(nalu_type: u8, is_first: bool, is_last: bool) -> u8 {
143 let mut header = nalu_type & 0b0011_1111;
144 if is_first {
145 header |= 0b1000_0000;
146 } else if is_last {
147 header |= 0b0100_0000;
148 }
149 header
150 }
151
152 pub fn parse(nalu: &Bytes) -> (Vec<usize>, usize) {
156 let finder = memchr::memmem::Finder::new(&ANNEXB_NALUSTART_CODE);
157 let nals = finder.find_iter(nalu).collect::<Vec<usize>>();
158 if nals.is_empty() {
159 let finder = memchr::memmem::Finder::new(&ANNEXB_3_NALUSTART_CODE);
160 return (finder.find_iter(nalu).collect::<Vec<usize>>(), 3);
161 }
162 (nals, 4)
163 }
164
165 fn flush_aggregation_buffer(nalus: &mut Vec<Bytes>, mtu: usize, payloads: &mut Vec<Bytes>) {
166 match nalus.len() {
167 0 => {}
168 1 => {
169 payloads.push(nalus.pop().expect("single buffered NAL exists"));
170 }
171 _ => {
172 let header = Self::aggregation_payload_header(nalus);
173 let mut aggr_nalu = BytesMut::with_capacity(
174 NAL_HEADER_SIZE + nalus.iter().map(|nalu| 2 + nalu.len()).sum::<usize>(),
175 );
176 aggr_nalu.extend_from_slice(&header);
177 for nalu in nalus.drain(..) {
178 aggr_nalu.extend_from_slice(&(nalu.len() as u16).to_be_bytes());
179 aggr_nalu.extend_from_slice(&nalu);
180 }
181 if aggr_nalu.len() <= mtu {
182 payloads.push(aggr_nalu.freeze());
183 }
184 }
185 }
186 }
187
188 fn emit(nalu: &Bytes, mtu: usize, payloads: &mut Vec<Bytes>) {
189 if nalu.is_empty() {
190 return;
191 }
192 let payload_header = H265NALUHeader::new(nalu[0], nalu[1]);
193 let payload_nalu_type = payload_header.nalu_type();
194
195 if payload_nalu_type >= H265NALU_AGGREGATION_PACKET_TYPE {
196 return;
197 }
198
199 if nalu.len() <= mtu {
201 payloads.push(nalu.clone());
202 return;
203 }
204 let max_fragment_size =
205 mtu as isize - NAL_HEADER_SIZE as isize - H265FRAGMENTATION_UNIT_HEADER_SIZE as isize;
206 let nalu_data = nalu;
207 let mut nalu_data_index = 2;
208 let nalu_data_length = nalu.len() as isize - nalu_data_index;
209 let mut nalu_data_remaining = nalu_data_length;
210 if std::cmp::min(max_fragment_size, nalu_data_remaining) <= 0 {
211 return;
212 }
213 while nalu_data_remaining > 0 {
214 let current_fragment_size = std::cmp::min(max_fragment_size, nalu_data_remaining);
215 let mut out = BytesMut::with_capacity(
216 NAL_HEADER_SIZE
217 + H265FRAGMENTATION_UNIT_HEADER_SIZE
218 + current_fragment_size as usize,
219 );
220 out.extend_from_slice(&Self::fragmentation_payload_header(payload_header));
221 let is_first = nalu_data_index == 2;
222 let is_last = nalu_data_remaining == current_fragment_size;
223 out.put_u8(Self::fu_header(payload_nalu_type, is_first, is_last));
224
225 out.extend_from_slice(
226 &nalu_data
227 [nalu_data_index as usize..(nalu_data_index + current_fragment_size) as usize],
228 );
229 payloads.push(out.freeze());
230
231 nalu_data_remaining -= current_fragment_size;
232 nalu_data_index += current_fragment_size;
233 }
234 }
235}
236
237impl Payloader for HevcPayloader {
238 fn payload(&mut self, mtu: usize, payload: &Bytes) -> Result<Vec<Bytes>> {
240 if payload.is_empty() || mtu == 0 {
241 return Ok(vec![]);
242 }
243
244 let mut payloads = vec![];
245 let mut aggregation_buffer = vec![];
246
247 let (nal_idxs, offset) = HevcPayloader::parse(payload);
248 if nal_idxs.is_empty() {
249 Self::emit(payload, mtu, &mut payloads);
250 return Ok(payloads);
251 }
252 let nal_len = nal_idxs.len();
253 for (i, start) in nal_idxs.iter().enumerate() {
254 let end = if (i + 1) < nal_len {
255 nal_idxs[i + 1]
256 } else {
257 payload.len()
258 };
259 let nalu = payload.slice((start + offset)..end);
260 if nalu.len() < NAL_HEADER_SIZE {
261 continue;
262 }
263
264 let payload_header = H265NALUHeader::new(nalu[0], nalu[1]);
265 if payload_header.is_aggregation_packet()
266 || payload_header.is_fragmentation_unit()
267 || payload_header.is_paci_packet()
268 {
269 continue;
270 }
271
272 if nalu.len() > mtu {
273 Self::flush_aggregation_buffer(&mut aggregation_buffer, mtu, &mut payloads);
274 Self::emit(&nalu, mtu, &mut payloads);
275 continue;
276 }
277
278 let aggregated_size = NAL_HEADER_SIZE
279 + aggregation_buffer
280 .iter()
281 .map(|nalu| 2 + nalu.len())
282 .sum::<usize>()
283 + 2
284 + nalu.len();
285 if !aggregation_buffer.is_empty() && aggregated_size > mtu {
286 Self::flush_aggregation_buffer(&mut aggregation_buffer, mtu, &mut payloads);
287 }
288
289 aggregation_buffer.push(nalu);
290 }
291 Self::flush_aggregation_buffer(&mut aggregation_buffer, mtu, &mut payloads);
292
293 Ok(payloads)
294 }
295
296 fn clone_to(&self) -> Box<dyn Payloader> {
297 Box::new(self.clone())
298 }
299}
300
301const H265NALU_HEADER_SIZE: usize = 2;
305const H265NALU_AGGREGATION_PACKET_TYPE: u8 = 48;
307const H265NALU_FRAGMENTATION_UNIT_TYPE: u8 = 49;
309const H265NALU_PACI_PACKET_TYPE: u8 = 50;
311
312#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
328pub struct H265NALUHeader(pub u16);
329
330impl H265NALUHeader {
331 pub fn new(high_byte: u8, low_byte: u8) -> Self {
333 H265NALUHeader(((high_byte as u16) << 8) | low_byte as u16)
334 }
335
336 pub fn f(&self) -> bool {
338 (self.0 >> 15) != 0
339 }
340
341 pub fn nalu_type(&self) -> u8 {
343 const MASK: u16 = 0b01111110 << 8;
345 ((self.0 & MASK) >> (8 + 1)) as u8
346 }
347
348 pub fn is_type_vcl_unit(&self) -> bool {
350 const MSB_MASK: u8 = 0b00100000;
352 (self.nalu_type() & MSB_MASK) == 0
353 }
354
355 pub fn layer_id(&self) -> u8 {
357 const MASK: u16 = (0b00000001 << 8) | 0b11111000;
359 ((self.0 & MASK) >> 3) as u8
360 }
361
362 pub fn tid(&self) -> u8 {
364 const MASK: u16 = 0b00000111;
365 (self.0 & MASK) as u8
366 }
367
368 pub fn is_aggregation_packet(&self) -> bool {
370 self.nalu_type() == H265NALU_AGGREGATION_PACKET_TYPE
371 }
372
373 pub fn is_fragmentation_unit(&self) -> bool {
375 self.nalu_type() == H265NALU_FRAGMENTATION_UNIT_TYPE
376 }
377
378 pub fn is_paci_packet(&self) -> bool {
380 self.nalu_type() == H265NALU_PACI_PACKET_TYPE
381 }
382}
383
384#[derive(Default, Debug, Clone, PartialEq, Eq)]
406pub struct H265SingleNALUnitPacket {
407 payload_header: H265NALUHeader,
409 donl: Option<u16>,
411 payload: Bytes,
413
414 might_need_donl: bool,
415}
416
417impl H265SingleNALUnitPacket {
418 pub fn with_donl(&mut self, value: bool) {
421 self.might_need_donl = value;
422 }
423
424 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
426 if payload.len() <= H265NALU_HEADER_SIZE {
427 return Err(Error::ErrShortPacket);
428 }
429
430 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
431 if payload_header.f() {
432 return Err(Error::ErrH265CorruptedPacket);
433 }
434 if payload_header.is_fragmentation_unit()
435 || payload_header.is_paci_packet()
436 || payload_header.is_aggregation_packet()
437 {
438 return Err(Error::ErrInvalidH265PacketType);
439 }
440
441 let mut payload = payload.slice(2..);
442
443 if self.might_need_donl {
444 if payload.len() <= 2 {
446 return Err(Error::ErrShortPacket);
447 }
448
449 let donl = ((payload[0] as u16) << 8) | (payload[1] as u16);
450 self.donl = Some(donl);
451 payload = payload.slice(2..);
452 }
453
454 self.payload_header = payload_header;
455 self.payload = payload;
456
457 Ok(())
458 }
459
460 pub fn payload_header(&self) -> H265NALUHeader {
462 self.payload_header
463 }
464
465 pub fn donl(&self) -> Option<u16> {
467 self.donl
468 }
469
470 pub fn payload(&self) -> Bytes {
472 self.payload.clone()
473 }
474}
475
476#[derive(Default, Debug, Clone, PartialEq, Eq)]
499pub struct H265AggregationUnitFirst {
500 donl: Option<u16>,
501 nal_unit_size: u16,
502 nal_unit: Bytes,
503}
504
505impl H265AggregationUnitFirst {
506 pub fn donl(&self) -> Option<u16> {
510 self.donl
511 }
512
513 pub fn nalu_size(&self) -> u16 {
515 self.nal_unit_size
516 }
517
518 pub fn nal_unit(&self) -> Bytes {
520 self.nal_unit.clone()
521 }
522}
523
524#[derive(Default, Debug, Clone, PartialEq, Eq)]
543pub struct H265AggregationUnit {
544 dond: Option<u8>,
545 nal_unit_size: u16,
546 nal_unit: Bytes,
547}
548
549impl H265AggregationUnit {
550 pub fn dond(&self) -> Option<u8> {
554 self.dond
555 }
556
557 pub fn nalu_size(&self) -> u16 {
559 self.nal_unit_size
560 }
561
562 pub fn nal_unit(&self) -> Bytes {
564 self.nal_unit.clone()
565 }
566}
567
568#[derive(Default, Debug, Clone, PartialEq, Eq)]
587pub struct H265AggregationPacket {
588 first_unit: Option<H265AggregationUnitFirst>,
589 other_units: Vec<H265AggregationUnit>,
590
591 might_need_donl: bool,
592}
593
594impl H265AggregationPacket {
595 pub fn with_donl(&mut self, value: bool) {
598 self.might_need_donl = value;
599 }
600
601 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
603 if payload.len() <= H265NALU_HEADER_SIZE {
604 return Err(Error::ErrShortPacket);
605 }
606
607 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
608 if payload_header.f() {
609 return Err(Error::ErrH265CorruptedPacket);
610 }
611 if !payload_header.is_aggregation_packet() {
612 return Err(Error::ErrInvalidH265PacketType);
613 }
614
615 let mut payload = payload.slice(2..);
617 let mut first_unit = H265AggregationUnitFirst::default();
618
619 if self.might_need_donl {
620 if payload.len() < 2 {
621 return Err(Error::ErrShortPacket);
622 }
623
624 let donl = ((payload[0] as u16) << 8) | (payload[1] as u16);
625 first_unit.donl = Some(donl);
626
627 payload = payload.slice(2..);
628 }
629 if payload.len() < 2 {
630 return Err(Error::ErrShortPacket);
631 }
632 first_unit.nal_unit_size = ((payload[0] as u16) << 8) | (payload[1] as u16);
633 payload = payload.slice(2..);
634
635 if payload.len() < first_unit.nal_unit_size as usize {
636 return Err(Error::ErrShortPacket);
637 }
638
639 first_unit.nal_unit = payload.slice(..first_unit.nal_unit_size as usize);
640 payload = payload.slice(first_unit.nal_unit_size as usize..);
641
642 let mut units = vec![]; loop {
645 let mut unit = H265AggregationUnit::default();
646
647 if self.might_need_donl {
648 if payload.is_empty() {
649 break;
650 }
651
652 let dond = payload[0];
653 unit.dond = Some(dond);
654
655 payload = payload.slice(1..);
656 }
657
658 if payload.len() < 2 {
659 break;
660 }
661 unit.nal_unit_size = ((payload[0] as u16) << 8) | (payload[1] as u16);
662 payload = payload.slice(2..);
663
664 if payload.len() < unit.nal_unit_size as usize {
665 break;
666 }
667
668 unit.nal_unit = payload.slice(..unit.nal_unit_size as usize);
669 payload = payload.slice(unit.nal_unit_size as usize..);
670
671 units.push(unit);
672 }
673
674 if units.is_empty() {
676 return Err(Error::ErrShortPacket);
677 }
678
679 self.first_unit = Some(first_unit);
680 self.other_units = units;
681
682 Ok(())
683 }
684
685 pub fn first_unit(&self) -> Option<&H265AggregationUnitFirst> {
687 self.first_unit.as_ref()
688 }
689
690 pub fn other_units(&self) -> &[H265AggregationUnit] {
692 self.other_units.as_slice()
693 }
694}
695
696#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
705pub struct H265FragmentationUnitHeader(pub u8);
706
707impl H265FragmentationUnitHeader {
708 pub fn s(&self) -> bool {
710 const MASK: u8 = 0b10000000;
711 ((self.0 & MASK) >> 7) != 0
712 }
713
714 pub fn e(&self) -> bool {
716 const MASK: u8 = 0b01000000;
717 ((self.0 & MASK) >> 6) != 0
718 }
719
720 pub fn fu_type(&self) -> u8 {
722 const MASK: u8 = 0b00111111;
723 self.0 & MASK
724 }
725}
726
727#[derive(Default, Debug, Clone, PartialEq, Eq)]
748pub struct H265FragmentationUnitPacket {
749 payload_header: H265NALUHeader,
751 fu_header: H265FragmentationUnitHeader,
753 donl: Option<u16>,
755 payload: Bytes,
757
758 might_need_donl: bool,
759}
760
761impl H265FragmentationUnitPacket {
762 pub fn with_donl(&mut self, value: bool) {
765 self.might_need_donl = value;
766 }
767
768 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
770 const TOTAL_HEADER_SIZE: usize = H265NALU_HEADER_SIZE + H265FRAGMENTATION_UNIT_HEADER_SIZE;
771 if payload.len() <= TOTAL_HEADER_SIZE {
772 return Err(Error::ErrShortPacket);
773 }
774
775 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
776 if payload_header.f() {
777 return Err(Error::ErrH265CorruptedPacket);
778 }
779 if !payload_header.is_fragmentation_unit() {
780 return Err(Error::ErrInvalidH265PacketType);
781 }
782
783 let fu_header = H265FragmentationUnitHeader(payload[2]);
784 let mut payload = payload.slice(3..);
785
786 if fu_header.s() && self.might_need_donl {
787 if payload.len() <= 2 {
788 return Err(Error::ErrShortPacket);
789 }
790
791 let donl = ((payload[0] as u16) << 8) | (payload[1] as u16);
792 self.donl = Some(donl);
793 payload = payload.slice(2..);
794 }
795
796 self.payload_header = payload_header;
797 self.fu_header = fu_header;
798 self.payload = payload;
799
800 Ok(())
801 }
802
803 pub fn payload_header(&self) -> H265NALUHeader {
805 self.payload_header
806 }
807
808 pub fn fu_header(&self) -> H265FragmentationUnitHeader {
810 self.fu_header
811 }
812
813 pub fn donl(&self) -> Option<u16> {
815 self.donl
816 }
817
818 pub fn payload(&self) -> Bytes {
820 self.payload.clone()
821 }
822}
823
824#[derive(Default, Debug, Clone, PartialEq, Eq)]
850pub struct H265PACIPacket {
851 payload_header: H265NALUHeader,
853
854 paci_header_fields: u16,
856
857 phes: Bytes,
859
860 payload: Bytes,
862}
863
864impl H265PACIPacket {
865 pub fn payload_header(&self) -> H265NALUHeader {
867 self.payload_header
868 }
869
870 pub fn a(&self) -> bool {
872 const MASK: u16 = 0b10000000 << 8;
873 (self.paci_header_fields & MASK) != 0
874 }
875
876 pub fn ctype(&self) -> u8 {
878 const MASK: u16 = 0b01111110 << 8;
879 ((self.paci_header_fields & MASK) >> (8 + 1)) as u8
880 }
881
882 pub fn phs_size(&self) -> u8 {
884 const MASK: u16 = (0b00000001 << 8) | 0b11110000;
885 ((self.paci_header_fields & MASK) >> 4) as u8
886 }
887
888 pub fn f0(&self) -> bool {
890 const MASK: u16 = 0b00001000;
891 (self.paci_header_fields & MASK) != 0
892 }
893
894 pub fn f1(&self) -> bool {
896 const MASK: u16 = 0b00000100;
897 (self.paci_header_fields & MASK) != 0
898 }
899
900 pub fn f2(&self) -> bool {
902 const MASK: u16 = 0b00000010;
903 (self.paci_header_fields & MASK) != 0
904 }
905
906 pub fn y(&self) -> bool {
908 const MASK: u16 = 0b00000001;
909 (self.paci_header_fields & MASK) != 0
910 }
911
912 pub fn phes(&self) -> Bytes {
914 self.phes.clone()
915 }
916
917 pub fn payload(&self) -> Bytes {
919 self.payload.clone()
920 }
921
922 pub fn tsci(&self) -> Option<H265TSCI> {
924 if !self.f0() || self.phs_size() < 3 {
925 return None;
926 }
927
928 Some(H265TSCI(
929 ((self.phes[0] as u32) << 16) | ((self.phes[1] as u32) << 8) | self.phes[0] as u32,
930 ))
931 }
932
933 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
935 const TOTAL_HEADER_SIZE: usize = H265NALU_HEADER_SIZE + 2;
936 if payload.len() <= TOTAL_HEADER_SIZE {
937 return Err(Error::ErrShortPacket);
938 }
939
940 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
941 if payload_header.f() {
942 return Err(Error::ErrH265CorruptedPacket);
943 }
944 if !payload_header.is_paci_packet() {
945 return Err(Error::ErrInvalidH265PacketType);
946 }
947
948 let paci_header_fields = ((payload[2] as u16) << 8) | (payload[3] as u16);
949 let mut payload = payload.slice(4..);
950
951 self.paci_header_fields = paci_header_fields;
952 let header_extension_size = self.phs_size();
953
954 if payload.len() < header_extension_size as usize + 1 {
955 self.paci_header_fields = 0;
956 return Err(Error::ErrShortPacket);
957 }
958
959 self.payload_header = payload_header;
960
961 if header_extension_size > 0 {
962 self.phes = payload.slice(..header_extension_size as usize);
963 }
964
965 payload = payload.slice(header_extension_size as usize..);
966 self.payload = payload;
967
968 Ok(())
969 }
970}
971
972#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
983pub struct H265TSCI(pub u32);
984
985impl H265TSCI {
986 pub fn tl0picidx(&self) -> u8 {
988 const M1: u32 = 0xFFFF0000;
989 const M2: u32 = 0xFF00;
990 ((((self.0 & M1) >> 16) & M2) >> 8) as u8
991 }
992
993 pub fn irap_pic_id(&self) -> u8 {
995 const M1: u32 = 0xFFFF0000;
996 const M2: u32 = 0x00FF;
997 (((self.0 & M1) >> 16) & M2) as u8
998 }
999
1000 pub fn s(&self) -> bool {
1002 const M1: u32 = 0xFF00;
1003 const M2: u32 = 0b10000000;
1004 (((self.0 & M1) >> 8) & M2) != 0
1005 }
1006
1007 pub fn e(&self) -> bool {
1009 const M1: u32 = 0xFF00;
1010 const M2: u32 = 0b01000000;
1011 (((self.0 & M1) >> 8) & M2) != 0
1012 }
1013
1014 pub fn res(&self) -> u8 {
1016 const M1: u32 = 0xFF00;
1017 const M2: u32 = 0b00111111;
1018 (((self.0 & M1) >> 8) & M2) as u8
1019 }
1020}
1021
1022#[derive(Debug, Clone, PartialEq, Eq)]
1026pub enum H265Payload {
1027 H265SingleNALUnitPacket(H265SingleNALUnitPacket),
1029 H265FragmentationUnitPacket(H265FragmentationUnitPacket),
1031 H265AggregationPacket(H265AggregationPacket),
1033 H265PACIPacket(H265PACIPacket),
1035}
1036
1037impl Default for H265Payload {
1038 fn default() -> Self {
1039 H265Payload::H265SingleNALUnitPacket(H265SingleNALUnitPacket::default())
1040 }
1041}
1042
1043#[derive(Default, Debug, Clone, PartialEq, Eq)]
1048pub struct H265Packet {
1049 payload: H265Payload,
1050 might_need_donl: bool,
1051}
1052
1053impl H265Packet {
1054 pub fn with_donl(&mut self, value: bool) {
1057 self.might_need_donl = value;
1058 }
1059
1060 pub fn payload(&self) -> &H265Payload {
1067 &self.payload
1068 }
1069}
1070
1071impl Depacketizer for H265Packet {
1072 fn depacketize(&mut self, payload: &Bytes) -> Result<Bytes> {
1074 if payload.len() <= H265NALU_HEADER_SIZE {
1075 return Err(Error::ErrShortPacket);
1076 }
1077
1078 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
1079 if payload_header.f() {
1080 return Err(Error::ErrH265CorruptedPacket);
1081 }
1082
1083 if payload_header.is_paci_packet() {
1084 let mut decoded = H265PACIPacket::default();
1085 decoded.depacketize(payload)?;
1086
1087 self.payload = H265Payload::H265PACIPacket(decoded);
1088 } else if payload_header.is_fragmentation_unit() {
1089 let mut decoded = H265FragmentationUnitPacket::default();
1090 decoded.with_donl(self.might_need_donl);
1091
1092 decoded.depacketize(payload)?;
1093
1094 self.payload = H265Payload::H265FragmentationUnitPacket(decoded);
1095 } else if payload_header.is_aggregation_packet() {
1096 let mut decoded = H265AggregationPacket::default();
1097 decoded.with_donl(self.might_need_donl);
1098
1099 decoded.depacketize(payload)?;
1100
1101 self.payload = H265Payload::H265AggregationPacket(decoded);
1102 } else {
1103 let mut decoded = H265SingleNALUnitPacket::default();
1104 decoded.with_donl(self.might_need_donl);
1105
1106 decoded.depacketize(payload)?;
1107
1108 self.payload = H265Payload::H265SingleNALUnitPacket(decoded);
1109 }
1110
1111 Ok(payload.clone())
1112 }
1113
1114 fn is_partition_head(&self, _payload: &Bytes) -> bool {
1116 true
1118 }
1119
1120 fn is_partition_tail(&self, marker: bool, _payload: &Bytes) -> bool {
1121 marker
1122 }
1123}