1 use nihav_core::codecs::{DecoderResult, DecoderError};
2 use nihav_core::io::bitreader::*;
7 pub struct SeqParameterSet {
9 pub high_profile: bool,
10 pub constraint_set0: bool,
11 pub constraint_set1: bool,
12 pub constraint_set2: bool,
14 pub seq_parameter_set_id: u32,
15 pub chroma_format_idc: u8,
16 pub separate_colour_plane: bool,
17 pub bit_depth_luma: u8,
18 pub bit_depth_chroma: u8,
19 pub qpprime_y_zero_transform_bypass: bool,
20 pub seq_scaling_matrix_present: bool,
21 pub scaling_list_4x4: [[u8; 16]; 6],
22 pub scaling_list_8x8: [[u8; 64]; 6],
23 pub log2_max_frame_num: u8,
24 pub pic_order_cnt_type: u8,
25 pub log2_max_pic_order_cnt_lsb: u8,
26 pub delta_pic_order_always_zero: bool,
27 pub offset_for_non_ref_pic: i32,
28 pub offset_for_top_to_bottom_field: i32,
29 pub num_ref_frames_in_pic_order_cnt_cycle: usize,
30 pub offset_for_ref_frame: [i32; 256],
31 pub num_ref_frames: usize,
32 pub gaps_in_frame_num_value_allowed: bool,
33 pub pic_width_in_mbs: usize,
34 pub pic_height_in_mbs: usize,
35 pub frame_mbs_only: bool,
36 pub mb_adaptive_frame_field: bool,
37 pub direct_8x8_inference: bool,
38 pub frame_cropping: bool,
39 pub frame_crop_left_offset: usize,
40 pub frame_crop_right_offset: usize,
41 pub frame_crop_top_offset: usize,
42 pub frame_crop_bottom_offset: usize,
43 pub vui_parameters_present: bool,
46 pub fn is_high_profile(profile: u8) -> bool {
47 matches!(profile, 100 | 110 | 122 | 244 | 44 | 83 | 86 | 118 | 128 | 138 | 139 | 134 | 125)
50 #[allow(clippy::cognitive_complexity)]
51 pub fn parse_sps(src: &[u8]) -> DecoderResult<SeqParameterSet> {
52 let mut br = BitReader::new(src, BitReaderMode::BE);
53 let mut sps: SeqParameterSet = unsafe { std::mem::zeroed() };
55 sps.profile_idc = br.read(8)? as u8;
56 sps.constraint_set0 = br.read_bool()?;
57 sps.constraint_set1 = br.read_bool()?;
58 sps.constraint_set2 = br.read_bool()?;
59 let reserved = br.read(5)?;
60 validate!(reserved == 0);
61 sps.level_idc = br.read(8)? as u8;
62 sps.seq_parameter_set_id = br.read_ue()?;
63 sps.high_profile = is_high_profile(sps.profile_idc);
65 sps.chroma_format_idc = br.read_ue_lim(3)? as u8;
66 if sps.chroma_format_idc == 3 {
67 sps.separate_colour_plane = br.read_bool()?;
69 sps.bit_depth_luma = br.read_ue_lim(6)? as u8 + 8;
70 sps.bit_depth_chroma = br.read_ue_lim(6)? as u8 + 8;
71 sps.qpprime_y_zero_transform_bypass = br.read_bool()?;
72 sps.seq_scaling_matrix_present = br.read_bool()?;
73 if sps.seq_scaling_matrix_present {
74 let mut slist_present = [false; 6];
75 for (i, slist) in sps.scaling_list_4x4.iter_mut().enumerate() {
76 slist_present[i] = br.read_bool()?;
78 parse_scaling_list(&mut br, slist, i < 3)?;
85 if !slist_present[i] {
86 sps.scaling_list_4x4[i] = sps.scaling_list_4x4[i - 1];
90 let mut slist_present = [false; 6];
91 let num_8x8 = if sps.chroma_format_idc != 3 { 2 } else { 6 };
92 for (i, slist) in sps.scaling_list_8x8.iter_mut().take(num_8x8).enumerate() {
93 slist_present[i] = br.read_bool()?;
95 parse_scaling_list(&mut br, slist, (i & 1) == 0)?;
100 if !slist_present[i] {
101 sps.scaling_list_8x8[i] = sps.scaling_list_8x8[i - 2];
106 sps.scaling_list_4x4 = [[16; 16]; 6];
107 sps.scaling_list_8x8 = [[16; 64]; 6];
110 sps.chroma_format_idc = 1;
111 sps.bit_depth_luma = 8;
112 sps.bit_depth_chroma = 8;
114 sps.log2_max_frame_num = (br.read_ue_lim(12)? + 4) as u8;
115 sps.pic_order_cnt_type = br.read_ue_lim(2)? as u8;
116 match sps.pic_order_cnt_type {
118 sps.log2_max_pic_order_cnt_lsb = (br.read_ue_lim(12)? + 4) as u8;
121 sps.delta_pic_order_always_zero = br.read_bool()?;
122 sps.offset_for_non_ref_pic = br.read_se()?;
123 sps.offset_for_top_to_bottom_field = br.read_se()?;
124 sps.num_ref_frames_in_pic_order_cnt_cycle = br.read_ue_lim(255)? as usize;
125 for offset in sps.offset_for_ref_frame[..sps.num_ref_frames_in_pic_order_cnt_cycle].iter_mut() {
126 *offset = br.read_se()?;
131 sps.num_ref_frames = br.read_ue()? as usize;
132 validate!(sps.num_ref_frames <= super::slice::MAX_FRAMES);
133 sps.gaps_in_frame_num_value_allowed = br.read_bool()?;
134 sps.pic_width_in_mbs = (br.read_ue()? + 1) as usize;
135 sps.pic_height_in_mbs = (br.read_ue()? + 1) as usize;
136 validate!(sps.pic_width_in_mbs <= 1024 && sps.pic_height_in_mbs <= 1024);
137 sps.frame_mbs_only = br.read_bool()?;
138 if !sps.frame_mbs_only {
139 sps.mb_adaptive_frame_field = br.read_bool()?;
141 sps.direct_8x8_inference = br.read_bool()?;
142 sps.frame_cropping = br.read_bool()?;
143 if sps.frame_cropping {
144 sps.frame_crop_left_offset = br.read_ue()? as usize;
145 sps.frame_crop_right_offset = br.read_ue()? as usize;
146 sps.frame_crop_top_offset = br.read_ue()? as usize;
147 sps.frame_crop_bottom_offset = br.read_ue()? as usize;
148 let l = sps.frame_crop_left_offset * 2;
149 let r = sps.pic_width_in_mbs * 16 - sps.frame_crop_right_offset * 2;
150 let t = sps.frame_crop_top_offset * 2;
151 let d = sps.pic_height_in_mbs * 16 - sps.frame_crop_bottom_offset * 2;
152 validate!(l < r && t < d);
154 sps.vui_parameters_present = br.read_bool()?;
155 if sps.vui_parameters_present {
156 // xxx: vui is ignored for now
158 let idc = br.read(8)?;
185 let nal_hrd_parameters_present = br.read_bool()?;
186 if nal_hrd_parameters_present {
187 skip_hrd_parameters(&mut br)?;
189 let vcl_hrd_parameters_present = br.read_bool()?;
190 if vcl_hrd_parameters_present {
191 skip_hrd_parameters(&mut br)?;
193 if nal_hrd_parameters_present || vcl_hrd_parameters_present {
211 fn parse_scaling_list(br: &mut BitReader, slist: &mut[u8], is_intra: bool) -> DecoderResult<()> {
212 const DEFAULT_INTRA_4X4: [u8; 16] = [
213 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42
215 const DEFAULT_INTER_4X4: [u8; 16] = [
216 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34
218 const DEFAULT_INTRA_8X8: [u8; 64] = [
219 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
220 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
221 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
222 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42
224 const DEFAULT_INTER_8X8: [u8; 64] = [
225 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
226 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
227 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
228 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35
230 let mut last_scale = 8u8;
231 let mut next_scale = 8u8;
232 let mut use_default = false;
233 for (j, elem) in slist.iter_mut().enumerate() {
235 let delta = br.read_se()?;
236 next_scale = last_scale.wrapping_add(delta as u8);
237 if (j == 0) && (next_scale == 0) {
242 *elem = if next_scale == 0 { last_scale } else { next_scale };
246 match (slist.len(), is_intra) {
247 (16, true) => slist.copy_from_slice(&DEFAULT_INTRA_4X4),
248 (16, false) => slist.copy_from_slice(&DEFAULT_INTER_4X4),
249 (64, true) => slist.copy_from_slice(&DEFAULT_INTRA_8X8),
250 (64, false) => slist.copy_from_slice(&DEFAULT_INTER_8X8),
257 fn skip_hrd_parameters(br: &mut BitReader) -> DecoderResult<()> {
258 let cpb_cnt = br.read_ue()? as usize + 1;
261 for _ in 0..cpb_cnt {
273 const MAX_SLICE_GROUPS: usize = 8;
276 pub struct PicParameterSet {
277 pub pic_parameter_set_id: u32,
278 pub seq_parameter_set_id: u32,
279 pub entropy_coding_mode: bool,
280 pub pic_order_present: bool,
281 pub num_slice_groups: usize,
282 pub slice_group_map_type: u8,
283 pub run_length: [u32; MAX_SLICE_GROUPS],
284 pub top_left: [u32; MAX_SLICE_GROUPS],
285 pub bottom_right: [u32; MAX_SLICE_GROUPS],
286 pub slice_group_change_direction: bool,
287 pub slice_group_change_rate: u32,
288 pub pic_size_in_map_units: u32,
289 pub num_ref_idx_l0_active: usize,
290 pub num_ref_idx_l1_active: usize,
291 pub weighted_pred: bool,
292 pub weighted_bipred_idc: u8,
295 pub chroma_qp_index_offset: i8,
296 pub deblocking_filter_control_present: bool,
297 pub constrained_intra_pred: bool,
298 pub redundant_pic_cnt_present: bool,
299 pub transform_8x8_mode: bool,
300 pub pic_scaling_matrix_present: bool,
301 pub scaling_list_4x4: [[u8; 16]; 6],
302 pub scaling_list_8x8: [[u8; 64]; 6],
303 pub second_chroma_qp_index_offset: i8,
306 pub fn parse_pps(src: &[u8], sps_arr: &[SeqParameterSet], full_size: usize) -> DecoderResult<PicParameterSet> {
307 let mut br = BitReader::new(src, BitReaderMode::BE);
308 let mut pps: PicParameterSet = unsafe { std::mem::zeroed() };
310 pps.pic_parameter_set_id = br.read_ue()?;
311 pps.seq_parameter_set_id = br.read_ue()?;
312 let mut found = false;
313 let mut cur_sps = None;
314 for sps in sps_arr.iter() {
315 if sps.seq_parameter_set_id == pps.seq_parameter_set_id {
322 let sps = cur_sps.unwrap();
323 pps.entropy_coding_mode = br.read_bool()?;
324 pps.pic_order_present = br.read_bool()?;
325 pps.num_slice_groups = (br.read_ue()? + 1) as usize;
326 validate!(pps.num_slice_groups <= MAX_SLICE_GROUPS);
327 if pps.num_slice_groups > 1 {
328 let smtype = br.read_ue()?;
329 validate!(smtype <= 6);
330 pps.slice_group_map_type = smtype as u8;
331 match pps.slice_group_map_type {
333 for elem in pps.run_length[..pps.num_slice_groups].iter_mut() {
334 *elem = br.read_ue()?;
338 for i in 0..pps.num_slice_groups - 1 {
339 pps.top_left[i] = br.read_ue()?;
340 pps.bottom_right[i] = br.read_ue()?;
344 pps.slice_group_change_direction = br.read_bool()?;
345 pps.slice_group_change_rate = br.read_ue()?;
348 pps.pic_size_in_map_units = br.read_ue()? + 1;
349 for _ in 0..pps.pic_size_in_map_units {
350 let _slice_group_id = br.read_ue()?;
355 println!("slice mode!");
356 return Err(DecoderError::NotImplemented);
358 pps.num_ref_idx_l0_active = (br.read_ue()? + 1) as usize;
359 pps.num_ref_idx_l1_active = (br.read_ue()? + 1) as usize;
360 pps.weighted_pred = br.read_bool()?;
361 pps.weighted_bipred_idc = br.read(2)? as u8;
362 let qp = br.read_se()? + 26;
363 validate!(qp > 0 && qp < 52);
364 pps.pic_init_qp = qp as u8;
365 let qs = br.read_se()? + 26;
366 validate!(qs > 0 && qs < 52);
367 pps.pic_init_qs = qs as u8;
368 let off = br.read_se()?;
369 validate!(off >= -12 && off <= 12);
370 pps.chroma_qp_index_offset = off as i8;
371 pps.deblocking_filter_control_present = br.read_bool()?;
372 pps.constrained_intra_pred = br.read_bool()?;
373 pps.redundant_pic_cnt_present = br.read_bool()?;
374 if br.tell() < full_size {
375 pps.transform_8x8_mode = br.read_bool()?;
376 pps.pic_scaling_matrix_present = br.read_bool()?;
377 if pps.pic_scaling_matrix_present {
378 let mut slist_present = [false; 6];
379 for (i, slist) in pps.scaling_list_4x4.iter_mut().enumerate() {
380 slist_present[i] = br.read_bool()?;
381 if slist_present[i] {
382 parse_scaling_list(&mut br, slist, i < 3)?;
389 if !slist_present[i] {
390 pps.scaling_list_4x4[i] = pps.scaling_list_4x4[i - 1];
394 let mut slist_present = [false; 6];
395 let num_8x8 = if !pps.transform_8x8_mode { 0 } else if sps.chroma_format_idc != 3 { 2 } else { 6 };
396 for (i, slist) in pps.scaling_list_8x8.iter_mut().take(num_8x8).enumerate() {
397 slist_present[i] = br.read_bool()?;
398 if slist_present[i] {
399 parse_scaling_list(&mut br, slist, (i & 1) == 0)?;
404 if !slist_present[i] {
405 pps.scaling_list_8x8[i] = pps.scaling_list_8x8[i - 2];
410 pps.scaling_list_4x4 = sps.scaling_list_4x4;
411 pps.scaling_list_8x8 = sps.scaling_list_8x8;
413 let off = br.read_se()?;
414 validate!(off >= -12 && off <= 12);
415 pps.second_chroma_qp_index_offset = off as i8;
417 pps.second_chroma_qp_index_offset = pps.chroma_qp_index_offset;