]> git.nihav.org Git - nihav.git/blame - nihav-itu/src/codecs/h264/sets.rs
h264: update test hashes after the changes
[nihav.git] / nihav-itu / src / codecs / h264 / sets.rs
CommitLineData
696e4e20
KS
1use nihav_core::codecs::{DecoderResult, DecoderError};
2use nihav_core::io::bitreader::*;
3
4use super::ReadUE;
5
6#[derive(Clone)]
7pub struct SeqParameterSet {
8 pub profile_idc: u8,
9 pub high_profile: bool,
10 pub constraint_set0: bool,
11 pub constraint_set1: bool,
12 pub constraint_set2: bool,
13 pub level_idc: u8,
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,
44}
45
46pub fn is_high_profile(profile: u8) -> bool {
47 match profile {
48 100 | 110 | 122 | 244 | 44 | 83 | 86 | 118 | 128 | 138 | 139 | 134 | 125 => true,
49 _ => false,
50 }
51}
52
b7c882c1 53#[allow(clippy::cognitive_complexity)]
696e4e20
KS
54pub 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() };
57
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);
67 if sps.high_profile {
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()?;
71 }
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()?;
80 if slist_present[i] {
81 parse_scaling_list(&mut br, slist, i < 3)?;
82 }
83 }
84 for i in 1..6 {
85 if i == 3 {
86 continue;
87 }
88 if !slist_present[i] {
89 sps.scaling_list_4x4[i] = sps.scaling_list_4x4[i - 1];
90 }
91 }
92
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()?;
97 if slist_present[i] {
98 parse_scaling_list(&mut br, slist, (i & 1) == 0)?;
99 }
100 }
101 if num_8x8 > 2 {
102 for i in 2..6 {
103 if !slist_present[i] {
104 sps.scaling_list_8x8[i] = sps.scaling_list_8x8[i - 2];
105 }
106 }
107 }
108 } else {
109 sps.scaling_list_4x4 = [[16; 16]; 6];
110 sps.scaling_list_8x8 = [[16; 64]; 6];
111 }
112 } else {
113 sps.chroma_format_idc = 1;
114 sps.bit_depth_luma = 8;
115 sps.bit_depth_chroma = 8;
116 }
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 {
120 0 => {
121 sps.log2_max_pic_order_cnt_lsb = (br.read_ue_lim(12)? + 4) as u8;
122 },
123 1 => {
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()?;
130 }
131 },
132 _ => {},
133 };
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()?;
143 }
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);
156 }
157 sps.vui_parameters_present = br.read_bool()?;
158 if sps.vui_parameters_present {
159 // xxx: vui is ignored for now
160 if br.read_bool()? {
161 let idc = br.read(8)?;
162 if idc == 255 {
163 br.read(16)?;
164 br.read(16)?;
165 }
166 }
167 if br.read_bool()? {
168 br.read_bool()?;
169 }
170 if br.read_bool()? {
171 br.read(3)?;
172 br.read_bool()?;
173 if br.read_bool()? {
174 br.read(8)?;
175 br.read(8)?;
176 br.read(8)?;
177 }
178 }
179 if br.read_bool()? {
180 br.read_ue()?;
181 br.read_ue()?;
182 }
183 if br.read_bool()? {
184 br.read(32)?;
185 br.read(32)?;
186 br.read_bool()?;
187 }
188 let nal_hrd_parameters_present = br.read_bool()?;
189 if nal_hrd_parameters_present {
190 skip_hrd_parameters(&mut br)?;
191 }
192 let vcl_hrd_parameters_present = br.read_bool()?;
193 if vcl_hrd_parameters_present {
194 skip_hrd_parameters(&mut br)?;
195 }
196 if nal_hrd_parameters_present || vcl_hrd_parameters_present {
197 br.read_bool()?;
198 }
199 br.read_bool()?;
200 if br.read_bool()? {
201 br.read_bool()?;
202 br.read_ue()?;
203 br.read_ue()?;
204 br.read_ue()?;
205 br.read_ue()?;
206 br.read_ue()?;
207 br.read_ue()?;
208 }
209 }
210
211 Ok(sps)
212}
213
214fn 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
217 ];
218 const DEFAULT_INTER_4X4: [u8; 16] = [
219 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34
220 ];
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
226 ];
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
232 ];
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() {
237 if next_scale != 0 {
238 let delta = br.read_se()?;
239 next_scale = last_scale.wrapping_add(delta as u8);
240 if (j == 0) && (next_scale == 0) {
241 use_default = true;
242 break;
243 }
244 }
245 *elem = if next_scale == 0 { last_scale } else { next_scale };
246 last_scale = *elem;
247 }
248 if use_default {
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),
254 _ => unreachable!(),
255 };
256 }
257 Ok(())
258}
259
260fn skip_hrd_parameters(br: &mut BitReader) -> DecoderResult<()> {
261 let cpb_cnt = br.read_ue()? as usize + 1;
262 br.read(4)?;
263 br.read(4)?;
264 for _ in 0..cpb_cnt {
265 br.read_ue()?;
266 br.read_ue()?;
267 br.read_bool()?;
268 }
269 br.read(5)?;
270 br.read(5)?;
271 br.read(5)?;
272 br.read(5)?;
273 Ok(())
274}
275
276const MAX_SLICE_GROUPS: usize = 8;
277
278#[derive(Clone)]
279pub 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,
296 pub pic_init_qp: u8,
297 pub pic_init_qs: 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,
307}
308
309pub 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() };
312
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 {
319 found = true;
320 cur_sps = Some(sps);
321 break;
322 }
323 }
324 validate!(found);
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 {
335 0 => {
336 for elem in pps.run_length[..pps.num_slice_groups].iter_mut() {
337 *elem = br.read_ue()?;
338 }
339 },
340 2 => {
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()?;
344 }
345 },
346 3 | 4 | 5 => {
347 pps.slice_group_change_direction = br.read_bool()?;
348 pps.slice_group_change_rate = br.read_ue()?;
349 },
350 6 => {
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()?;
354 }
355 },
356 _ => {},
357 };
358println!("slice mode!");
359 return Err(DecoderError::NotImplemented);
360 }
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)?;
386 }
387 }
388 for i in 1..6 {
389 if i == 3 {
390 continue;
391 }
392 if !slist_present[i] {
393 pps.scaling_list_4x4[i] = pps.scaling_list_4x4[i - 1];
394 }
395 }
396
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)?;
403 }
404 }
405 if num_8x8 > 2 {
406 for i in 2..6 {
407 if !slist_present[i] {
408 pps.scaling_list_8x8[i] = pps.scaling_list_8x8[i - 2];
409 }
410 }
411 }
412 } else {
413 pps.scaling_list_4x4 = sps.scaling_list_4x4;
414 pps.scaling_list_8x8 = sps.scaling_list_8x8;
415 }
416 let off = br.read_se()?;
417 validate!(off >= -12 && off <= 12);
418 pps.second_chroma_qp_index_offset = off as i8;
419 } else {
420 pps.second_chroma_qp_index_offset = pps.chroma_qp_index_offset;
421 }
422
423 Ok(pps)
424}