h264_decoder/
sps.rs

1use {
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)]
7pub 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
58pub struct SpsParser {
59    pub bytes_reader: BytesReader,
60    pub bits_reader: BitsReader,
61    pub sps: Sps,
62}
63
64impl SpsParser {
65    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
73    pub fn extend_data(&mut self, data: BytesMut) {
74        self.bits_reader.extend_data(data);
75    }
76
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}