mostly working ITU H.264 decoder
[nihav.git] / nihav-itu / src / codecs / h264 / sets.rs
1 use nihav_core::codecs::{DecoderResult, DecoderError};
2 use nihav_core::io::bitreader::*;
3
4 use super::ReadUE;
5
6 #[derive(Clone)]
7 pub 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
46 pub 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
53 pub fn parse_sps(src: &[u8]) -> DecoderResult<SeqParameterSet> {
54 let mut br = BitReader::new(src, BitReaderMode::BE);
55 let mut sps: SeqParameterSet = unsafe { std::mem::zeroed() };
56
57 sps.profile_idc = br.read(8)? as u8;
58 sps.constraint_set0 = br.read_bool()?;
59 sps.constraint_set1 = br.read_bool()?;
60 sps.constraint_set2 = br.read_bool()?;
61 let reserved = br.read(5)?;
62 validate!(reserved == 0);
63 sps.level_idc = br.read(8)? as u8;
64 sps.seq_parameter_set_id = br.read_ue()?;
65 sps.high_profile = is_high_profile(sps.profile_idc);
66 if sps.high_profile {
67 sps.chroma_format_idc = br.read_ue_lim(3)? as u8;
68 if sps.chroma_format_idc == 3 {
69 sps.separate_colour_plane = br.read_bool()?;
70 }
71 sps.bit_depth_luma = br.read_ue_lim(6)? as u8 + 8;
72 sps.bit_depth_chroma = br.read_ue_lim(6)? as u8 + 8;
73 sps.qpprime_y_zero_transform_bypass = br.read_bool()?;
74 sps.seq_scaling_matrix_present = br.read_bool()?;
75 if sps.seq_scaling_matrix_present {
76 let mut slist_present = [false; 6];
77 for (i, slist) in sps.scaling_list_4x4.iter_mut().enumerate() {
78 slist_present[i] = br.read_bool()?;
79 if slist_present[i] {
80 parse_scaling_list(&mut br, slist, i < 3)?;
81 }
82 }
83 for i in 1..6 {
84 if i == 3 {
85 continue;
86 }
87 if !slist_present[i] {
88 sps.scaling_list_4x4[i] = sps.scaling_list_4x4[i - 1];
89 }
90 }
91
92 let mut slist_present = [false; 6];
93 let num_8x8 = if sps.chroma_format_idc != 3 { 2 } else { 6 };
94 for (i, slist) in sps.scaling_list_8x8.iter_mut().take(num_8x8).enumerate() {
95 slist_present[i] = br.read_bool()?;
96 if slist_present[i] {
97 parse_scaling_list(&mut br, slist, (i & 1) == 0)?;
98 }
99 }
100 if num_8x8 > 2 {
101 for i in 2..6 {
102 if !slist_present[i] {
103 sps.scaling_list_8x8[i] = sps.scaling_list_8x8[i - 2];
104 }
105 }
106 }
107 } else {
108 sps.scaling_list_4x4 = [[16; 16]; 6];
109 sps.scaling_list_8x8 = [[16; 64]; 6];
110 }
111 } else {
112 sps.chroma_format_idc = 1;
113 sps.bit_depth_luma = 8;
114 sps.bit_depth_chroma = 8;
115 }
116 sps.log2_max_frame_num = (br.read_ue_lim(12)? + 4) as u8;
117 sps.pic_order_cnt_type = br.read_ue_lim(2)? as u8;
118 match sps.pic_order_cnt_type {
119 0 => {
120 sps.log2_max_pic_order_cnt_lsb = (br.read_ue_lim(12)? + 4) as u8;
121 },
122 1 => {
123 sps.delta_pic_order_always_zero = br.read_bool()?;
124 sps.offset_for_non_ref_pic = br.read_se()?;
125 sps.offset_for_top_to_bottom_field = br.read_se()?;
126 sps.num_ref_frames_in_pic_order_cnt_cycle = br.read_ue_lim(255)? as usize;
127 for offset in sps.offset_for_ref_frame[..sps.num_ref_frames_in_pic_order_cnt_cycle].iter_mut() {
128 *offset = br.read_se()?;
129 }
130 },
131 _ => {},
132 };
133 sps.num_ref_frames = br.read_ue()? as usize;
134 validate!(sps.num_ref_frames <= super::slice::MAX_FRAMES);
135 sps.gaps_in_frame_num_value_allowed = br.read_bool()?;
136 sps.pic_width_in_mbs = (br.read_ue()? + 1) as usize;
137 sps.pic_height_in_mbs = (br.read_ue()? + 1) as usize;
138 validate!(sps.pic_width_in_mbs <= 1024 && sps.pic_height_in_mbs <= 1024);
139 sps.frame_mbs_only = br.read_bool()?;
140 if !sps.frame_mbs_only {
141 sps.mb_adaptive_frame_field = br.read_bool()?;
142 }
143 sps.direct_8x8_inference = br.read_bool()?;
144 sps.frame_cropping = br.read_bool()?;
145 if sps.frame_cropping {
146 sps.frame_crop_left_offset = br.read_ue()? as usize;
147 sps.frame_crop_right_offset = br.read_ue()? as usize;
148 sps.frame_crop_top_offset = br.read_ue()? as usize;
149 sps.frame_crop_bottom_offset = br.read_ue()? as usize;
150 let l = sps.frame_crop_left_offset * 2;
151 let r = sps.pic_width_in_mbs * 16 - sps.frame_crop_right_offset * 2;
152 let t = sps.frame_crop_top_offset * 2;
153 let d = sps.pic_height_in_mbs * 16 - sps.frame_crop_bottom_offset * 2;
154 validate!(l < r && t < d);
155 }
156 sps.vui_parameters_present = br.read_bool()?;
157 if sps.vui_parameters_present {
158 // xxx: vui is ignored for now
159 if br.read_bool()? {
160 let idc = br.read(8)?;
161 if idc == 255 {
162 br.read(16)?;
163 br.read(16)?;
164 }
165 }
166 if br.read_bool()? {
167 br.read_bool()?;
168 }
169 if br.read_bool()? {
170 br.read(3)?;
171 br.read_bool()?;
172 if br.read_bool()? {
173 br.read(8)?;
174 br.read(8)?;
175 br.read(8)?;
176 }
177 }
178 if br.read_bool()? {
179 br.read_ue()?;
180 br.read_ue()?;
181 }
182 if br.read_bool()? {
183 br.read(32)?;
184 br.read(32)?;
185 br.read_bool()?;
186 }
187 let nal_hrd_parameters_present = br.read_bool()?;
188 if nal_hrd_parameters_present {
189 skip_hrd_parameters(&mut br)?;
190 }
191 let vcl_hrd_parameters_present = br.read_bool()?;
192 if vcl_hrd_parameters_present {
193 skip_hrd_parameters(&mut br)?;
194 }
195 if nal_hrd_parameters_present || vcl_hrd_parameters_present {
196 br.read_bool()?;
197 }
198 br.read_bool()?;
199 if br.read_bool()? {
200 br.read_bool()?;
201 br.read_ue()?;
202 br.read_ue()?;
203 br.read_ue()?;
204 br.read_ue()?;
205 br.read_ue()?;
206 br.read_ue()?;
207 }
208 }
209
210 Ok(sps)
211 }
212
213 fn parse_scaling_list(br: &mut BitReader, slist: &mut[u8], is_intra: bool) -> DecoderResult<()> {
214 const DEFAULT_INTRA_4X4: [u8; 16] = [
215 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42
216 ];
217 const DEFAULT_INTER_4X4: [u8; 16] = [
218 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34
219 ];
220 const DEFAULT_INTRA_8X8: [u8; 64] = [
221 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
222 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
223 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
224 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42
225 ];
226 const DEFAULT_INTER_8X8: [u8; 64] = [
227 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
228 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
229 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
230 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35
231 ];
232 let mut last_scale = 8u8;
233 let mut next_scale = 8u8;
234 let mut use_default = false;
235 for (j, elem) in slist.iter_mut().enumerate() {
236 if next_scale != 0 {
237 let delta = br.read_se()?;
238 next_scale = last_scale.wrapping_add(delta as u8);
239 if (j == 0) && (next_scale == 0) {
240 use_default = true;
241 break;
242 }
243 }
244 *elem = if next_scale == 0 { last_scale } else { next_scale };
245 last_scale = *elem;
246 }
247 if use_default {
248 match (slist.len(), is_intra) {
249 (16, true) => slist.copy_from_slice(&DEFAULT_INTRA_4X4),
250 (16, false) => slist.copy_from_slice(&DEFAULT_INTER_4X4),
251 (64, true) => slist.copy_from_slice(&DEFAULT_INTRA_8X8),
252 (64, false) => slist.copy_from_slice(&DEFAULT_INTER_8X8),
253 _ => unreachable!(),
254 };
255 }
256 Ok(())
257 }
258
259 fn skip_hrd_parameters(br: &mut BitReader) -> DecoderResult<()> {
260 let cpb_cnt = br.read_ue()? as usize + 1;
261 br.read(4)?;
262 br.read(4)?;
263 for _ in 0..cpb_cnt {
264 br.read_ue()?;
265 br.read_ue()?;
266 br.read_bool()?;
267 }
268 br.read(5)?;
269 br.read(5)?;
270 br.read(5)?;
271 br.read(5)?;
272 Ok(())
273 }
274
275 const MAX_SLICE_GROUPS: usize = 8;
276
277 #[derive(Clone)]
278 pub struct PicParameterSet {
279 pub pic_parameter_set_id: u32,
280 pub seq_parameter_set_id: u32,
281 pub entropy_coding_mode: bool,
282 pub pic_order_present: bool,
283 pub num_slice_groups: usize,
284 pub slice_group_map_type: u8,
285 pub run_length: [u32; MAX_SLICE_GROUPS],
286 pub top_left: [u32; MAX_SLICE_GROUPS],
287 pub bottom_right: [u32; MAX_SLICE_GROUPS],
288 pub slice_group_change_direction: bool,
289 pub slice_group_change_rate: u32,
290 pub pic_size_in_map_units: u32,
291 pub num_ref_idx_l0_active: usize,
292 pub num_ref_idx_l1_active: usize,
293 pub weighted_pred: bool,
294 pub weighted_bipred_idc: u8,
295 pub pic_init_qp: u8,
296 pub pic_init_qs: u8,
297 pub chroma_qp_index_offset: i8,
298 pub deblocking_filter_control_present: bool,
299 pub constrained_intra_pred: bool,
300 pub redundant_pic_cnt_present: bool,
301 pub transform_8x8_mode: bool,
302 pub pic_scaling_matrix_present: bool,
303 pub scaling_list_4x4: [[u8; 16]; 6],
304 pub scaling_list_8x8: [[u8; 64]; 6],
305 pub second_chroma_qp_index_offset: i8,
306 }
307
308 pub fn parse_pps(src: &[u8], sps_arr: &[SeqParameterSet], full_size: usize) -> DecoderResult<PicParameterSet> {
309 let mut br = BitReader::new(src, BitReaderMode::BE);
310 let mut pps: PicParameterSet = unsafe { std::mem::zeroed() };
311
312 pps.pic_parameter_set_id = br.read_ue()?;
313 pps.seq_parameter_set_id = br.read_ue()?;
314 let mut found = false;
315 let mut cur_sps = None;
316 for sps in sps_arr.iter() {
317 if sps.seq_parameter_set_id == pps.seq_parameter_set_id {
318 found = true;
319 cur_sps = Some(sps);
320 break;
321 }
322 }
323 validate!(found);
324 let sps = cur_sps.unwrap();
325 pps.entropy_coding_mode = br.read_bool()?;
326 pps.pic_order_present = br.read_bool()?;
327 pps.num_slice_groups = (br.read_ue()? + 1) as usize;
328 validate!(pps.num_slice_groups <= MAX_SLICE_GROUPS);
329 if pps.num_slice_groups > 1 {
330 let smtype = br.read_ue()?;
331 validate!(smtype <= 6);
332 pps.slice_group_map_type = smtype as u8;
333 match pps.slice_group_map_type {
334 0 => {
335 for elem in pps.run_length[..pps.num_slice_groups].iter_mut() {
336 *elem = br.read_ue()?;
337 }
338 },
339 2 => {
340 for i in 0..pps.num_slice_groups - 1 {
341 pps.top_left[i] = br.read_ue()?;
342 pps.bottom_right[i] = br.read_ue()?;
343 }
344 },
345 3 | 4 | 5 => {
346 pps.slice_group_change_direction = br.read_bool()?;
347 pps.slice_group_change_rate = br.read_ue()?;
348 },
349 6 => {
350 pps.pic_size_in_map_units = br.read_ue()? + 1;
351 for _ in 0..pps.pic_size_in_map_units {
352 let _slice_group_id = br.read_ue()?;
353 }
354 },
355 _ => {},
356 };
357 println!("slice mode!");
358 return Err(DecoderError::NotImplemented);
359 }
360 pps.num_ref_idx_l0_active = (br.read_ue()? + 1) as usize;
361 pps.num_ref_idx_l1_active = (br.read_ue()? + 1) as usize;
362 pps.weighted_pred = br.read_bool()?;
363 pps.weighted_bipred_idc = br.read(2)? as u8;
364 let qp = br.read_se()? + 26;
365 validate!(qp > 0 && qp < 52);
366 pps.pic_init_qp = qp as u8;
367 let qs = br.read_se()? + 26;
368 validate!(qs > 0 && qs < 52);
369 pps.pic_init_qs = qs as u8;
370 let off = br.read_se()?;
371 validate!(off >= -12 && off <= 12);
372 pps.chroma_qp_index_offset = off as i8;
373 pps.deblocking_filter_control_present = br.read_bool()?;
374 pps.constrained_intra_pred = br.read_bool()?;
375 pps.redundant_pic_cnt_present = br.read_bool()?;
376 if br.tell() < full_size {
377 pps.transform_8x8_mode = br.read_bool()?;
378 pps.pic_scaling_matrix_present = br.read_bool()?;
379 if pps.pic_scaling_matrix_present {
380 let mut slist_present = [false; 6];
381 for (i, slist) in pps.scaling_list_4x4.iter_mut().enumerate() {
382 slist_present[i] = br.read_bool()?;
383 if slist_present[i] {
384 parse_scaling_list(&mut br, slist, i < 3)?;
385 }
386 }
387 for i in 1..6 {
388 if i == 3 {
389 continue;
390 }
391 if !slist_present[i] {
392 pps.scaling_list_4x4[i] = pps.scaling_list_4x4[i - 1];
393 }
394 }
395
396 let mut slist_present = [false; 6];
397 let num_8x8 = if !pps.transform_8x8_mode { 0 } else if sps.chroma_format_idc != 3 { 2 } else { 6 };
398 for (i, slist) in pps.scaling_list_8x8.iter_mut().take(num_8x8).enumerate() {
399 slist_present[i] = br.read_bool()?;
400 if slist_present[i] {
401 parse_scaling_list(&mut br, slist, (i & 1) == 0)?;
402 }
403 }
404 if num_8x8 > 2 {
405 for i in 2..6 {
406 if !slist_present[i] {
407 pps.scaling_list_8x8[i] = pps.scaling_list_8x8[i - 2];
408 }
409 }
410 }
411 } else {
412 pps.scaling_list_4x4 = sps.scaling_list_4x4;
413 pps.scaling_list_8x8 = sps.scaling_list_8x8;
414 }
415 let off = br.read_se()?;
416 validate!(off >= -12 && off <= 12);
417 pps.second_chroma_qp_index_offset = off as i8;
418 } else {
419 pps.second_chroma_qp_index_offset = pps.chroma_qp_index_offset;
420 }
421
422 Ok(pps)
423 }