xref: /xiu/library/codec/h264/src/sps.rs (revision 69de9bbd)
1 use {
2     super::errors::H264Error, super::utils, bytes::BytesMut, bytesio::bits_reader::BitsReader,
3     bytesio::bytes_reader::BytesReader, std::vec::Vec,
4 };
5 
6 #[derive(Default, Debug)]
7 pub struct Sps {
8     pub profile_idc: u8, // u(8)
9     flag: u8,
10 
11     pub level_idc: u8,         // u(8)
12     seq_parameter_set_id: u32, // ue(v)
13 
14     chroma_format_idc: u32, // ue(v)
15 
16     separate_colour_plane_flag: u8,           // u(1)
17     bit_depth_luma_minus8: u32,               // ue(v)
18     bit_depth_chroma_minus8: u32,             // ue(v)
19     qpprime_y_zero_transform_bypass_flag: u8, // u(1)
20 
21     seq_scaling_matrix_present_flag: u8, // u(1)
22 
23     seq_scaling_list_present_flag: Vec<u8>, // u(1)
24 
25     log2_max_frame_num_minus4: u32, // ue(v)
26     pic_order_cnt_type: u32,        // ue(v)
27 
28     log2_max_pic_order_cnt_lsb_minus4: u32, // ue(v)
29 
30     delta_pic_order_always_zero_flag: u8,       // u(1)
31     offset_for_non_ref_pic: i32,                // se(v)
32     offset_for_top_to_bottom_field: i32,        // se(v)
33     num_ref_frames_in_pic_order_cnt_cycle: u32, // ue(v)
34 
35     offset_for_ref_frame: Vec<i32>, // se(v)
36 
37     max_num_ref_frames: u32,                  // ue(v)
38     gaps_in_frame_num_value_allowed_flag: u8, // u(1)
39 
40     pic_width_in_mbs_minus1: u32,        // ue(v)
41     pic_height_in_map_units_minus1: u32, // ue(v)
42     frame_mbs_only_flag: u8,             // u(1)
43 
44     mb_adaptive_frame_field_flag: u8, // u(1)
45 
46     direct_8x8_inference_flag: u8, // u(1)
47 
48     frame_cropping_flag: u8, // u(1)
49 
50     frame_crop_left_offset: u32,   // ue(v)
51     frame_crop_right_offset: u32,  // ue(v)
52     frame_crop_top_offset: u32,    // ue(v)
53     frame_crop_bottom_offset: u32, // ue(v)
54 
55     vui_parameters_present_flag: u8, // u(1)
56 }
57 
58 pub struct SpsParser {
59     pub bytes_reader: BytesReader,
60     pub bits_reader: BitsReader,
61     pub sps: Sps,
62 }
63 
64 impl SpsParser {
new(reader: BytesReader) -> SpsParser65     pub fn new(reader: BytesReader) -> SpsParser {
66         Self {
67             bytes_reader: BytesReader::new(BytesMut::new()),
68             bits_reader: BitsReader::new(reader),
69             sps: Sps::default(),
70         }
71     }
72 
extend_data(&mut self, data: BytesMut)73     pub fn extend_data(&mut self, data: BytesMut) {
74         self.bits_reader.extend_data(data);
75     }
76 
parse(&mut self) -> Result<(u32, u32), H264Error>77     pub fn parse(&mut self) -> Result<(u32, u32), H264Error> {
78         self.sps.profile_idc = self.bits_reader.read_byte()?;
79         log::info!("profile_idc: {}", self.sps.profile_idc);
80         self.sps.flag = self.bits_reader.read_byte()?;
81         self.sps.level_idc = self.bits_reader.read_byte()?;
82         log::info!("level_idc: {}", self.sps.level_idc);
83         self.sps.seq_parameter_set_id = utils::read_uev(&mut self.bits_reader)?;
84 
85         match self.sps.profile_idc {
86             100 | 110 | 122 | 244 | 44 | 83 | 86 | 118 | 128 => {
87                 self.sps.chroma_format_idc = utils::read_uev(&mut self.bits_reader)?;
88                 if self.sps.chroma_format_idc == 3 {
89                     self.sps.separate_colour_plane_flag = self.bits_reader.read_bit()?;
90                 }
91                 self.sps.bit_depth_luma_minus8 = utils::read_uev(&mut self.bits_reader)?;
92                 self.sps.bit_depth_chroma_minus8 = utils::read_uev(&mut self.bits_reader)?;
93 
94                 self.sps.qpprime_y_zero_transform_bypass_flag = self.bits_reader.read_bit()?;
95                 self.sps.seq_scaling_matrix_present_flag = self.bits_reader.read_bit()?;
96 
97                 if self.sps.seq_scaling_matrix_present_flag > 0 {
98                     let matrix_dim: usize = if self.sps.chroma_format_idc != 2 {
99                         8
100                     } else {
101                         12
102                     };
103 
104                     for _ in 0..matrix_dim {
105                         self.sps
106                             .seq_scaling_list_present_flag
107                             .push(self.bits_reader.read_bit()?);
108                     }
109                 }
110             }
111             _ => {}
112         }
113 
114         self.sps.log2_max_frame_num_minus4 = utils::read_uev(&mut self.bits_reader)?;
115         self.sps.pic_order_cnt_type = utils::read_uev(&mut self.bits_reader)?;
116 
117         match self.sps.pic_order_cnt_type {
118             0 => {
119                 self.sps.log2_max_pic_order_cnt_lsb_minus4 =
120                     utils::read_uev(&mut self.bits_reader)?;
121             }
122             1 => {
123                 self.sps.delta_pic_order_always_zero_flag = self.bits_reader.read_bit()?;
124                 self.sps.offset_for_non_ref_pic = utils::read_sev(&mut self.bits_reader)?;
125                 self.sps.offset_for_top_to_bottom_field = utils::read_sev(&mut self.bits_reader)?;
126                 self.sps.num_ref_frames_in_pic_order_cnt_cycle =
127                     utils::read_uev(&mut self.bits_reader)?;
128 
129                 for i in 0..self.sps.num_ref_frames_in_pic_order_cnt_cycle as usize {
130                     self.sps.offset_for_ref_frame[i] = utils::read_sev(&mut self.bits_reader)?;
131                 }
132             }
133             _ => {}
134         }
135 
136         self.sps.max_num_ref_frames = utils::read_uev(&mut self.bits_reader)?;
137         self.sps.gaps_in_frame_num_value_allowed_flag = self.bits_reader.read_bit()?;
138 
139         self.sps.pic_width_in_mbs_minus1 = utils::read_uev(&mut self.bits_reader)?;
140         self.sps.pic_height_in_map_units_minus1 = utils::read_uev(&mut self.bits_reader)?;
141 
142         self.sps.frame_mbs_only_flag = self.bits_reader.read_bit()?;
143 
144         if self.sps.frame_mbs_only_flag == 0 {
145             self.sps.mb_adaptive_frame_field_flag = self.bits_reader.read_bit()?;
146         }
147         self.sps.direct_8x8_inference_flag = self.bits_reader.read_bit()?;
148         self.sps.frame_cropping_flag = self.bits_reader.read_bit()?;
149 
150         if self.sps.frame_cropping_flag > 0 {
151             self.sps.frame_crop_left_offset = utils::read_uev(&mut self.bits_reader)?;
152             self.sps.frame_crop_right_offset = utils::read_uev(&mut self.bits_reader)?;
153             self.sps.frame_crop_top_offset = utils::read_uev(&mut self.bits_reader)?;
154             self.sps.frame_crop_bottom_offset = utils::read_uev(&mut self.bits_reader)?;
155         }
156 
157         self.sps.vui_parameters_present_flag = self.bits_reader.read_bit()?;
158 
159         let width = (self.sps.pic_width_in_mbs_minus1 + 1) * 16
160             - self.sps.frame_crop_left_offset * 2
161             - self.sps.frame_crop_right_offset * 2;
162         let height = ((2 - self.sps.frame_mbs_only_flag as u32)
163             * (self.sps.pic_height_in_map_units_minus1 + 1)
164             * 16)
165             - (self.sps.frame_crop_top_offset * 2)
166             - (self.sps.frame_crop_bottom_offset * 2);
167 
168         log::trace!("parsed sps data: {:?}", self.sps);
169         Ok((width, height))
170     }
171 }
172