nihav_itu: ignore high-profile extradata tail when it is not correct
[nihav.git] / nihav-itu / src / codecs / h264 / decoder_st.rs
CommitLineData
93839abd
KS
1use std::sync::Arc;
2
47ecb2b7
KS
3use nihav_core::codecs::*;
4use nihav_core::io::bitreader::*;
5
6use super::*;
7
8struct H264Decoder {
9 info: NACodecInfoRef,
10 width: usize,
11 height: usize,
12 num_mbs: usize,
13 nal_len: u8,
93839abd 14 sps: Vec<Arc<SeqParameterSet>>,
47ecb2b7 15 cur_sps: usize,
93839abd 16 pps: Vec<Arc<PicParameterSet>>,
47ecb2b7
KS
17 cur_pps: usize,
18
19 skip_mode: FrameSkipMode,
20 deblock_skip: bool,
21
22 is_mbaff: bool,
23
24 cavlc_cb: CAVLCTables,
25
26 sstate: SliceState,
27
28 cur_pic: Option<PictureInfo>,
29 cur_id: u16,
30 has_pic: bool,
31 frame_refs: FrameRefs,
32
33 temporal_mv: bool,
34 deblock_mode: u8,
35 lf_alpha: i8,
36 lf_beta: i8,
37 is_s: bool,
38
39 ipcm_buf: [u8; 256 + 64 + 64],
40
41 mc_dsp: H264MC,
42
43 transform_8x8_mode: bool,
44}
45
46impl H264Decoder {
47 fn new() -> Self {
48 let avg_vi = NAVideoInfo { width: 32, height: 32, flipped: false, format: YUV420_FORMAT, bits: 12 };
49 let avg_buf = alloc_video_buffer(avg_vi, 4).unwrap().get_vbuf().unwrap();
50 H264Decoder{
51 info: NACodecInfoRef::default(),
52 width: 0,
53 height: 0,
54 num_mbs: 0,
55 nal_len: 0,
56 sps: Vec::with_capacity(1),
57 cur_sps: 0,
58 pps: Vec::with_capacity(3),
59 cur_pps: 0,
60
61 skip_mode: FrameSkipMode::default(),
62 deblock_skip: false,
63
64 is_mbaff: false,
65
66 cavlc_cb: CAVLCTables::new(),
67
68 sstate: SliceState::new(),
69 cur_pic: None,
70 cur_id: 0,
71 has_pic: false,
72 frame_refs: FrameRefs::new(),
73
74 temporal_mv: false,
75 deblock_mode: 0,
76 lf_alpha: 0,
77 lf_beta: 0,
78 is_s: false,
79
80 ipcm_buf: [0; 256 + 64 + 64],
81
82 mc_dsp: H264MC::new(avg_buf),
83
84 transform_8x8_mode: false,
85 }
86 }
87 fn handle_nal(&mut self, src: &[u8], supp: &mut NADecoderSupport, skip_decoding: bool) -> DecoderResult<()> {
88 validate!(!src.is_empty());
89 validate!((src[0] & 0x80) == 0);
90 let nal_ref_idc = src[0] >> 5;
91 let nal_unit_type = src[0] & 0x1F;
92
93 let mut full_size = src.len() * 8;
94 for &byte in src.iter().rev() {
95 if byte == 0 {
96 full_size -= 8;
97 } else {
98 full_size -= (byte.trailing_zeros() + 1) as usize;
99 break;
100 }
101 }
102 validate!(full_size > 0);
103 match nal_unit_type {
104 1 | 5 if !skip_decoding => {
105 let is_idr = nal_unit_type == 5;
106 let mut br = BitReader::new(&src[..(full_size + 7)/8], BitReaderMode::BE);
107 br.skip(8)?;
108
93839abd 109 let slice_hdr = parse_slice_header(&mut br, self.sps.as_slice(), self.pps.as_slice(), is_idr, nal_ref_idc)?;
47ecb2b7
KS
110 validate!(br.tell() < full_size);
111 let full_id;
112 if slice_hdr.first_mb_in_slice == 0 {
113 validate!(self.cur_pic.is_none());
114 for (i, pps) in self.pps.iter().enumerate() {
115 if pps.pic_parameter_set_id == slice_hdr.pic_parameter_set_id {
116 self.cur_pps = i;
117 break;
118 }
119 }
120 for (i, sps) in self.sps.iter().enumerate() {
121 if sps.seq_parameter_set_id == self.pps[self.cur_pps].seq_parameter_set_id {
122 self.cur_sps = i;
123 break;
124 }
125 }
126
127 full_id = self.frame_refs.calc_picture_num(&slice_hdr, is_idr, nal_ref_idc, &self.sps[self.cur_sps]);
128
129 let sps = &self.sps[self.cur_sps];
130 if sps.chroma_format_idc != 1 || sps.bit_depth_luma != 8 || sps.bit_depth_chroma != 8 {
131println!(" chroma fmt {} bits {}/{}", sps.chroma_format_idc, sps.bit_depth_luma, sps.bit_depth_chroma);
132 return Err(DecoderError::NotImplemented);
133 }
134 //let pps = &self.pps[self.cur_pps];
135
136 if is_idr {
137 self.frame_refs.clear_refs();
138 }
139
140 self.width = sps.pic_width_in_mbs << 4;
141 self.height = sps.pic_height_in_mbs << 4;
142 self.num_mbs = sps.pic_width_in_mbs * sps.pic_height_in_mbs;
143 self.mc_dsp.set_dimensions(self.width, self.height);
144
145 self.is_mbaff = sps.mb_adaptive_frame_field && !slice_hdr.field_pic;
146 if self.is_mbaff {
147println!("MBAFF");
148 return Err(DecoderError::NotImplemented);
149 }
150 if !sps.frame_mbs_only {
151println!("PAFF?");
152 return Err(DecoderError::NotImplemented);
153 }
154
155//if slice_hdr.slice_type.is_b() { return Ok(()); }
156 self.cur_id = full_id as u16;
157 } else {
158 if let Some(ref mut pic) = self.cur_pic {
159 validate!(pic.cur_mb == slice_hdr.first_mb_in_slice);
160 let new_type = slice_hdr.slice_type.to_frame_type();
161 pic.pic_type = match (pic.pic_type, new_type) {
162 (FrameType::I, _) => new_type,
163 (_, FrameType::B) => FrameType::B,
164 _ => pic.pic_type,
165 };
166 full_id = pic.full_id;
167 } else {
168 return Ok(());//Err(DecoderError::InvalidData);
169 }
170 validate!(self.cur_pps < self.pps.len() && self.pps[self.cur_pps].pic_parameter_set_id == slice_hdr.pic_parameter_set_id);
171 }
172
173 let sps = &self.sps[self.cur_sps];
174 let pps = &self.pps[self.cur_pps];
175
176 self.temporal_mv = !slice_hdr.direct_spatial_mv_pred;
177 self.is_s = slice_hdr.slice_type == SliceType::SI || slice_hdr.slice_type == SliceType::SP;
178 self.deblock_mode = slice_hdr.disable_deblocking_filter_idc;
179 self.lf_alpha = slice_hdr.slice_alpha_c0_offset;
180 self.lf_beta = slice_hdr.slice_beta_offset;
181
182 self.frame_refs.select_refs(sps, &slice_hdr, full_id);
183
184 if slice_hdr.adaptive_ref_pic_marking_mode {
185 self.frame_refs.apply_adaptive_marking(&slice_hdr.adaptive_ref_pic_marking, slice_hdr.frame_num, 1 << self.sps[self.cur_sps].log2_max_frame_num)?;
186 }
187 if slice_hdr.first_mb_in_slice == 0 {
188 let ret = supp.pool_u8.get_free();
189 if ret.is_none() {
190 return Err(DecoderError::AllocError);
191 }
192 let tmp_vinfo = NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT);
193 let mut buf = ret.unwrap();
194 if buf.get_info() != tmp_vinfo {
195 supp.pool_u8.reset();
196 supp.pool_u8.prealloc_video(tmp_vinfo, 4)?;
197 let ret = supp.pool_u8.get_free();
198 if ret.is_none() {
199 return Err(DecoderError::AllocError);
200 }
201 buf = ret.unwrap();
202 }
203 self.cur_pic = Some(PictureInfo {
204 id: slice_hdr.frame_num,
205 full_id,
11d7aef2
KS
206 user_id: full_id,
207 time: NATimeInfo::new(None, None, None, 0, 0),
47ecb2b7
KS
208 pic_type: slice_hdr.slice_type.to_frame_type(),
209 buf,
210 cur_mb: 0,
211 is_ref: nal_ref_idc != 0,
11d7aef2 212 is_idr,
47ecb2b7 213 long_term: get_long_term_id(is_idr, &slice_hdr),
93839abd 214 mv_info: NABufferRef::new(FrameMV::new(sps.pic_width_in_mbs, sps.pic_height_in_mbs)),
47ecb2b7
KS
215 });
216 }
217
218 self.transform_8x8_mode = pps.transform_8x8_mode;
219
220 self.sstate.reset(sps.pic_width_in_mbs, sps.pic_height_in_mbs, slice_hdr.first_mb_in_slice);
fe64781d
KS
221
222 let mut dst_pic = if let Some(ref pic) = self.cur_pic {
223 pic.clone()
224 } else {
225 return Err(DecoderError::InvalidData);
226 };
227 let mut dst_frm = NASimpleVideoFrame::from_video_buf(&mut dst_pic.buf).unwrap();
228 let dst_mv_info = &mut dst_pic.mv_info;
47ecb2b7 229 if !pps.entropy_coding_mode {
fe64781d 230 self.has_pic = self.decode_slice_cavlc(&mut br, &slice_hdr, full_size, &mut dst_frm, dst_mv_info)?;
47ecb2b7
KS
231 } else {
232 br.align();
e6aaad5c 233 let start = br.tell() / 8;
47ecb2b7
KS
234 let csrc = &src[start..];
235 validate!(csrc.len() >= 2);
236 let mut cabac = CABAC::new(csrc, slice_hdr.slice_type, slice_hdr.slice_qp, slice_hdr.cabac_init_idc as usize)?;
fe64781d 237 self.has_pic = self.decode_slice_cabac(&mut cabac, &slice_hdr, &mut dst_frm, dst_mv_info)?;
47ecb2b7
KS
238 }
239 },
240 2 => { // slice data partition A
241 //slice header
242 //slice id = read_ue()
243 //cat 2 slice data (all but MB layer residual)
244 return Err(DecoderError::NotImplemented);
245 },
246 3 => { // slice data partition B
247 //slice id = read_ue()
248 //if pps.redundant_pic_cnt_present { redundant_pic_cnt = read_ue() }
249 //cat 3 slice data (MB layer residual)
250 return Err(DecoderError::NotImplemented);
251 },
252 4 => { // slice data partition C
253 //slice id = read_ue()
254 //if pps.redundant_pic_cnt_present { redundant_pic_cnt = read_ue() }
255 //cat 4 slice data (MB layer residual)
256 return Err(DecoderError::NotImplemented);
257 },
258 6 => {}, //SEI
259 7 => {
260 let sps = parse_sps(&src[1..])?;
93839abd 261 self.sps.push(Arc::new(sps));
47ecb2b7
KS
262 },
263 8 => {
264 validate!(full_size >= 8 + 16);
265 let pps = parse_pps(&src[1..], &self.sps, full_size - 8)?;
266 let mut found = false;
267 for stored_pps in self.pps.iter_mut() {
268 if stored_pps.pic_parameter_set_id == pps.pic_parameter_set_id {
93839abd 269 *stored_pps = Arc::clone(&pps);
47ecb2b7
KS
270 found = true;
271 break;
272 }
273 }
274 if !found {
275 self.pps.push(pps);
276 }
277 },
278 9 => { // access unit delimiter
279 },
280 10 => {}, //end of sequence
281 11 => {}, //end of stream
282 12 => {}, //filler
283 _ => {},
284 };
285
286 Ok(())
287 }
5f223cdb 288 fn pred_mv(sstate: &mut SliceState, frame_refs: &SimplifiedSliceRefs, mb_info: &mut CurrentMBInfo, cur_id: u16, temporal_mv: bool, direct_8x8: bool) {
47ecb2b7
KS
289 let mb_type = mb_info.mb_type;
290 if !mb_type.is_4x4() {
291 let (pw, ph) = mb_type.size();
292 let mut xoff = 0;
293 let mut yoff = 0;
294 if mb_type == MBType::Direct || mb_type == MBType::BSkip {
295 sstate.predict_direct_mb(frame_refs, temporal_mv, direct_8x8, cur_id);
296 }
297 for part in 0..mb_type.num_parts() {
298 if !mb_type.is_l1(part) {
299 match mb_type {
300 MBType::PSkip => sstate.predict_pskip(),
301 MBType::BSkip | MBType::Direct => {
302 },
303 _ => {
304 sstate.predict(xoff, yoff, pw, ph, 0,
305 mb_info.mv_l0[part], mb_info.ref_l0[part]);
306 },
307 };
308 }
309 if !mb_type.is_l0(part) && mb_type != MBType::BSkip && mb_type != MBType::Direct {
310 sstate.predict(xoff, yoff, pw, ph, 1, mb_info.mv_l1[part], mb_info.ref_l1[part]);
311 }
312 if pw != 16 {
313 xoff += pw;
314 } else {
315 yoff += ph;
316 }
317 }
318 } else {
319 for part in 0..4 {
320 let sub_type = mb_info.sub_mb_type[part];
321 let mut xoff = (part & 1) * 8;
322 let mut yoff = (part & 2) * 4;
323 let orig_x = xoff;
324 let (pw, ph) = sub_type.size();
325 for subpart in 0..sub_type.num_parts() {
326 if sub_type != SubMBType::Direct8x8 {
327 if !sub_type.is_l1() {
328 sstate.predict(xoff, yoff, pw, ph, 0, mb_info.mv_l0[part * 4 + subpart], mb_info.ref_l0[part]);
329 }
330 if !sub_type.is_l0() {
331 sstate.predict(xoff, yoff, pw, ph, 1, mb_info.mv_l1[part * 4 + subpart], mb_info.ref_l1[part]);
332 }
333 } else {
334 for sblk in 0..4 {
335 sstate.predict_direct_sub(frame_refs, temporal_mv, direct_8x8, cur_id, (xoff / 4) + (sblk & 1) + (yoff / 4) * 4 + (sblk & 2) * 2);
336 }
337 }
338 xoff += pw;
339 if xoff == orig_x + 8 {
340 xoff -= 8;
341 yoff += ph;
342 }
343 }
344 }
345 }
346 }
347 #[allow(clippy::cognitive_complexity)]
fe64781d 348 fn handle_macroblock(&mut self, slice_hdr: &SliceHeader, mb_info: &mut CurrentMBInfo, slice_refs: &SimplifiedSliceRefs, frm: &mut NASimpleVideoFrame<u8>, mv_info: &mut FrameMV) {
47ecb2b7
KS
349 let pps = &self.pps[self.cur_pps];
350
351 let qp_y = mb_info.qp_y;
352 let qpr = ((qp_y as i8) + pps.chroma_qp_index_offset).max(0).min(51) as usize;
353 let qp_u = CHROMA_QUANTS[qpr];
354 let qpb = ((qp_y as i8) + pps.second_chroma_qp_index_offset).max(0).min(51) as usize;
355 let qp_v = CHROMA_QUANTS[qpb];
356
357 let tx_bypass = qp_y == 0 && self.sps[self.cur_sps].qpprime_y_zero_transform_bypass;
358
359 self.sstate.get_cur_mb().mb_type = mb_info.mb_type.into();
360 if mb_info.mb_type != MBType::PCM {
361 self.sstate.get_cur_mb().qp_y = qp_y;
362 self.sstate.get_cur_mb().qp_u = qp_u;
363 self.sstate.get_cur_mb().qp_v = qp_v;
364 self.sstate.get_cur_mb().transform_8x8 = mb_info.transform_size_8x8;
365 }
366 let has_dc = mb_info.mb_type.is_intra16x16() && mb_info.coded[24];
367 if has_dc {
368 idct_luma_dc(&mut mb_info.coeffs[24], qp_y);
369 for i in 0..16 {
370 mb_info.coeffs[i][0] = mb_info.coeffs[24][i];
371 }
372 }
754ab49a
KS
373 if !tx_bypass {
374 if !mb_info.transform_size_8x8 {
375 let quant_dc = !mb_info.mb_type.is_intra16x16();
fe64781d
KS
376 if quant_dc {
377 for (coded, coeffs) in mb_info.coded[..16].iter_mut().zip(mb_info.coeffs[..16].iter_mut()) {
378 if *coded {
379 idct(coeffs, qp_y);
380 } else if has_dc {
381 idct_dc(coeffs, qp_y, quant_dc);
382 *coded = true;
383 }
384 }
385 } else {
386 for (coded, coeffs) in mb_info.coded[..16].iter_mut().zip(mb_info.coeffs[..16].iter_mut()) {
387 if *coded {
388 idct_skip_dc(coeffs, qp_y);
389 } else if has_dc {
390 idct_dc(coeffs, qp_y, quant_dc);
391 *coded = true;
392 }
47ecb2b7 393 }
754ab49a
KS
394 }
395 } else {
396 for i in 0..4 {
397 if mb_info.coded[(i & 1) * 2 + (i & 2) * 4] {
398 dequant8x8(&mut mb_info.coeffs8x8[i].coeffs, &pps.scaling_list_8x8[!mb_info.mb_type.is_intra() as usize]);
399 idct8x8(&mut mb_info.coeffs8x8[i].coeffs, qp_y);
47ecb2b7 400 }
47ecb2b7
KS
401 }
402 }
754ab49a
KS
403 } else if !mb_info.transform_size_8x8 {
404 for i in 0..16 {
405 if !mb_info.coded[i] && has_dc {
406 mb_info.coded[i] = true;
47ecb2b7
KS
407 }
408 }
409 }
410 for chroma in 0..2 {
411 let qp_c = if chroma == 0 { qp_u } else { qp_v };
412 if mb_info.cbpc != 0 {
413 chroma_dc_transform(&mut mb_info.chroma_dc[chroma], qp_c);
414 }
415 for i in 0..4 {
416 let blk_no = 16 + chroma * 4 + i;
417 mb_info.coeffs[blk_no][0] = mb_info.chroma_dc[chroma][i];
418 if mb_info.coded[blk_no] {
fe64781d 419 idct_skip_dc(&mut mb_info.coeffs[blk_no], qp_c);
47ecb2b7
KS
420 } else if mb_info.coeffs[blk_no][0] != 0 {
421 idct_dc(&mut mb_info.coeffs[blk_no], qp_c, false);
422 mb_info.coded[blk_no] = true;
423 }
424 }
425 }
426 if !pps.entropy_coding_mode || mb_info.mb_type.is_skip() || mb_info.mb_type.is_intra() {
427 self.sstate.reset_mb_mv();
428 }
429 if !mb_info.mb_type.is_intra() {
5f223cdb 430 Self::pred_mv(&mut self.sstate, slice_refs, mb_info, self.cur_id, self.temporal_mv, self.sps[self.cur_sps].direct_8x8_inference);
47ecb2b7
KS
431 }
432 if !pps.constrained_intra_pred && mb_info.mb_type != MBType::Intra4x4 && mb_info.mb_type != MBType::Intra8x8 {
433 self.sstate.fill_ipred(IntraPredMode::DC);
434 }
435
436 let xpos = self.sstate.mb_x * 16;
437 let ypos = self.sstate.mb_y * 16;
fe64781d
KS
438
439 if mb_info.mb_type != MBType::PCM {
440 let weight_mode = if self.pps[self.cur_pps].weighted_pred && slice_hdr.slice_type.is_p() {
441 1
442 } else if slice_hdr.slice_type.is_b() {
443 self.pps[self.cur_pps].weighted_bipred_idc
444 } else {
445 0
446 };
447 recon_mb(frm, slice_hdr, mb_info, &mut self.sstate, slice_refs, &mut self.mc_dsp, weight_mode);
448 } else {
449 for (dline, src) in frm.data[frm.offset[0] + xpos + ypos * frm.stride[0]..].chunks_mut(frm.stride[0]).take(16).zip(self.ipcm_buf.chunks(16)) {
450 dline[..16].copy_from_slice(src);
47ecb2b7 451 }
fe64781d
KS
452 for (dline, src) in frm.data[frm.offset[1] + xpos/2 + ypos/2 * frm.stride[1]..].chunks_mut(frm.stride[1]).take(8).zip(self.ipcm_buf[256..].chunks(8)) {
453 dline[..8].copy_from_slice(src);
454 }
455 for (dline, src) in frm.data[frm.offset[2] + xpos/2 + ypos/2 * frm.stride[2]..].chunks_mut(frm.stride[2]).take(8).zip(self.ipcm_buf[256 + 64..].chunks(8)) {
456 dline[..8].copy_from_slice(src);
457 }
458 }
47ecb2b7
KS
459/*match mb_info.mb_type {
460MBType::BSkip | MBType::Direct | MBType::B16x16(_) | MBType::B16x8(_, _) | MBType::B8x16(_, _) | MBType::B8x8 => {
461 let dstride = frm.stride[0];
462 let dst = &mut frm.data[frm.offset[0] + self.sstate.mb_x * 16 + self.sstate.mb_y * 16 * dstride..];
463 for el in dst[..16].iter_mut() { *el = 255; }
464 for row in dst.chunks_mut(dstride).skip(1).take(15) {
465 row[0] = 255;
466 }
467},
468_ => {},
469};*/
fe64781d
KS
470 self.sstate.save_ipred_context(frm);
471
472 let mb_pos = self.sstate.mb_x + self.sstate.mb_y * mv_info.mb_stride;
473 let mut mb = FrameMBInfo::new();
474 mb.mb_type = mb_info.mb_type.into();
475 for blk4 in 0..16 {
476 mb.mv[blk4] = self.sstate.get_cur_blk4(blk4).mv;
47ecb2b7 477 }
fe64781d
KS
478 for blk8 in 0..4 {
479 mb.ref_poc[blk8] = slice_refs.map_refs(self.sstate.get_cur_blk8(blk8).ref_idx);
480 mb.ref_idx[blk8] = self.sstate.get_cur_blk8(blk8).ref_idx;
47ecb2b7 481 }
fe64781d
KS
482 mv_info.mbs[mb_pos] = mb;
483
47ecb2b7 484 if !self.deblock_skip && self.deblock_mode != 1 {
5f223cdb 485 self.sstate.fill_deblock(slice_refs, self.deblock_mode, self.is_s);
fe64781d 486 loop_filter_mb(frm, &self.sstate, self.lf_alpha, self.lf_beta);
47ecb2b7
KS
487 }
488 self.sstate.next_mb();
489 }
fe64781d 490 fn decode_slice_cavlc(&mut self, br: &mut BitReader, slice_hdr: &SliceHeader, full_size: usize, frm: &mut NASimpleVideoFrame<u8>, mv_info: &mut FrameMV) -> DecoderResult<bool> {
47ecb2b7
KS
491 const INTRA_CBP: [u8; 48] = [
492 47, 31, 15, 0, 23, 27, 29, 30, 7, 11, 13, 14, 39, 43, 45, 46,
493 16, 3, 5, 10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1, 2, 4,
494 8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41
495 ];
496 const INTER_CBP: [u8; 48] = [
497 0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13,
498 14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46,
499 17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41
500 ];
501
e6aaad5c 502 let mut mb_idx = slice_hdr.first_mb_in_slice;
47ecb2b7
KS
503 let mut mb_info = CurrentMBInfo { qp_y: slice_hdr.slice_qp, ..Default::default() };
504 let skip_type = if slice_hdr.slice_type.is_p() { MBType::PSkip } else { MBType::BSkip };
5f223cdb
KS
505
506 let slice_refs = self.frame_refs.cur_refs.clone();
507 let sslice_refs = SimplifiedSliceRefs::new(&slice_refs);
508
47ecb2b7
KS
509 while br.tell() < full_size && mb_idx < self.num_mbs {
510 mb_info.coded = [false; 25];
511 mb_info.ref_l0 = [ZERO_REF; 4];
512 mb_info.ref_l1 = [ZERO_REF; 4];
513 mb_info.mv_l0 = [ZERO_MV; 16];
514 mb_info.mv_l1 = [ZERO_MV; 16];
515 mb_info.chroma_dc = [[0; 4]; 2];
516 mb_info.cbpy = 0;
517 mb_info.cbpc = 0;
518
519 if !slice_hdr.slice_type.is_intra() {
520 let mb_skip_run = br.read_ue()? as usize;
521 validate!(mb_idx + mb_skip_run <= self.num_mbs);
522 mb_info.mb_type = skip_type;
523 for _ in 0..mb_skip_run {
fe64781d 524 self.handle_macroblock(slice_hdr, &mut mb_info, &sslice_refs, frm, mv_info);
47ecb2b7
KS
525 mb_idx += 1;
526 }
527 if mb_idx == self.num_mbs || br.tell() >= full_size {
528 break;
529 }
530 }
531 if br.tell() < full_size {
532 if self.is_mbaff && ((mb_idx & 1) == 0) {
533 let _mb_field_decoding = br.read_bool()?;
534 }
535 let mut mb_type = decode_mb_type_cavlc(br, slice_hdr)?;
536 mb_info.mb_type = mb_type;
537 mb_info.transform_size_8x8 = false;
538 if mb_type == MBType::PCM {
539 br.align();
540 for pix in self.ipcm_buf[..256 + 64 + 64].iter_mut() {
541 *pix = br.read(8)? as u8;
542 }
543 self.sstate.fill_ncoded(16);
544 } else {
545 if self.transform_8x8_mode && mb_type == MBType::Intra4x4 {
546 mb_info.transform_size_8x8 = br.read_bool()?;
547 if mb_info.transform_size_8x8 {
548 mb_type = MBType::Intra8x8;
549 mb_info.mb_type = MBType::Intra8x8;
550 }
551 }
552 decode_mb_pred_cavlc(br, slice_hdr, mb_type, &mut self.sstate, &mut mb_info)?;
553 let (cbpy, cbpc) = if let MBType::Intra16x16(_, cbpy, cbpc) = mb_type {
554 (cbpy, cbpc)
555 } else {
556 let cbp_id = br.read_ue()? as usize;
557 validate!(cbp_id < INTRA_CBP.len());
558 let cbp = if mb_type == MBType::Intra4x4 || mb_type == MBType::Intra8x8 {
559 INTRA_CBP[cbp_id]
560 } else {
561 INTER_CBP[cbp_id]
562 };
563 if self.transform_8x8_mode && (cbp & 0xF) != 0 && mb_info.can_have_8x8_tx(self.sps[self.cur_sps].direct_8x8_inference) {
564 mb_info.transform_size_8x8 = br.read_bool()?;
565 }
566 ((cbp & 0xF), (cbp >> 4))
567 };
568 mb_info.cbpy = cbpy;
569 mb_info.cbpc = cbpc;
570 self.sstate.get_cur_mb().cbp = (cbpc << 4) | cbpy;
571 if cbpy != 0 || cbpc != 0 || mb_type.is_intra16x16() {
572 let mb_qp_delta = br.read_se()?;
573 validate!(mb_qp_delta >= -26 && mb_qp_delta <= 25);
574 let new_qp = mb_qp_delta + i32::from(mb_info.qp_y);
575 mb_info.qp_y = if new_qp < 0 {
576 (new_qp + 52) as u8
577 } else if new_qp >= 52 {
578 (new_qp - 52) as u8
579 } else {
580 new_qp as u8
581 };
582 mb_info.coeffs = [[0; 16]; 25];
583 if self.transform_8x8_mode {
584 mb_info.clear_coeffs8x8();
585 }
586 mb_info.chroma_dc = [[0; 4]; 2];
587 decode_residual_cavlc(br, &mut self.sstate, &mut mb_info, &self.cavlc_cb)?;
588 }
589 }
fe64781d 590 self.handle_macroblock(slice_hdr, &mut mb_info, &sslice_refs, frm, mv_info);
47ecb2b7
KS
591 }
592 mb_idx += 1;
593 }
594 if let Some(ref mut pic) = self.cur_pic {
595 pic.cur_mb = mb_idx;
596 }
597 Ok(mb_idx == self.num_mbs)
598 }
fe64781d 599 fn decode_slice_cabac(&mut self, cabac: &mut CABAC, slice_hdr: &SliceHeader, frm: &mut NASimpleVideoFrame<u8>, mv_info: &mut FrameMV) -> DecoderResult<bool> {
e6aaad5c 600 let mut mb_idx = slice_hdr.first_mb_in_slice;
47ecb2b7
KS
601 let mut prev_mb_skipped = false;
602 let skip_type = if slice_hdr.slice_type.is_p() { MBType::PSkip } else { MBType::BSkip };
603 let mut last_qp_diff = false;
604
605 let mut mb_info = CurrentMBInfo { qp_y: slice_hdr.slice_qp, ..Default::default() };
606
5f223cdb
KS
607 let slice_refs = self.frame_refs.cur_refs.clone();
608 let sslice_refs = SimplifiedSliceRefs::new(&slice_refs);
609
47ecb2b7
KS
610 while mb_idx < self.num_mbs {
611 mb_info.coded = [false; 25];
612 mb_info.ref_l0 = [ZERO_REF; 4];
613 mb_info.ref_l1 = [ZERO_REF; 4];
614 mb_info.mv_l0 = [ZERO_MV; 16];
615 mb_info.mv_l1 = [ZERO_MV; 16];
616 mb_info.chroma_dc = [[0; 4]; 2];
617 mb_info.cbpy = 0;
618 mb_info.cbpc = 0;
619 let mb_skip = cabac_decode_mbskip(cabac, &self.sstate, slice_hdr);
620 if !mb_skip {
621 if self.is_mbaff && (((mb_idx & 1) == 0) || (prev_mb_skipped && ((mb_idx & 1) == 1))) {
622 let _mb_field_decoding = cabac.decode_bit(70);
623 }
624 let mut mb_type = cabac_decode_mb_type(cabac, slice_hdr, &self.sstate);
625 mb_info.mb_type = mb_type;
626 mb_info.transform_size_8x8 = false;
627 if mb_type == MBType::PCM {
628 let ipcm_size = 256 + 64 + 64;
629 validate!(cabac.pos + ipcm_size <= cabac.src.len());
630 self.ipcm_buf[..ipcm_size].copy_from_slice(&cabac.src[cabac.pos..][..ipcm_size]);
631 cabac.pos += ipcm_size;
632 cabac.reinit()?;
633 last_qp_diff = false;
634 } else {
635 if self.transform_8x8_mode && mb_type == MBType::Intra4x4 {
636 let mut ctx = 0;
637 if self.sstate.get_top_mb().transform_8x8 {
638 ctx += 1;
639 }
640 if self.sstate.get_left_mb().transform_8x8 {
641 ctx += 1;
642 }
643 mb_info.transform_size_8x8 = cabac.decode_bit(399 + ctx);
644 if mb_info.transform_size_8x8 {
645 mb_type = MBType::Intra8x8;
646 mb_info.mb_type = MBType::Intra8x8;
647 }
648 }
649 decode_mb_pred_cabac(cabac, slice_hdr, mb_type, &mut self.sstate, &mut mb_info);
650 let (cbpy, cbpc) = if let MBType::Intra16x16(_, cbpy, cbpc) = mb_type {
651 (cbpy, cbpc)
652 } else {
653 decode_cbp_cabac(cabac, &self.sstate)
654 };
655 if self.transform_8x8_mode && cbpy != 0 && mb_info.can_have_8x8_tx(self.sps[self.cur_sps].direct_8x8_inference) {
656 let mut ctx = 0;
657 if self.sstate.get_top_mb().transform_8x8 {
658 ctx += 1;
659 }
660 if self.sstate.get_left_mb().transform_8x8 {
661 ctx += 1;
662 }
663 mb_info.transform_size_8x8 = cabac.decode_bit(399 + ctx);
664 }
665 if mb_type.is_intra() {
666 self.sstate.get_cur_mb().cmode = mb_info.chroma_ipred;
667 }
668 mb_info.cbpy = cbpy;
669 mb_info.cbpc = cbpc;
670 self.sstate.get_cur_mb().cbp = (cbpc << 4) | cbpy;
671 if cbpy != 0 || cbpc != 0 || mb_type.is_intra16x16() {
672 let mb_qp_delta = decode_mb_qp_delta_cabac(cabac, last_qp_diff as usize);
673 validate!(mb_qp_delta >= -26 && mb_qp_delta <= 25);
674 last_qp_diff = mb_qp_delta != 0;
675 let new_qp = mb_qp_delta + i32::from(mb_info.qp_y);
676 mb_info.qp_y = if new_qp < 0 {
677 (new_qp + 52) as u8
678 } else if new_qp >= 52 {
679 (new_qp - 52) as u8
680 } else {
681 new_qp as u8
682 };
683 mb_info.coeffs = [[0; 16]; 25];
684 if self.transform_8x8_mode {
685 mb_info.clear_coeffs8x8();
686 }
687 mb_info.chroma_dc = [[0; 4]; 2];
688 decode_residual_cabac(cabac, &mut self.sstate, &mut mb_info);
689 } else {
690 last_qp_diff = false;
691 }
692 }
693 } else {
694 mb_info.mb_type = skip_type;
695 mb_info.transform_size_8x8 = false;
696 last_qp_diff = false;
697 }
fe64781d 698 self.handle_macroblock(slice_hdr, &mut mb_info, &sslice_refs, frm, mv_info);
47ecb2b7
KS
699 prev_mb_skipped = mb_skip;
700 if !(self.is_mbaff && ((mb_idx & 1) == 0)) && cabac.decode_terminate() {
701 if let Some(ref mut pic) = self.cur_pic {
702 pic.cur_mb = mb_idx + 1;
703 }
704 return Ok(mb_idx + 1 == self.num_mbs);
705 }
706 mb_idx += 1;
707 }
708 Err(DecoderError::InvalidData)
709 }
710}
711
712impl NADecoder for H264Decoder {
713 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
714 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
715 let fmt = YUV420_FORMAT;
716 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, false, fmt));
717 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
718
719 let edata = info.get_extradata().unwrap();
720//print!("edata:"); for &el in edata.iter() { print!(" {:02X}", el); } println!();
721 if edata.len() > 11 && &edata[0..4] == b"avcC" {
722 let mut mr = MemoryReader::new_read(edata.as_slice());
723 let mut br = ByteReader::new(&mut mr);
724 let mut nal_buf = Vec::new();
725
726 br.read_skip(4)?;
727 let version = br.read_byte()?;
728 validate!(version == 1);
729 let profile = br.read_byte()?;
730 let _compatibility = br.read_byte()?;
731 let _level = br.read_byte()?;
732 let b = br.read_byte()?;
733 validate!((b & 0xFC) == 0xFC);
734 self.nal_len = (b & 3) + 1;
735 let b = br.read_byte()?;
736 validate!((b & 0xE0) == 0xE0);
737 let num_sps = (b & 0x1F) as usize;
738 for _ in 0..num_sps {
739 let len = br.read_u16be()? as usize;
740 let offset = br.tell() as usize;
741 validate!((br.peek_byte()? & 0x1F) == 7);
742 let _size = unescape_nal(&edata[offset..][..len], &mut nal_buf);
743 self.handle_nal(&nal_buf, supp, true)?;
744 br.read_skip(len)?;
745 }
746 let num_pps = br.read_byte()? as usize;
747 for _ in 0..num_pps {
748 let len = br.read_u16be()? as usize;
749 let offset = br.tell() as usize;
750 validate!((br.peek_byte()? & 0x1F) == 8);
751 let _size = unescape_nal(&edata[offset..][..len], &mut nal_buf);
752 self.handle_nal(&nal_buf, supp, true)?;
753 br.read_skip(len)?;
754 }
755 if br.left() > 0 {
756 match profile {
757 100 | 110 | 122 | 144 => {
758 let b = br.read_byte()?;
e12dabcd
KS
759 // some encoders put something different here
760 if (b & 0xFC) != 0xFC {
761 return Ok(());
762 }
47ecb2b7
KS
763 // b & 3 -> chroma format
764 let b = br.read_byte()?;
765 validate!((b & 0xF8) == 0xF8);
766 // b & 7 -> luma depth minus 8
767 let b = br.read_byte()?;
768 validate!((b & 0xF8) == 0xF8);
769 // b & 7 -> chroma depth minus 8
770 let num_spsext = br.read_byte()? as usize;
771 for _ in 0..num_spsext {
772 let len = br.read_u16be()? as usize;
773 // parse spsext
774 br.read_skip(len)?;
775 }
776 },
777 _ => {},
778 };
779 }
780 } else {
781 return Err(DecoderError::NotImplemented);
782 }
783
784 self.width = vinfo.get_width();
785 self.height = vinfo.get_height();
786
787 if (self.width == 0 || self.height == 0) && !self.sps.is_empty() {
788 self.width = self.sps[0].pic_width_in_mbs * 16;
789 self.height = self.sps[0].pic_height_in_mbs * 16;
790 }
791
792 let num_bufs = if !self.sps.is_empty() {
e6aaad5c 793 self.sps[0].num_ref_frames + 1
47ecb2b7
KS
794 } else {
795 3
796 }.max(16 + 1);
797 supp.pool_u8.set_dec_bufs(num_bufs);
798 supp.pool_u8.prealloc_video(NAVideoInfo::new(self.width, self.height, false, fmt), 4)?;
799
800 Ok(())
801 } else {
802 Err(DecoderError::InvalidData)
803 }
804 }
805 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
806 let src = pkt.get_buffer();
807
808 let mut mr = MemoryReader::new_read(&src);
809 let mut br = ByteReader::new(&mut mr);
810 let mut nal_buf = Vec::with_capacity(src.len());
811 if self.nal_len > 0 {
812 let mut skip_decoding = false;
813 if self.skip_mode != FrameSkipMode::None {
814 let mut pic_type = FrameType::I;
815 let mut is_ref = false;
816 while br.left() > 0 {
817 let size = match self.nal_len {
818 1 => br.read_byte()? as usize,
819 2 => br.read_u16be()? as usize,
820 3 => br.read_u24be()? as usize,
821 4 => br.read_u32be()? as usize,
822 _ => unreachable!(),
823 };
824 validate!(br.left() >= (size as i64));
825 let offset = br.tell() as usize;
826 let size = unescape_nal(&src[offset..][..size], &mut nal_buf);
827 validate!(size > 0);
828 let nal_ref_idc = nal_buf[0] >> 5;
829 let nal_unit_type = nal_buf[0] & 0x1F;
830 if nal_unit_type == 1 || nal_unit_type == 5 {
831 let mut bitr = BitReader::new(&nal_buf[1..], BitReaderMode::BE);
832 let (first_mb, slice_type) = parse_slice_header_minimal(&mut bitr)?;
833 if first_mb == 0 && nal_ref_idc != 0 {
834 is_ref = true;
835 }
836 let new_type = slice_type.to_frame_type();
837 pic_type = match (pic_type, new_type) {
838 (FrameType::I, _) => new_type,
839 (_, FrameType::B) => FrameType::B,
840 _ => pic_type,
841 };
842 }
843 br.read_skip(size)?;
844 }
845 match self.skip_mode {
846 FrameSkipMode::IntraOnly => {
847 skip_decoding = pic_type != FrameType::I;
848 },
849 FrameSkipMode::KeyframesOnly => {
850 if !is_ref {
851 skip_decoding = true;
852 }
853 },
854 _ => {},
855 };
856 br.seek(SeekFrom::Start(0))?;
857 }
858 while br.left() > 0 {
859 let size = match self.nal_len {
860 1 => br.read_byte()? as usize,
861 2 => br.read_u16be()? as usize,
862 3 => br.read_u24be()? as usize,
863 4 => br.read_u32be()? as usize,
864 _ => unreachable!(),
865 };
866 validate!(br.left() >= (size as i64));
867 let offset = br.tell() as usize;
868 let _size = unescape_nal(&src[offset..][..size], &mut nal_buf);
869 self.handle_nal(nal_buf.as_slice(), supp, skip_decoding)?;
870 br.read_skip(size)?;
871 }
872 } else {
873//todo NAL detection
874 unimplemented!();
875 }
876
877 let (bufinfo, ftype, dts) = if self.has_pic && self.cur_pic.is_some() {
878 let mut npic = None;
879 std::mem::swap(&mut self.cur_pic, &mut npic);
880 let cpic = npic.unwrap();
881 let ret = (NABufferType::Video(cpic.buf.clone()), cpic.pic_type, Some(u64::from(cpic.full_id)));
882 if cpic.is_ref {
883 self.frame_refs.add_short_term(cpic.clone(), self.sps[self.cur_sps].num_ref_frames);
884 }
885 if let Some(lt_idx) = cpic.long_term {
886 self.frame_refs.add_long_term(lt_idx, cpic);
887 }
888 ret
889 } else {
890 (NABufferType::None, FrameType::Skip, None)
891 };
892
893 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
894 frm.set_keyframe(ftype == FrameType::I);
895 if let (Some(mydts), None) = (dts, frm.get_dts()) {
896 frm.set_dts(Some(mydts));
897 }
898 if let Some(dts) = dts {
899 frm.set_id(dts as i64);
900 }
901 frm.set_frame_type(ftype);
902 Ok(frm.into_ref())
903 }
904 fn flush(&mut self) {
905 }
906}
907
908impl NAOptionHandler for H264Decoder {
909 fn get_supported_options(&self) -> &[NAOptionDefinition] { DECODER_OPTIONS }
910 fn set_options(&mut self, options: &[NAOption]) {
911 for option in options.iter() {
912 for opt_def in DECODER_OPTIONS.iter() {
913 if opt_def.check(option).is_ok() {
914 match (option.name, &option.value) {
915 (FRAME_SKIP_OPTION, NAValue::String(ref strval)) => {
916 if let Ok(smode) = FrameSkipMode::from_str(strval) {
917 self.skip_mode = smode;
918 }
919 },
920 (DEBLOCK_SKIP_OPTION, NAValue::Bool(val)) => {
921 self.deblock_skip = *val;
922 },
923 _ => {},
924 }
925 }
926 }
927 }
928 }
929 fn query_option_value(&self, name: &str) -> Option<NAValue> {
930 match name {
931 FRAME_SKIP_OPTION => Some(NAValue::String(self.skip_mode.to_string())),
932 DEBLOCK_SKIP_OPTION => Some(NAValue::Bool(self.deblock_skip)),
933 _ => None,
934 }
935 }
936}
937
938pub fn get_decoder() -> Box<dyn NADecoder + Send> {
939 Box::new(H264Decoder::new())
940}