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 {
48 100 | 110 | 122 | 244 | 44 | 83 | 86 | 118 | 128 | 138 | 139 | 134 | 125 => true,
53 #[allow(clippy::cognitive_complexity)]
54 pub fn parse_sps(src: &[u8]) -> DecoderResult<SeqParameterSet> {
55 let mut br = BitReader::new(src, BitReaderMode::BE);
56 let mut sps: SeqParameterSet = unsafe { std::mem::zeroed() };
58 sps.profile_idc = br.read(8)? as u8;
59 sps.constraint_set0 = br.read_bool()?;
60 sps.constraint_set1 = br.read_bool()?;
61 sps.constraint_set2 = br.read_bool()?;
62 let reserved = br.read(5)?;
63 validate!(reserved == 0);
64 sps.level_idc = br.read(8)? as u8;
65 sps.seq_parameter_set_id = br.read_ue()?;
66 sps.high_profile = is_high_profile(sps.profile_idc);
68 sps.chroma_format_idc = br.read_ue_lim(3)? as u8;
69 if sps.chroma_format_idc == 3 {
70 sps.separate_colour_plane = br.read_bool()?;
72 sps.bit_depth_luma = br.read_ue_lim(6)? as u8 + 8;
73 sps.bit_depth_chroma = br.read_ue_lim(6)? as u8 + 8;
74 sps.qpprime_y_zero_transform_bypass = br.read_bool()?;
75 sps.seq_scaling_matrix_present = br.read_bool()?;
76 if sps.seq_scaling_matrix_present {
77 let mut slist_present = [false; 6];
78 for (i, slist) in sps.scaling_list_4x4.iter_mut().enumerate() {
79 slist_present[i] = br.read_bool()?;
81 parse_scaling_list(&mut br, slist, i < 3)?;
88 if !slist_present[i] {
89 sps.scaling_list_4x4[i] = sps.scaling_list_4x4[i - 1];
93 let mut slist_present = [false; 6];
94 let num_8x8 = if sps.chroma_format_idc != 3 { 2 } else { 6 };
95 for (i, slist) in sps.scaling_list_8x8.iter_mut().take(num_8x8).enumerate() {
96 slist_present[i] = br.read_bool()?;
98 parse_scaling_list(&mut br, slist, (i & 1) == 0)?;
103 if !slist_present[i] {
104 sps.scaling_list_8x8[i] = sps.scaling_list_8x8[i - 2];
109 sps.scaling_list_4x4 = [[16; 16]; 6];
110 sps.scaling_list_8x8 = [[16; 64]; 6];
113 sps.chroma_format_idc = 1;
114 sps.bit_depth_luma = 8;
115 sps.bit_depth_chroma = 8;
117 sps.log2_max_frame_num = (br.read_ue_lim(12)? + 4) as u8;
118 sps.pic_order_cnt_type = br.read_ue_lim(2)? as u8;
119 match sps.pic_order_cnt_type {
121 sps.log2_max_pic_order_cnt_lsb = (br.read_ue_lim(12)? + 4) as u8;
124 sps.delta_pic_order_always_zero = br.read_bool()?;
125 sps.offset_for_non_ref_pic = br.read_se()?;
126 sps.offset_for_top_to_bottom_field = br.read_se()?;
127 sps.num_ref_frames_in_pic_order_cnt_cycle = br.read_ue_lim(255)? as usize;
128 for offset in sps.offset_for_ref_frame[..sps.num_ref_frames_in_pic_order_cnt_cycle].iter_mut() {
129 *offset = br.read_se()?;
134 sps.num_ref_frames = br.read_ue()? as usize;
135 validate!(sps.num_ref_frames <= super::slice::MAX_FRAMES);
136 sps.gaps_in_frame_num_value_allowed = br.read_bool()?;
137 sps.pic_width_in_mbs = (br.read_ue()? + 1) as usize;
138 sps.pic_height_in_mbs = (br.read_ue()? + 1) as usize;
139 validate!(sps.pic_width_in_mbs <= 1024 && sps.pic_height_in_mbs <= 1024);
140 sps.frame_mbs_only = br.read_bool()?;
141 if !sps.frame_mbs_only {
142 sps.mb_adaptive_frame_field = br.read_bool()?;
144 sps.direct_8x8_inference = br.read_bool()?;
145 sps.frame_cropping = br.read_bool()?;
146 if sps.frame_cropping {
147 sps.frame_crop_left_offset = br.read_ue()? as usize;
148 sps.frame_crop_right_offset = br.read_ue()? as usize;
149 sps.frame_crop_top_offset = br.read_ue()? as usize;
150 sps.frame_crop_bottom_offset = br.read_ue()? as usize;
151 let l = sps.frame_crop_left_offset * 2;
152 let r = sps.pic_width_in_mbs * 16 - sps.frame_crop_right_offset * 2;
153 let t = sps.frame_crop_top_offset * 2;
154 let d = sps.pic_height_in_mbs * 16 - sps.frame_crop_bottom_offset * 2;
155 validate!(l < r && t < d);
157 sps.vui_parameters_present = br.read_bool()?;
158 if sps.vui_parameters_present {
159 // xxx: vui is ignored for now
161 let idc = br.read(8)?;
188 let nal_hrd_parameters_present = br.read_bool()?;
189 if nal_hrd_parameters_present {
190 skip_hrd_parameters(&mut br)?;
192 let vcl_hrd_parameters_present = br.read_bool()?;
193 if vcl_hrd_parameters_present {
194 skip_hrd_parameters(&mut br)?;
196 if nal_hrd_parameters_present || vcl_hrd_parameters_present {
214 fn parse_scaling_list(br: &mut BitReader, slist: &mut[u8], is_intra: bool) -> DecoderResult<()> {
215 const DEFAULT_INTRA_4X4: [u8; 16] = [
216 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42
218 const DEFAULT_INTER_4X4: [u8; 16] = [
219 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34
221 const DEFAULT_INTRA_8X8: [u8; 64] = [
222 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
223 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
224 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
225 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42
227 const DEFAULT_INTER_8X8: [u8; 64] = [
228 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
229 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
230 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
231 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35
233 let mut last_scale = 8u8;
234 let mut next_scale = 8u8;
235 let mut use_default = false;
236 for (j, elem) in slist.iter_mut().enumerate() {
238 let delta = br.read_se()?;
239 next_scale = last_scale.wrapping_add(delta as u8);
240 if (j == 0) && (next_scale == 0) {
245 *elem = if next_scale == 0 { last_scale } else { next_scale };
249 match (slist.len(), is_intra) {
250 (16, true) => slist.copy_from_slice(&DEFAULT_INTRA_4X4),
251 (16, false) => slist.copy_from_slice(&DEFAULT_INTER_4X4),
252 (64, true) => slist.copy_from_slice(&DEFAULT_INTRA_8X8),
253 (64, false) => slist.copy_from_slice(&DEFAULT_INTER_8X8),
260 fn skip_hrd_parameters(br: &mut BitReader) -> DecoderResult<()> {
261 let cpb_cnt = br.read_ue()? as usize + 1;
264 for _ in 0..cpb_cnt {
276 const MAX_SLICE_GROUPS: usize = 8;
279 pub struct PicParameterSet {
280 pub pic_parameter_set_id: u32,
281 pub seq_parameter_set_id: u32,
282 pub entropy_coding_mode: bool,
283 pub pic_order_present: bool,
284 pub num_slice_groups: usize,
285 pub slice_group_map_type: u8,
286 pub run_length: [u32; MAX_SLICE_GROUPS],
287 pub top_left: [u32; MAX_SLICE_GROUPS],
288 pub bottom_right: [u32; MAX_SLICE_GROUPS],
289 pub slice_group_change_direction: bool,
290 pub slice_group_change_rate: u32,
291 pub pic_size_in_map_units: u32,
292 pub num_ref_idx_l0_active: usize,
293 pub num_ref_idx_l1_active: usize,
294 pub weighted_pred: bool,
295 pub weighted_bipred_idc: u8,
298 pub chroma_qp_index_offset: i8,
299 pub deblocking_filter_control_present: bool,
300 pub constrained_intra_pred: bool,
301 pub redundant_pic_cnt_present: bool,
302 pub transform_8x8_mode: bool,
303 pub pic_scaling_matrix_present: bool,
304 pub scaling_list_4x4: [[u8; 16]; 6],
305 pub scaling_list_8x8: [[u8; 64]; 6],
306 pub second_chroma_qp_index_offset: i8,
309 pub fn parse_pps(src: &[u8], sps_arr: &[SeqParameterSet], full_size: usize) -> DecoderResult<PicParameterSet> {
310 let mut br = BitReader::new(src, BitReaderMode::BE);
311 let mut pps: PicParameterSet = unsafe { std::mem::zeroed() };
313 pps.pic_parameter_set_id = br.read_ue()?;
314 pps.seq_parameter_set_id = br.read_ue()?;
315 let mut found = false;
316 let mut cur_sps = None;
317 for sps in sps_arr.iter() {
318 if sps.seq_parameter_set_id == pps.seq_parameter_set_id {
325 let sps = cur_sps.unwrap();
326 pps.entropy_coding_mode = br.read_bool()?;
327 pps.pic_order_present = br.read_bool()?;
328 pps.num_slice_groups = (br.read_ue()? + 1) as usize;
329 validate!(pps.num_slice_groups <= MAX_SLICE_GROUPS);
330 if pps.num_slice_groups > 1 {
331 let smtype = br.read_ue()?;
332 validate!(smtype <= 6);
333 pps.slice_group_map_type = smtype as u8;
334 match pps.slice_group_map_type {
336 for elem in pps.run_length[..pps.num_slice_groups].iter_mut() {
337 *elem = br.read_ue()?;
341 for i in 0..pps.num_slice_groups - 1 {
342 pps.top_left[i] = br.read_ue()?;
343 pps.bottom_right[i] = br.read_ue()?;
347 pps.slice_group_change_direction = br.read_bool()?;
348 pps.slice_group_change_rate = br.read_ue()?;
351 pps.pic_size_in_map_units = br.read_ue()? + 1;
352 for _ in 0..pps.pic_size_in_map_units {
353 let _slice_group_id = br.read_ue()?;
358 println!("slice mode!");
359 return Err(DecoderError::NotImplemented);
361 pps.num_ref_idx_l0_active = (br.read_ue()? + 1) as usize;
362 pps.num_ref_idx_l1_active = (br.read_ue()? + 1) as usize;
363 pps.weighted_pred = br.read_bool()?;
364 pps.weighted_bipred_idc = br.read(2)? as u8;
365 let qp = br.read_se()? + 26;
366 validate!(qp > 0 && qp < 52);
367 pps.pic_init_qp = qp as u8;
368 let qs = br.read_se()? + 26;
369 validate!(qs > 0 && qs < 52);
370 pps.pic_init_qs = qs as u8;
371 let off = br.read_se()?;
372 validate!(off >= -12 && off <= 12);
373 pps.chroma_qp_index_offset = off as i8;
374 pps.deblocking_filter_control_present = br.read_bool()?;
375 pps.constrained_intra_pred = br.read_bool()?;
376 pps.redundant_pic_cnt_present = br.read_bool()?;
377 if br.tell() < full_size {
378 pps.transform_8x8_mode = br.read_bool()?;
379 pps.pic_scaling_matrix_present = br.read_bool()?;
380 if pps.pic_scaling_matrix_present {
381 let mut slist_present = [false; 6];
382 for (i, slist) in pps.scaling_list_4x4.iter_mut().enumerate() {
383 slist_present[i] = br.read_bool()?;
384 if slist_present[i] {
385 parse_scaling_list(&mut br, slist, i < 3)?;
392 if !slist_present[i] {
393 pps.scaling_list_4x4[i] = pps.scaling_list_4x4[i - 1];
397 let mut slist_present = [false; 6];
398 let num_8x8 = if !pps.transform_8x8_mode { 0 } else if sps.chroma_format_idc != 3 { 2 } else { 6 };
399 for (i, slist) in pps.scaling_list_8x8.iter_mut().take(num_8x8).enumerate() {
400 slist_present[i] = br.read_bool()?;
401 if slist_present[i] {
402 parse_scaling_list(&mut br, slist, (i & 1) == 0)?;
407 if !slist_present[i] {
408 pps.scaling_list_8x8[i] = pps.scaling_list_8x8[i - 2];
413 pps.scaling_list_4x4 = sps.scaling_list_4x4;
414 pps.scaling_list_8x8 = sps.scaling_list_8x8;
416 let off = br.read_se()?;
417 validate!(off >= -12 && off <= 12);
418 pps.second_chroma_qp_index_offset = off as i8;
420 pps.second_chroma_qp_index_offset = pps.chroma_qp_index_offset;