mpeg2ts_reader/descriptor/
avcvideo.rs1use super::DescriptorError;
5use crate::descriptor::descriptor_len;
6use std::fmt;
7
8pub struct AvcVideoDescriptor<'buf> {
10 buf: &'buf [u8],
11}
12impl<'buf> AvcVideoDescriptor<'buf> {
13 pub const TAG: u8 = 40;
15 pub fn new(tag: u8, buf: &'buf [u8]) -> Result<AvcVideoDescriptor<'buf>, DescriptorError> {
18 assert_eq!(tag, Self::TAG);
19 descriptor_len(buf, tag, 4)?;
20 Ok(AvcVideoDescriptor { buf })
21 }
22
23 pub fn profile_idc(&self) -> u8 {
25 self.buf[0]
26 }
27 pub fn constraint_set0_flag(&self) -> bool {
29 self.buf[1] & 0b1000_0000 != 0
30 }
31 pub fn constraint_set1_flag(&self) -> bool {
33 self.buf[1] & 0b0100_0000 != 0
34 }
35 pub fn constraint_set2_flag(&self) -> bool {
37 self.buf[1] & 0b0010_0000 != 0
38 }
39 pub fn constraint_set3_flag(&self) -> bool {
41 self.buf[1] & 0b0001_0000 != 0
42 }
43 pub fn constraint_set4_flag(&self) -> bool {
45 self.buf[1] & 0b0000_1000 != 0
46 }
47 pub fn constraint_set5_flag(&self) -> bool {
49 self.buf[1] & 0b0000_0100 != 0
50 }
51 pub fn avc_compatible_flags(&self) -> u8 {
53 self.buf[1] & 0b0000_0011
54 }
55 pub fn level_idc(&self) -> u8 {
57 self.buf[2]
58 }
59 pub fn avc_still_present(&self) -> bool {
61 self.buf[3] & 0b1000_0000 != 0
62 }
63 pub fn avc_24_hour_picture_flag(&self) -> bool {
65 self.buf[3] & 0b0100_0000 != 0
66 }
67 pub fn frame_packing_sei_not_present_flag(&self) -> bool {
70 self.buf[3] & 0b0010_0000 != 0
71 }
72}
73
74impl fmt::Debug for AvcVideoDescriptor<'_> {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
76 f.debug_struct("AvcVideoDescriptor")
77 .field("profile_idc", &self.profile_idc())
78 .field("constraint_set0_flag", &self.constraint_set0_flag())
79 .field("constraint_set1_flag", &self.constraint_set1_flag())
80 .field("constraint_set2_flag", &self.constraint_set2_flag())
81 .field("constraint_set3_flag", &self.constraint_set3_flag())
82 .field("constraint_set4_flag", &self.constraint_set4_flag())
83 .field("constraint_set5_flag", &self.constraint_set5_flag())
84 .field("avc_compatible_flags", &self.avc_compatible_flags())
85 .field("level_idc", &self.level_idc())
86 .field("avc_still_present", &self.avc_still_present())
87 .field("avc_24_hour_picture_flag", &self.avc_24_hour_picture_flag())
88 .field(
89 "frame_packing_sei_not_present_flag",
90 &self.frame_packing_sei_not_present_flag(),
91 )
92 .finish()
93 }
94}
95
96#[cfg(test)]
97mod test {
98 use super::super::{CoreDescriptors, Descriptor};
99 use assert_matches::assert_matches;
100 use hex_literal::*;
101
102 #[test]
103 fn descriptor() {
104 let data = hex!("280442c01e3f");
105 let desc = CoreDescriptors::from_bytes(&data[..]).unwrap();
106 assert_matches!(desc, CoreDescriptors::AvcVideo(avc_video) => {
107 assert_eq!(avc_video.level_idc(), 30);
108 assert_eq!(avc_video.constraint_set0_flag(), true);
109 assert_eq!(avc_video.constraint_set1_flag(), true);
110 assert_eq!(avc_video.constraint_set3_flag(), false);
111 assert_eq!(avc_video.constraint_set4_flag(), false);
112 assert_eq!(avc_video.constraint_set5_flag(), false);
113 assert_eq!(avc_video.avc_compatible_flags(), 0);
114 assert_eq!(avc_video.profile_idc(), 66);
115 assert_eq!(avc_video.avc_still_present(), false);
116 assert_eq!(avc_video.avc_24_hour_picture_flag(), false);
117 assert_eq!(avc_video.frame_packing_sei_not_present_flag(), true);
118 })
119 }
120
121 #[test]
122 fn debug() {
123 let data = hex!("280442c01e3f");
124 let desc = CoreDescriptors::from_bytes(&data[..]).unwrap();
125 assert_matches!(desc, CoreDescriptors::AvcVideo(avc_video) => {
126 assert!(!format!("{:?}", avc_video).is_empty());
127 });
128 }
129}