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)]
57#[non_exhaustive]
59pub enum UnitType {
60 VPS = 32,
62 SPS = 33,
64 PPS = 34,
66 CRA = 21,
68 SEI = 39,
70 IDR = 19,
72 PFR = 1,
74 BFR = 0,
76 IGNORE = -1,
78}
79impl UnitType {
80 pub fn for_id(id: u8) -> Result<UnitType> {
86 if id > 64 {
87 Err(Error::ErrUnhandledNaluType)
88 } else {
89 let t = match id {
90 32 => UnitType::VPS,
91 33 => UnitType::SPS,
92 34 => UnitType::PPS,
93 21 => UnitType::CRA,
94 39 => UnitType::SEI,
95 19 => UnitType::IDR,
96 1 => UnitType::PFR,
97 0 => UnitType::BFR,
98 _ => UnitType::IGNORE, };
100 Ok(t)
101 }
102 }
103}
104
105#[derive(Default, Debug, Clone)]
106pub struct HevcPayloader;
108
109impl HevcPayloader {
110 fn aggregation_payload_header(nalus: &[Bytes]) -> [u8; 2] {
111 let mut f = false;
112 let mut layer_id = u8::MAX;
113 let mut tid = u8::MAX;
114
115 for nalu in nalus {
116 let header = H265NALUHeader::new(nalu[0], nalu[1]);
117 f |= header.f();
118 layer_id = layer_id.min(header.layer_id());
119 tid = tid.min(header.tid());
120 }
121
122 let mut raw = (H265NALU_AGGREGATION_PACKET_TYPE as u16) << 9;
123 raw |= (layer_id as u16) << 3;
124 raw |= tid as u16;
125 if f {
126 raw |= 1 << 15;
127 }
128
129 raw.to_be_bytes()
130 }
131
132 fn fragmentation_payload_header(payload_header: H265NALUHeader) -> [u8; 2] {
133 let mut raw = (H265NALU_FRAGMENTATION_UNIT_TYPE as u16) << 9;
134 raw |= (payload_header.layer_id() as u16) << 3;
135 raw |= payload_header.tid() as u16;
136 if payload_header.f() {
137 raw |= 1 << 15;
138 }
139
140 raw.to_be_bytes()
141 }
142
143 fn fu_header(nalu_type: u8, is_first: bool, is_last: bool) -> u8 {
144 let mut header = nalu_type & 0b0011_1111;
145 if is_first {
146 header |= 0b1000_0000;
147 } else if is_last {
148 header |= 0b0100_0000;
149 }
150 header
151 }
152
153 pub fn parse(nalu: &Bytes) -> (Vec<usize>, usize) {
157 let finder = memchr::memmem::Finder::new(&ANNEXB_NALUSTART_CODE);
158 let nals = finder.find_iter(nalu).collect::<Vec<usize>>();
159 if nals.is_empty() {
160 let finder = memchr::memmem::Finder::new(&ANNEXB_3_NALUSTART_CODE);
161 return (finder.find_iter(nalu).collect::<Vec<usize>>(), 3);
162 }
163 (nals, 4)
164 }
165
166 fn flush_aggregation_buffer(nalus: &mut Vec<Bytes>, mtu: usize, payloads: &mut Vec<Bytes>) {
167 match nalus.len() {
168 0 => {}
169 1 => {
170 payloads.push(nalus.pop().expect("single buffered NAL exists"));
171 }
172 _ => {
173 let header = Self::aggregation_payload_header(nalus);
174 let mut aggr_nalu = BytesMut::with_capacity(
175 NAL_HEADER_SIZE + nalus.iter().map(|nalu| 2 + nalu.len()).sum::<usize>(),
176 );
177 aggr_nalu.extend_from_slice(&header);
178 for nalu in nalus.drain(..) {
179 aggr_nalu.extend_from_slice(&(nalu.len() as u16).to_be_bytes());
180 aggr_nalu.extend_from_slice(&nalu);
181 }
182 if aggr_nalu.len() <= mtu {
183 payloads.push(aggr_nalu.freeze());
184 }
185 }
186 }
187 }
188
189 fn emit(nalu: &Bytes, mtu: usize, payloads: &mut Vec<Bytes>) {
190 if nalu.is_empty() {
191 return;
192 }
193 let payload_header = H265NALUHeader::new(nalu[0], nalu[1]);
194 let payload_nalu_type = payload_header.nalu_type();
195
196 if payload_nalu_type >= H265NALU_AGGREGATION_PACKET_TYPE {
197 return;
198 }
199
200 if nalu.len() <= mtu {
202 payloads.push(nalu.clone());
203 return;
204 }
205 let max_fragment_size =
206 mtu as isize - NAL_HEADER_SIZE as isize - H265FRAGMENTATION_UNIT_HEADER_SIZE as isize;
207 let nalu_data = nalu;
208 let mut nalu_data_index = 2;
209 let nalu_data_length = nalu.len() as isize - nalu_data_index;
210 let mut nalu_data_remaining = nalu_data_length;
211 if std::cmp::min(max_fragment_size, nalu_data_remaining) <= 0 {
212 return;
213 }
214 while nalu_data_remaining > 0 {
215 let current_fragment_size = std::cmp::min(max_fragment_size, nalu_data_remaining);
216 let mut out = BytesMut::with_capacity(
217 NAL_HEADER_SIZE
218 + H265FRAGMENTATION_UNIT_HEADER_SIZE
219 + current_fragment_size as usize,
220 );
221 out.extend_from_slice(&Self::fragmentation_payload_header(payload_header));
222 let is_first = nalu_data_index == 2;
223 let is_last = nalu_data_remaining == current_fragment_size;
224 out.put_u8(Self::fu_header(payload_nalu_type, is_first, is_last));
225
226 out.extend_from_slice(
227 &nalu_data
228 [nalu_data_index as usize..(nalu_data_index + current_fragment_size) as usize],
229 );
230 payloads.push(out.freeze());
231
232 nalu_data_remaining -= current_fragment_size;
233 nalu_data_index += current_fragment_size;
234 }
235 }
236}
237
238impl Payloader for HevcPayloader {
239 fn payload(&mut self, mtu: usize, payload: &Bytes) -> Result<Vec<Bytes>> {
241 if payload.is_empty() || mtu == 0 {
242 return Ok(vec![]);
243 }
244
245 let mut payloads = vec![];
246 let mut aggregation_buffer = vec![];
247
248 let (nal_idxs, offset) = HevcPayloader::parse(payload);
249 if nal_idxs.is_empty() {
250 Self::emit(payload, mtu, &mut payloads);
251 return Ok(payloads);
252 }
253 let nal_len = nal_idxs.len();
254 for (i, start) in nal_idxs.iter().enumerate() {
255 let end = if (i + 1) < nal_len {
256 nal_idxs[i + 1]
257 } else {
258 payload.len()
259 };
260 let nalu = payload.slice((start + offset)..end);
261 if nalu.len() < NAL_HEADER_SIZE {
262 continue;
263 }
264
265 let payload_header = H265NALUHeader::new(nalu[0], nalu[1]);
266 if payload_header.is_aggregation_packet()
267 || payload_header.is_fragmentation_unit()
268 || payload_header.is_paci_packet()
269 {
270 continue;
271 }
272
273 if nalu.len() > mtu {
274 Self::flush_aggregation_buffer(&mut aggregation_buffer, mtu, &mut payloads);
275 Self::emit(&nalu, mtu, &mut payloads);
276 continue;
277 }
278
279 let aggregated_size = NAL_HEADER_SIZE
280 + aggregation_buffer
281 .iter()
282 .map(|nalu| 2 + nalu.len())
283 .sum::<usize>()
284 + 2
285 + nalu.len();
286 if !aggregation_buffer.is_empty() && aggregated_size > mtu {
287 Self::flush_aggregation_buffer(&mut aggregation_buffer, mtu, &mut payloads);
288 }
289
290 aggregation_buffer.push(nalu);
291 }
292 Self::flush_aggregation_buffer(&mut aggregation_buffer, mtu, &mut payloads);
293
294 Ok(payloads)
295 }
296
297 fn clone_to(&self) -> Box<dyn Payloader> {
298 Box::new(self.clone())
299 }
300}
301
302const H265NALU_HEADER_SIZE: usize = 2;
306const H265NALU_AGGREGATION_PACKET_TYPE: u8 = 48;
308const H265NALU_FRAGMENTATION_UNIT_TYPE: u8 = 49;
310const H265NALU_PACI_PACKET_TYPE: u8 = 50;
312
313#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
329pub struct H265NALUHeader(pub u16);
330
331impl H265NALUHeader {
332 pub fn new(high_byte: u8, low_byte: u8) -> Self {
334 H265NALUHeader(((high_byte as u16) << 8) | low_byte as u16)
335 }
336
337 pub fn f(&self) -> bool {
339 (self.0 >> 15) != 0
340 }
341
342 pub fn nalu_type(&self) -> u8 {
344 const MASK: u16 = 0b01111110 << 8;
346 ((self.0 & MASK) >> (8 + 1)) as u8
347 }
348
349 pub fn is_type_vcl_unit(&self) -> bool {
351 const MSB_MASK: u8 = 0b00100000;
353 (self.nalu_type() & MSB_MASK) == 0
354 }
355
356 pub fn layer_id(&self) -> u8 {
358 const MASK: u16 = (0b00000001 << 8) | 0b11111000;
360 ((self.0 & MASK) >> 3) as u8
361 }
362
363 pub fn tid(&self) -> u8 {
365 const MASK: u16 = 0b00000111;
366 (self.0 & MASK) as u8
367 }
368
369 pub fn is_aggregation_packet(&self) -> bool {
371 self.nalu_type() == H265NALU_AGGREGATION_PACKET_TYPE
372 }
373
374 pub fn is_fragmentation_unit(&self) -> bool {
376 self.nalu_type() == H265NALU_FRAGMENTATION_UNIT_TYPE
377 }
378
379 pub fn is_paci_packet(&self) -> bool {
381 self.nalu_type() == H265NALU_PACI_PACKET_TYPE
382 }
383}
384
385#[derive(Default, Debug, Clone, PartialEq, Eq)]
407pub struct H265SingleNALUnitPacket {
408 payload_header: H265NALUHeader,
410 donl: Option<u16>,
412 payload: Bytes,
414
415 might_need_donl: bool,
416}
417
418impl H265SingleNALUnitPacket {
419 pub fn with_donl(&mut self, value: bool) {
422 self.might_need_donl = value;
423 }
424
425 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
427 if payload.len() <= H265NALU_HEADER_SIZE {
428 return Err(Error::ErrShortPacket);
429 }
430
431 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
432 if payload_header.f() {
433 return Err(Error::ErrH265CorruptedPacket);
434 }
435 if payload_header.is_fragmentation_unit()
436 || payload_header.is_paci_packet()
437 || payload_header.is_aggregation_packet()
438 {
439 return Err(Error::ErrInvalidH265PacketType);
440 }
441
442 let mut payload = payload.slice(2..);
443
444 if self.might_need_donl {
445 if payload.len() <= 2 {
447 return Err(Error::ErrShortPacket);
448 }
449
450 let donl = ((payload[0] as u16) << 8) | (payload[1] as u16);
451 self.donl = Some(donl);
452 payload = payload.slice(2..);
453 }
454
455 self.payload_header = payload_header;
456 self.payload = payload;
457
458 Ok(())
459 }
460
461 pub fn payload_header(&self) -> H265NALUHeader {
463 self.payload_header
464 }
465
466 pub fn donl(&self) -> Option<u16> {
468 self.donl
469 }
470
471 pub fn payload(&self) -> Bytes {
473 self.payload.clone()
474 }
475}
476
477#[derive(Default, Debug, Clone, PartialEq, Eq)]
500pub struct H265AggregationUnitFirst {
501 donl: Option<u16>,
502 nal_unit_size: u16,
503 nal_unit: Bytes,
504}
505
506impl H265AggregationUnitFirst {
507 pub fn donl(&self) -> Option<u16> {
511 self.donl
512 }
513
514 pub fn nalu_size(&self) -> u16 {
516 self.nal_unit_size
517 }
518
519 pub fn nal_unit(&self) -> Bytes {
521 self.nal_unit.clone()
522 }
523}
524
525#[derive(Default, Debug, Clone, PartialEq, Eq)]
544pub struct H265AggregationUnit {
545 dond: Option<u8>,
546 nal_unit_size: u16,
547 nal_unit: Bytes,
548}
549
550impl H265AggregationUnit {
551 pub fn dond(&self) -> Option<u8> {
555 self.dond
556 }
557
558 pub fn nalu_size(&self) -> u16 {
560 self.nal_unit_size
561 }
562
563 pub fn nal_unit(&self) -> Bytes {
565 self.nal_unit.clone()
566 }
567}
568
569#[derive(Default, Debug, Clone, PartialEq, Eq)]
588pub struct H265AggregationPacket {
589 first_unit: Option<H265AggregationUnitFirst>,
590 other_units: Vec<H265AggregationUnit>,
591
592 might_need_donl: bool,
593}
594
595impl H265AggregationPacket {
596 pub fn with_donl(&mut self, value: bool) {
599 self.might_need_donl = value;
600 }
601
602 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
604 if payload.len() <= H265NALU_HEADER_SIZE {
605 return Err(Error::ErrShortPacket);
606 }
607
608 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
609 if payload_header.f() {
610 return Err(Error::ErrH265CorruptedPacket);
611 }
612 if !payload_header.is_aggregation_packet() {
613 return Err(Error::ErrInvalidH265PacketType);
614 }
615
616 let mut payload = payload.slice(2..);
618 let mut first_unit = H265AggregationUnitFirst::default();
619
620 if self.might_need_donl {
621 if payload.len() < 2 {
622 return Err(Error::ErrShortPacket);
623 }
624
625 let donl = ((payload[0] as u16) << 8) | (payload[1] as u16);
626 first_unit.donl = Some(donl);
627
628 payload = payload.slice(2..);
629 }
630 if payload.len() < 2 {
631 return Err(Error::ErrShortPacket);
632 }
633 first_unit.nal_unit_size = ((payload[0] as u16) << 8) | (payload[1] as u16);
634 payload = payload.slice(2..);
635
636 if payload.len() < first_unit.nal_unit_size as usize {
637 return Err(Error::ErrShortPacket);
638 }
639
640 first_unit.nal_unit = payload.slice(..first_unit.nal_unit_size as usize);
641 payload = payload.slice(first_unit.nal_unit_size as usize..);
642
643 let mut units = vec![]; loop {
646 let mut unit = H265AggregationUnit::default();
647
648 if self.might_need_donl {
649 if payload.is_empty() {
650 break;
651 }
652
653 let dond = payload[0];
654 unit.dond = Some(dond);
655
656 payload = payload.slice(1..);
657 }
658
659 if payload.len() < 2 {
660 break;
661 }
662 unit.nal_unit_size = ((payload[0] as u16) << 8) | (payload[1] as u16);
663 payload = payload.slice(2..);
664
665 if payload.len() < unit.nal_unit_size as usize {
666 break;
667 }
668
669 unit.nal_unit = payload.slice(..unit.nal_unit_size as usize);
670 payload = payload.slice(unit.nal_unit_size as usize..);
671
672 units.push(unit);
673 }
674
675 if units.is_empty() {
677 return Err(Error::ErrShortPacket);
678 }
679
680 self.first_unit = Some(first_unit);
681 self.other_units = units;
682
683 Ok(())
684 }
685
686 pub fn first_unit(&self) -> Option<&H265AggregationUnitFirst> {
688 self.first_unit.as_ref()
689 }
690
691 pub fn other_units(&self) -> &[H265AggregationUnit] {
693 self.other_units.as_slice()
694 }
695}
696
697#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
706pub struct H265FragmentationUnitHeader(pub u8);
707
708impl H265FragmentationUnitHeader {
709 pub fn s(&self) -> bool {
711 const MASK: u8 = 0b10000000;
712 ((self.0 & MASK) >> 7) != 0
713 }
714
715 pub fn e(&self) -> bool {
717 const MASK: u8 = 0b01000000;
718 ((self.0 & MASK) >> 6) != 0
719 }
720
721 pub fn fu_type(&self) -> u8 {
723 const MASK: u8 = 0b00111111;
724 self.0 & MASK
725 }
726}
727
728#[derive(Default, Debug, Clone, PartialEq, Eq)]
749pub struct H265FragmentationUnitPacket {
750 payload_header: H265NALUHeader,
752 fu_header: H265FragmentationUnitHeader,
754 donl: Option<u16>,
756 payload: Bytes,
758
759 might_need_donl: bool,
760}
761
762impl H265FragmentationUnitPacket {
763 pub fn with_donl(&mut self, value: bool) {
766 self.might_need_donl = value;
767 }
768
769 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
771 const TOTAL_HEADER_SIZE: usize = H265NALU_HEADER_SIZE + H265FRAGMENTATION_UNIT_HEADER_SIZE;
772 if payload.len() <= TOTAL_HEADER_SIZE {
773 return Err(Error::ErrShortPacket);
774 }
775
776 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
777 if payload_header.f() {
778 return Err(Error::ErrH265CorruptedPacket);
779 }
780 if !payload_header.is_fragmentation_unit() {
781 return Err(Error::ErrInvalidH265PacketType);
782 }
783
784 let fu_header = H265FragmentationUnitHeader(payload[2]);
785 let mut payload = payload.slice(3..);
786
787 if fu_header.s() && self.might_need_donl {
788 if payload.len() <= 2 {
789 return Err(Error::ErrShortPacket);
790 }
791
792 let donl = ((payload[0] as u16) << 8) | (payload[1] as u16);
793 self.donl = Some(donl);
794 payload = payload.slice(2..);
795 }
796
797 self.payload_header = payload_header;
798 self.fu_header = fu_header;
799 self.payload = payload;
800
801 Ok(())
802 }
803
804 pub fn payload_header(&self) -> H265NALUHeader {
806 self.payload_header
807 }
808
809 pub fn fu_header(&self) -> H265FragmentationUnitHeader {
811 self.fu_header
812 }
813
814 pub fn donl(&self) -> Option<u16> {
816 self.donl
817 }
818
819 pub fn payload(&self) -> Bytes {
821 self.payload.clone()
822 }
823}
824
825#[derive(Default, Debug, Clone, PartialEq, Eq)]
851pub struct H265PACIPacket {
852 payload_header: H265NALUHeader,
854
855 paci_header_fields: u16,
857
858 phes: Bytes,
860
861 payload: Bytes,
863}
864
865impl H265PACIPacket {
866 pub fn payload_header(&self) -> H265NALUHeader {
868 self.payload_header
869 }
870
871 pub fn a(&self) -> bool {
873 const MASK: u16 = 0b10000000 << 8;
874 (self.paci_header_fields & MASK) != 0
875 }
876
877 pub fn ctype(&self) -> u8 {
879 const MASK: u16 = 0b01111110 << 8;
880 ((self.paci_header_fields & MASK) >> (8 + 1)) as u8
881 }
882
883 pub fn phs_size(&self) -> u8 {
885 const MASK: u16 = (0b00000001 << 8) | 0b11110000;
886 ((self.paci_header_fields & MASK) >> 4) as u8
887 }
888
889 pub fn f0(&self) -> bool {
891 const MASK: u16 = 0b00001000;
892 (self.paci_header_fields & MASK) != 0
893 }
894
895 pub fn f1(&self) -> bool {
897 const MASK: u16 = 0b00000100;
898 (self.paci_header_fields & MASK) != 0
899 }
900
901 pub fn f2(&self) -> bool {
903 const MASK: u16 = 0b00000010;
904 (self.paci_header_fields & MASK) != 0
905 }
906
907 pub fn y(&self) -> bool {
909 const MASK: u16 = 0b00000001;
910 (self.paci_header_fields & MASK) != 0
911 }
912
913 pub fn phes(&self) -> Bytes {
915 self.phes.clone()
916 }
917
918 pub fn payload(&self) -> Bytes {
920 self.payload.clone()
921 }
922
923 pub fn tsci(&self) -> Option<H265TSCI> {
925 if !self.f0() || self.phs_size() < 3 {
926 return None;
927 }
928
929 Some(H265TSCI(
930 ((self.phes[0] as u32) << 16) | ((self.phes[1] as u32) << 8) | self.phes[0] as u32,
931 ))
932 }
933
934 fn depacketize(&mut self, payload: &Bytes) -> Result<()> {
936 const TOTAL_HEADER_SIZE: usize = H265NALU_HEADER_SIZE + 2;
937 if payload.len() <= TOTAL_HEADER_SIZE {
938 return Err(Error::ErrShortPacket);
939 }
940
941 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
942 if payload_header.f() {
943 return Err(Error::ErrH265CorruptedPacket);
944 }
945 if !payload_header.is_paci_packet() {
946 return Err(Error::ErrInvalidH265PacketType);
947 }
948
949 let paci_header_fields = ((payload[2] as u16) << 8) | (payload[3] as u16);
950 let mut payload = payload.slice(4..);
951
952 self.paci_header_fields = paci_header_fields;
953 let header_extension_size = self.phs_size();
954
955 if payload.len() < header_extension_size as usize + 1 {
956 self.paci_header_fields = 0;
957 return Err(Error::ErrShortPacket);
958 }
959
960 self.payload_header = payload_header;
961
962 if header_extension_size > 0 {
963 self.phes = payload.slice(..header_extension_size as usize);
964 }
965
966 payload = payload.slice(header_extension_size as usize..);
967 self.payload = payload;
968
969 Ok(())
970 }
971}
972
973#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
984pub struct H265TSCI(pub u32);
985
986impl H265TSCI {
987 pub fn tl0picidx(&self) -> u8 {
989 const M1: u32 = 0xFFFF0000;
990 const M2: u32 = 0xFF00;
991 ((((self.0 & M1) >> 16) & M2) >> 8) as u8
992 }
993
994 pub fn irap_pic_id(&self) -> u8 {
996 const M1: u32 = 0xFFFF0000;
997 const M2: u32 = 0x00FF;
998 (((self.0 & M1) >> 16) & M2) as u8
999 }
1000
1001 pub fn s(&self) -> bool {
1003 const M1: u32 = 0xFF00;
1004 const M2: u32 = 0b10000000;
1005 (((self.0 & M1) >> 8) & M2) != 0
1006 }
1007
1008 pub fn e(&self) -> bool {
1010 const M1: u32 = 0xFF00;
1011 const M2: u32 = 0b01000000;
1012 (((self.0 & M1) >> 8) & M2) != 0
1013 }
1014
1015 pub fn res(&self) -> u8 {
1017 const M1: u32 = 0xFF00;
1018 const M2: u32 = 0b00111111;
1019 (((self.0 & M1) >> 8) & M2) as u8
1020 }
1021}
1022
1023#[derive(Debug, Clone, PartialEq, Eq)]
1027#[non_exhaustive]
1028pub enum H265Payload {
1029 H265SingleNALUnitPacket(H265SingleNALUnitPacket),
1031 H265FragmentationUnitPacket(H265FragmentationUnitPacket),
1033 H265AggregationPacket(H265AggregationPacket),
1035 H265PACIPacket(H265PACIPacket),
1037}
1038
1039impl Default for H265Payload {
1040 fn default() -> Self {
1041 H265Payload::H265SingleNALUnitPacket(H265SingleNALUnitPacket::default())
1042 }
1043}
1044
1045#[derive(Default, Debug, Clone, PartialEq, Eq)]
1050pub struct H265Packet {
1051 payload: H265Payload,
1052 might_need_donl: bool,
1053}
1054
1055impl H265Packet {
1056 pub fn with_donl(&mut self, value: bool) {
1059 self.might_need_donl = value;
1060 }
1061
1062 pub fn payload(&self) -> &H265Payload {
1069 &self.payload
1070 }
1071}
1072
1073impl Depacketizer for H265Packet {
1074 fn depacketize(&mut self, payload: &Bytes) -> Result<Bytes> {
1076 if payload.len() <= H265NALU_HEADER_SIZE {
1077 return Err(Error::ErrShortPacket);
1078 }
1079
1080 let payload_header = H265NALUHeader::new(payload[0], payload[1]);
1081 if payload_header.f() {
1082 return Err(Error::ErrH265CorruptedPacket);
1083 }
1084
1085 if payload_header.is_paci_packet() {
1086 let mut decoded = H265PACIPacket::default();
1087 decoded.depacketize(payload)?;
1088
1089 self.payload = H265Payload::H265PACIPacket(decoded);
1090 } else if payload_header.is_fragmentation_unit() {
1091 let mut decoded = H265FragmentationUnitPacket::default();
1092 decoded.with_donl(self.might_need_donl);
1093
1094 decoded.depacketize(payload)?;
1095
1096 self.payload = H265Payload::H265FragmentationUnitPacket(decoded);
1097 } else if payload_header.is_aggregation_packet() {
1098 let mut decoded = H265AggregationPacket::default();
1099 decoded.with_donl(self.might_need_donl);
1100
1101 decoded.depacketize(payload)?;
1102
1103 self.payload = H265Payload::H265AggregationPacket(decoded);
1104 } else {
1105 let mut decoded = H265SingleNALUnitPacket::default();
1106 decoded.with_donl(self.might_need_donl);
1107
1108 decoded.depacketize(payload)?;
1109
1110 self.payload = H265Payload::H265SingleNALUnitPacket(decoded);
1111 }
1112
1113 Ok(payload.clone())
1114 }
1115
1116 fn is_partition_head(&self, _payload: &Bytes) -> bool {
1118 true
1120 }
1121
1122 fn is_partition_tail(&self, marker: bool, _payload: &Bytes) -> bool {
1123 marker
1124 }
1125}