3 use nihav_core::codecs::*;
4 use nihav_core::io::bitreader::*;
16 sps: Vec<Arc<SeqParameterSet>>,
18 pps: Vec<Arc<PicParameterSet>>,
21 skip_mode: FrameSkipMode,
26 cavlc_cb: CAVLCTables,
30 cur_pic: Option<PictureInfo>,
33 frame_refs: FrameRefs,
41 ipcm_buf: [u8; 256 + 64 + 64],
45 transform_8x8_mode: bool,
51 info: NACodecInfoRef::default(),
58 sps: Vec::with_capacity(1),
60 pps: Vec::with_capacity(3),
63 skip_mode: FrameSkipMode::default(),
68 cavlc_cb: CAVLCTables::new(),
70 sstate: SliceState::new(),
74 frame_refs: FrameRefs::new(),
82 ipcm_buf: [0; 256 + 64 + 64],
84 mc_dsp: H264MC::new(),
86 transform_8x8_mode: false,
89 fn handle_nal(&mut self, src: &[u8], supp: &mut NADecoderSupport, skip_decoding: bool) -> DecoderResult<()> {
90 validate!(!src.is_empty());
91 validate!((src[0] & 0x80) == 0);
92 let nal_ref_idc = src[0] >> 5;
93 let nal_unit_type = src[0] & 0x1F;
95 let mut full_size = src.len() * 8;
96 for &byte in src.iter().rev() {
100 full_size -= (byte.trailing_zeros() + 1) as usize;
104 validate!(full_size > 0);
105 match nal_unit_type {
106 1 | 5 if !skip_decoding => {
107 let is_idr = nal_unit_type == 5;
108 let mut br = BitReader::new(&src[..(full_size + 7)/8], BitReaderMode::BE);
111 let slice_hdr = parse_slice_header(&mut br, self.sps.as_slice(), self.pps.as_slice(), is_idr, nal_ref_idc)?;
112 validate!(br.tell() < full_size);
114 if slice_hdr.first_mb_in_slice == 0 {
115 validate!(self.cur_pic.is_none());
116 for (i, pps) in self.pps.iter().enumerate() {
117 if pps.pic_parameter_set_id == slice_hdr.pic_parameter_set_id {
122 for (i, sps) in self.sps.iter().enumerate() {
123 if sps.seq_parameter_set_id == self.pps[self.cur_pps].seq_parameter_set_id {
129 full_id = self.frame_refs.calc_picture_num(&slice_hdr, is_idr, nal_ref_idc, &self.sps[self.cur_sps]);
131 let sps = &self.sps[self.cur_sps];
132 if sps.chroma_format_idc != 1 || sps.bit_depth_luma != 8 || sps.bit_depth_chroma != 8 {
133 println!(" chroma fmt {} bits {}/{}", sps.chroma_format_idc, sps.bit_depth_luma, sps.bit_depth_chroma);
134 return Err(DecoderError::NotImplemented);
136 //let pps = &self.pps[self.cur_pps];
139 self.frame_refs.clear_refs();
142 self.width = sps.pic_width_in_mbs << 4;
143 self.height = sps.pic_height_in_mbs << 4;
144 self.num_mbs = sps.pic_width_in_mbs * sps.pic_height_in_mbs;
145 self.mc_dsp.set_dimensions(self.width, self.height);
147 self.is_mbaff = sps.mb_adaptive_frame_field && !slice_hdr.field_pic;
150 return Err(DecoderError::NotImplemented);
152 if !sps.frame_mbs_only {
154 return Err(DecoderError::NotImplemented);
157 //if slice_hdr.slice_type.is_b() { return Ok(()); }
158 self.cur_id = full_id as u16;
160 if let Some(ref mut pic) = self.cur_pic {
161 validate!(pic.cur_mb == slice_hdr.first_mb_in_slice);
162 let new_type = slice_hdr.slice_type.to_frame_type();
163 pic.pic_type = match (pic.pic_type, new_type) {
164 (FrameType::I, _) => new_type,
165 (_, FrameType::B) => FrameType::B,
168 full_id = pic.full_id;
170 return Ok(());//Err(DecoderError::InvalidData);
172 validate!(self.cur_pps < self.pps.len() && self.pps[self.cur_pps].pic_parameter_set_id == slice_hdr.pic_parameter_set_id);
175 let sps = &self.sps[self.cur_sps];
176 let pps = &self.pps[self.cur_pps];
178 self.temporal_mv = !slice_hdr.direct_spatial_mv_pred;
179 self.is_s = slice_hdr.slice_type == SliceType::SI || slice_hdr.slice_type == SliceType::SP;
180 self.deblock_mode = slice_hdr.disable_deblocking_filter_idc;
181 self.lf_alpha = slice_hdr.slice_alpha_c0_offset;
182 self.lf_beta = slice_hdr.slice_beta_offset;
184 self.frame_refs.select_refs(sps, &slice_hdr, full_id);
186 if slice_hdr.adaptive_ref_pic_marking_mode {
187 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)?;
189 if slice_hdr.first_mb_in_slice == 0 {
190 let ret = supp.pool_u8.get_free();
192 return Err(DecoderError::AllocError);
194 let (w, h) = if ((self.disp_w + 15) & !15) == self.width && ((self.disp_h + 15) & !15) == self.height {
195 (self.disp_w, self.disp_h)
197 (self.width, self.height)
199 let tmp_vinfo = NAVideoInfo::new(w, h, false, YUV420_FORMAT);
200 let mut buf = ret.unwrap();
201 if buf.get_info() != tmp_vinfo {
202 supp.pool_u8.reset();
203 supp.pool_u8.prealloc_video(tmp_vinfo, 4)?;
204 let ret = supp.pool_u8.get_free();
206 return Err(DecoderError::AllocError);
210 self.cur_pic = Some(PictureInfo {
211 id: slice_hdr.frame_num,
214 time: NATimeInfo::new(None, None, None, 0, 0),
215 pic_type: slice_hdr.slice_type.to_frame_type(),
218 is_ref: nal_ref_idc != 0,
220 long_term: get_long_term_id(is_idr, &slice_hdr),
221 mv_info: NABufferRef::new(FrameMV::new(sps.pic_width_in_mbs, sps.pic_height_in_mbs)),
225 self.transform_8x8_mode = pps.transform_8x8_mode;
227 self.sstate.reset(sps.pic_width_in_mbs, sps.pic_height_in_mbs, slice_hdr.first_mb_in_slice);
229 let mut dst_pic = if let Some(ref pic) = self.cur_pic {
232 return Err(DecoderError::InvalidData);
234 let mut dst_frm = NASimpleVideoFrame::from_video_buf(&mut dst_pic.buf).unwrap();
235 let dst_mv_info = &mut dst_pic.mv_info;
236 if !pps.entropy_coding_mode {
237 self.has_pic = self.decode_slice_cavlc(&mut br, &slice_hdr, full_size, &mut dst_frm, dst_mv_info)?;
240 let start = br.tell() / 8;
241 let csrc = &src[start..];
242 validate!(csrc.len() >= 2);
243 let mut cabac = CABAC::new(csrc, slice_hdr.slice_type, slice_hdr.slice_qp, slice_hdr.cabac_init_idc as usize)?;
244 self.has_pic = self.decode_slice_cabac(&mut cabac, &slice_hdr, &mut dst_frm, dst_mv_info)?;
247 2 => { // slice data partition A
249 //slice id = read_ue()
250 //cat 2 slice data (all but MB layer residual)
251 return Err(DecoderError::NotImplemented);
253 3 => { // slice data partition B
254 //slice id = read_ue()
255 //if pps.redundant_pic_cnt_present { redundant_pic_cnt = read_ue() }
256 //cat 3 slice data (MB layer residual)
257 return Err(DecoderError::NotImplemented);
259 4 => { // slice data partition C
260 //slice id = read_ue()
261 //if pps.redundant_pic_cnt_present { redundant_pic_cnt = read_ue() }
262 //cat 4 slice data (MB layer residual)
263 return Err(DecoderError::NotImplemented);
267 let sps = parse_sps(&src[1..])?;
268 self.sps.push(Arc::new(sps));
271 validate!(full_size >= 8 + 16);
272 let pps = parse_pps(&src[1..], &self.sps, full_size - 8)?;
273 let mut found = false;
274 for stored_pps in self.pps.iter_mut() {
275 if stored_pps.pic_parameter_set_id == pps.pic_parameter_set_id {
276 *stored_pps = Arc::clone(&pps);
285 9 => { // access unit delimiter
287 10 => {}, //end of sequence
288 11 => {}, //end of stream
295 fn pred_mv(sstate: &mut SliceState, frame_refs: &SimplifiedSliceRefs, mb_info: &mut CurrentMBInfo, cur_id: u16, temporal_mv: bool, direct_8x8: bool) {
296 let mb_type = mb_info.mb_type;
297 if !mb_type.is_4x4() {
298 let (pw, ph) = mb_type.size();
301 if mb_type == MBType::Direct || mb_type == MBType::BSkip {
302 sstate.predict_direct_mb(frame_refs, temporal_mv, direct_8x8, cur_id);
304 for part in 0..mb_type.num_parts() {
305 if !mb_type.is_l1(part) {
307 MBType::PSkip => sstate.predict_pskip(),
308 MBType::BSkip | MBType::Direct => {
311 sstate.predict(xoff, yoff, pw, ph, 0,
312 mb_info.mv_l0[part], mb_info.ref_l0[part]);
316 if !mb_type.is_l0(part) && mb_type != MBType::BSkip && mb_type != MBType::Direct {
317 sstate.predict(xoff, yoff, pw, ph, 1, mb_info.mv_l1[part], mb_info.ref_l1[part]);
327 let sub_type = mb_info.sub_mb_type[part];
328 let mut xoff = (part & 1) * 8;
329 let mut yoff = (part & 2) * 4;
331 let (pw, ph) = sub_type.size();
332 for subpart in 0..sub_type.num_parts() {
333 if sub_type != SubMBType::Direct8x8 {
334 if !sub_type.is_l1() {
335 sstate.predict(xoff, yoff, pw, ph, 0, mb_info.mv_l0[part * 4 + subpart], mb_info.ref_l0[part]);
337 if !sub_type.is_l0() {
338 sstate.predict(xoff, yoff, pw, ph, 1, mb_info.mv_l1[part * 4 + subpart], mb_info.ref_l1[part]);
342 sstate.predict_direct_sub(frame_refs, temporal_mv, direct_8x8, cur_id, (xoff / 4) + (sblk & 1) + (yoff / 4) * 4 + (sblk & 2) * 2);
346 if xoff == orig_x + 8 {
354 #[allow(clippy::cognitive_complexity)]
355 fn handle_macroblock(&mut self, slice_hdr: &SliceHeader, mb_info: &mut CurrentMBInfo, slice_refs: &SimplifiedSliceRefs, frm: &mut NASimpleVideoFrame<u8>, mv_info: &mut FrameMV) {
356 let pps = &self.pps[self.cur_pps];
358 let qp_y = mb_info.qp_y;
359 let qpr = ((qp_y as i8) + pps.chroma_qp_index_offset).max(0).min(51) as usize;
360 let qp_u = CHROMA_QUANTS[qpr];
361 let qpb = ((qp_y as i8) + pps.second_chroma_qp_index_offset).max(0).min(51) as usize;
362 let qp_v = CHROMA_QUANTS[qpb];
364 let tx_bypass = qp_y == 0 && self.sps[self.cur_sps].qpprime_y_zero_transform_bypass;
366 self.sstate.get_cur_mb().mb_type = mb_info.mb_type.into();
367 if mb_info.mb_type != MBType::PCM {
368 self.sstate.get_cur_mb().qp_y = qp_y;
369 self.sstate.get_cur_mb().qp_u = qp_u;
370 self.sstate.get_cur_mb().qp_v = qp_v;
371 self.sstate.get_cur_mb().transform_8x8 = mb_info.transform_size_8x8;
373 let has_dc = mb_info.mb_type.is_intra16x16() && mb_info.coded[24];
375 idct_luma_dc(&mut mb_info.coeffs[24], qp_y);
377 mb_info.coeffs[i][0] = mb_info.coeffs[24][i];
381 if !mb_info.transform_size_8x8 {
382 let quant_dc = !mb_info.mb_type.is_intra16x16();
384 for (coded, coeffs) in mb_info.coded[..16].iter_mut().zip(mb_info.coeffs[..16].iter_mut()) {
388 idct_dc(coeffs, qp_y, quant_dc);
393 for (coded, coeffs) in mb_info.coded[..16].iter_mut().zip(mb_info.coeffs[..16].iter_mut()) {
395 idct_skip_dc(coeffs, qp_y);
397 idct_dc(coeffs, qp_y, quant_dc);
404 if mb_info.coded[(i & 1) * 2 + (i & 2) * 4] {
405 dequant8x8(&mut mb_info.coeffs8x8[i].coeffs, &pps.scaling_list_8x8[!mb_info.mb_type.is_intra() as usize]);
406 idct8x8(&mut mb_info.coeffs8x8[i].coeffs, qp_y);
410 } else if !mb_info.transform_size_8x8 {
412 if !mb_info.coded[i] && has_dc {
413 mb_info.coded[i] = true;
418 let qp_c = if chroma == 0 { qp_u } else { qp_v };
419 if mb_info.cbpc != 0 {
420 chroma_dc_transform(&mut mb_info.chroma_dc[chroma], qp_c);
423 let blk_no = 16 + chroma * 4 + i;
424 mb_info.coeffs[blk_no][0] = mb_info.chroma_dc[chroma][i];
425 if mb_info.coded[blk_no] {
426 idct_skip_dc(&mut mb_info.coeffs[blk_no], qp_c);
427 } else if mb_info.coeffs[blk_no][0] != 0 {
428 idct_dc(&mut mb_info.coeffs[blk_no], qp_c, false);
429 mb_info.coded[blk_no] = true;
433 if !pps.entropy_coding_mode || mb_info.mb_type.is_skip() || mb_info.mb_type.is_intra() {
434 self.sstate.reset_mb_mv();
436 if !mb_info.mb_type.is_intra() {
437 Self::pred_mv(&mut self.sstate, slice_refs, mb_info, self.cur_id, self.temporal_mv, self.sps[self.cur_sps].direct_8x8_inference);
439 if !pps.constrained_intra_pred && mb_info.mb_type != MBType::Intra4x4 && mb_info.mb_type != MBType::Intra8x8 {
440 self.sstate.fill_ipred(IntraPredMode::DC);
443 let xpos = self.sstate.mb_x * 16;
444 let ypos = self.sstate.mb_y * 16;
446 if mb_info.mb_type != MBType::PCM {
447 let weight_mode = if self.pps[self.cur_pps].weighted_pred && slice_hdr.slice_type.is_p() {
449 } else if slice_hdr.slice_type.is_b() {
450 self.pps[self.cur_pps].weighted_bipred_idc
454 recon_mb(frm, slice_hdr, mb_info, &mut self.sstate, slice_refs, &mut self.mc_dsp, weight_mode);
456 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)) {
457 dline[..16].copy_from_slice(src);
459 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)) {
460 dline[..8].copy_from_slice(src);
462 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)) {
463 dline[..8].copy_from_slice(src);
466 /*match mb_info.mb_type {
467 MBType::BSkip | MBType::Direct | MBType::B16x16(_) | MBType::B16x8(_, _) | MBType::B8x16(_, _) | MBType::B8x8 => {
468 let dstride = frm.stride[0];
469 let dst = &mut frm.data[frm.offset[0] + self.sstate.mb_x * 16 + self.sstate.mb_y * 16 * dstride..];
470 for el in dst[..16].iter_mut() { *el = 255; }
471 for row in dst.chunks_mut(dstride).skip(1).take(15) {
477 self.sstate.save_ipred_context(frm);
479 let mb_pos = self.sstate.mb_x + self.sstate.mb_y * mv_info.mb_stride;
480 let mut mb = FrameMBInfo::new();
481 mb.mb_type = mb_info.mb_type.into();
483 mb.mv[blk4] = self.sstate.get_cur_blk4(blk4).mv;
486 mb.ref_poc[blk8] = slice_refs.map_refs(self.sstate.get_cur_blk8(blk8).ref_idx);
487 mb.ref_idx[blk8] = self.sstate.get_cur_blk8(blk8).ref_idx;
489 mv_info.mbs[mb_pos] = mb;
491 if !self.deblock_skip && self.deblock_mode != 1 {
492 self.sstate.fill_deblock(slice_refs, self.deblock_mode, self.is_s);
493 loop_filter_mb(frm, &self.sstate, self.lf_alpha, self.lf_beta);
495 self.sstate.next_mb();
497 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> {
498 const INTRA_CBP: [u8; 48] = [
499 47, 31, 15, 0, 23, 27, 29, 30, 7, 11, 13, 14, 39, 43, 45, 46,
500 16, 3, 5, 10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1, 2, 4,
501 8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41
503 const INTER_CBP: [u8; 48] = [
504 0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13,
505 14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46,
506 17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41
509 let mut mb_idx = slice_hdr.first_mb_in_slice;
510 let mut mb_info = CurrentMBInfo { qp_y: slice_hdr.slice_qp, ..Default::default() };
511 let skip_type = if slice_hdr.slice_type.is_p() { MBType::PSkip } else { MBType::BSkip };
513 let slice_refs = self.frame_refs.cur_refs.clone();
514 let sslice_refs = SimplifiedSliceRefs::new(&slice_refs);
516 while br.tell() < full_size && mb_idx < self.num_mbs {
517 mb_info.coded = [false; 25];
518 mb_info.ref_l0 = [ZERO_REF; 4];
519 mb_info.ref_l1 = [ZERO_REF; 4];
520 mb_info.mv_l0 = [ZERO_MV; 16];
521 mb_info.mv_l1 = [ZERO_MV; 16];
522 mb_info.chroma_dc = [[0; 4]; 2];
526 if !slice_hdr.slice_type.is_intra() {
527 let mb_skip_run = br.read_ue()? as usize;
528 validate!(mb_idx + mb_skip_run <= self.num_mbs);
529 mb_info.mb_type = skip_type;
530 for _ in 0..mb_skip_run {
531 self.handle_macroblock(slice_hdr, &mut mb_info, &sslice_refs, frm, mv_info);
534 if mb_idx == self.num_mbs || br.tell() >= full_size {
538 if br.tell() < full_size {
539 if self.is_mbaff && ((mb_idx & 1) == 0) {
540 let _mb_field_decoding = br.read_bool()?;
542 let mut mb_type = decode_mb_type_cavlc(br, slice_hdr)?;
543 mb_info.mb_type = mb_type;
544 mb_info.transform_size_8x8 = false;
545 if mb_type == MBType::PCM {
547 for pix in self.ipcm_buf[..256 + 64 + 64].iter_mut() {
548 *pix = br.read(8)? as u8;
550 self.sstate.fill_ncoded(16);
552 if self.transform_8x8_mode && mb_type == MBType::Intra4x4 {
553 mb_info.transform_size_8x8 = br.read_bool()?;
554 if mb_info.transform_size_8x8 {
555 mb_type = MBType::Intra8x8;
556 mb_info.mb_type = MBType::Intra8x8;
559 decode_mb_pred_cavlc(br, slice_hdr, mb_type, &mut self.sstate, &mut mb_info)?;
560 let (cbpy, cbpc) = if let MBType::Intra16x16(_, cbpy, cbpc) = mb_type {
563 let cbp_id = br.read_ue()? as usize;
564 validate!(cbp_id < INTRA_CBP.len());
565 let cbp = if mb_type == MBType::Intra4x4 || mb_type == MBType::Intra8x8 {
570 if self.transform_8x8_mode && (cbp & 0xF) != 0 && mb_info.can_have_8x8_tx(self.sps[self.cur_sps].direct_8x8_inference) {
571 mb_info.transform_size_8x8 = br.read_bool()?;
573 ((cbp & 0xF), (cbp >> 4))
577 self.sstate.get_cur_mb().cbp = (cbpc << 4) | cbpy;
578 if cbpy != 0 || cbpc != 0 || mb_type.is_intra16x16() {
579 let mb_qp_delta = br.read_se()?;
580 validate!(mb_qp_delta >= -26 && mb_qp_delta <= 25);
581 let new_qp = mb_qp_delta + i32::from(mb_info.qp_y);
582 mb_info.qp_y = if new_qp < 0 {
584 } else if new_qp >= 52 {
589 mb_info.coeffs = [[0; 16]; 25];
590 if self.transform_8x8_mode {
591 mb_info.clear_coeffs8x8();
593 mb_info.chroma_dc = [[0; 4]; 2];
594 decode_residual_cavlc(br, &mut self.sstate, &mut mb_info, &self.cavlc_cb)?;
597 self.handle_macroblock(slice_hdr, &mut mb_info, &sslice_refs, frm, mv_info);
601 if let Some(ref mut pic) = self.cur_pic {
604 Ok(mb_idx == self.num_mbs)
606 fn decode_slice_cabac(&mut self, cabac: &mut CABAC, slice_hdr: &SliceHeader, frm: &mut NASimpleVideoFrame<u8>, mv_info: &mut FrameMV) -> DecoderResult<bool> {
607 let mut mb_idx = slice_hdr.first_mb_in_slice;
608 let mut prev_mb_skipped = false;
609 let skip_type = if slice_hdr.slice_type.is_p() { MBType::PSkip } else { MBType::BSkip };
610 let mut last_qp_diff = false;
612 let mut mb_info = CurrentMBInfo { qp_y: slice_hdr.slice_qp, ..Default::default() };
614 let slice_refs = self.frame_refs.cur_refs.clone();
615 let sslice_refs = SimplifiedSliceRefs::new(&slice_refs);
617 while mb_idx < self.num_mbs {
618 mb_info.coded = [false; 25];
619 mb_info.ref_l0 = [ZERO_REF; 4];
620 mb_info.ref_l1 = [ZERO_REF; 4];
621 mb_info.mv_l0 = [ZERO_MV; 16];
622 mb_info.mv_l1 = [ZERO_MV; 16];
623 mb_info.chroma_dc = [[0; 4]; 2];
626 let mb_skip = cabac_decode_mbskip(cabac, &self.sstate, slice_hdr);
628 if self.is_mbaff && (((mb_idx & 1) == 0) || (prev_mb_skipped && ((mb_idx & 1) == 1))) {
629 let _mb_field_decoding = cabac.decode_bit(70);
631 let mut mb_type = cabac_decode_mb_type(cabac, slice_hdr, &self.sstate);
632 mb_info.mb_type = mb_type;
633 mb_info.transform_size_8x8 = false;
634 if mb_type == MBType::PCM {
635 let ipcm_size = 256 + 64 + 64;
636 validate!(cabac.pos + ipcm_size <= cabac.src.len());
637 self.ipcm_buf[..ipcm_size].copy_from_slice(&cabac.src[cabac.pos..][..ipcm_size]);
638 cabac.pos += ipcm_size;
640 last_qp_diff = false;
642 if self.transform_8x8_mode && mb_type == MBType::Intra4x4 {
644 if self.sstate.get_top_mb().transform_8x8 {
647 if self.sstate.get_left_mb().transform_8x8 {
650 mb_info.transform_size_8x8 = cabac.decode_bit(399 + ctx);
651 if mb_info.transform_size_8x8 {
652 mb_type = MBType::Intra8x8;
653 mb_info.mb_type = MBType::Intra8x8;
656 decode_mb_pred_cabac(cabac, slice_hdr, mb_type, &mut self.sstate, &mut mb_info);
657 let (cbpy, cbpc) = if let MBType::Intra16x16(_, cbpy, cbpc) = mb_type {
660 decode_cbp_cabac(cabac, &self.sstate)
662 if self.transform_8x8_mode && cbpy != 0 && mb_info.can_have_8x8_tx(self.sps[self.cur_sps].direct_8x8_inference) {
664 if self.sstate.get_top_mb().transform_8x8 {
667 if self.sstate.get_left_mb().transform_8x8 {
670 mb_info.transform_size_8x8 = cabac.decode_bit(399 + ctx);
672 if mb_type.is_intra() {
673 self.sstate.get_cur_mb().cmode = mb_info.chroma_ipred;
677 self.sstate.get_cur_mb().cbp = (cbpc << 4) | cbpy;
678 if cbpy != 0 || cbpc != 0 || mb_type.is_intra16x16() {
679 let mb_qp_delta = decode_mb_qp_delta_cabac(cabac, last_qp_diff as usize);
680 validate!(mb_qp_delta >= -26 && mb_qp_delta <= 25);
681 last_qp_diff = mb_qp_delta != 0;
682 let new_qp = mb_qp_delta + i32::from(mb_info.qp_y);
683 mb_info.qp_y = if new_qp < 0 {
685 } else if new_qp >= 52 {
690 mb_info.coeffs = [[0; 16]; 25];
691 if self.transform_8x8_mode {
692 mb_info.clear_coeffs8x8();
694 mb_info.chroma_dc = [[0; 4]; 2];
695 decode_residual_cabac(cabac, &mut self.sstate, &mut mb_info);
697 last_qp_diff = false;
701 mb_info.mb_type = skip_type;
702 mb_info.transform_size_8x8 = false;
703 last_qp_diff = false;
705 self.handle_macroblock(slice_hdr, &mut mb_info, &sslice_refs, frm, mv_info);
706 prev_mb_skipped = mb_skip;
707 if !(self.is_mbaff && ((mb_idx & 1) == 0)) && cabac.decode_terminate() {
708 if let Some(ref mut pic) = self.cur_pic {
709 pic.cur_mb = mb_idx + 1;
711 return Ok(mb_idx + 1 == self.num_mbs);
715 Err(DecoderError::InvalidData)
719 impl NADecoder for H264Decoder {
720 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
721 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
722 let fmt = YUV420_FORMAT;
723 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, false, fmt));
724 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
726 let edata = info.get_extradata().unwrap();
727 //print!("edata:"); for &el in edata.iter() { print!(" {:02X}", el); } println!();
728 if edata.len() > 11 && &edata[0..4] == b"avcC" {
729 let mut mr = MemoryReader::new_read(edata.as_slice());
730 let mut br = ByteReader::new(&mut mr);
731 let mut nal_buf = Vec::new();
734 let version = br.read_byte()?;
735 validate!(version == 1);
736 let profile = br.read_byte()?;
737 let _compatibility = br.read_byte()?;
738 let _level = br.read_byte()?;
739 let b = br.read_byte()?;
740 //validate!((b & 0xFC) == 0xFC);
741 self.nal_len = (b & 3) + 1;
742 let b = br.read_byte()?;
743 //validate!((b & 0xE0) == 0xE0);
744 let num_sps = (b & 0x1F) as usize;
745 for _ in 0..num_sps {
746 let len = br.read_u16be()? as usize;
747 let offset = br.tell() as usize;
748 validate!((br.peek_byte()? & 0x1F) == 7);
749 let _size = unescape_nal(&edata[offset..][..len], &mut nal_buf);
750 self.handle_nal(&nal_buf, supp, true)?;
753 let num_pps = br.read_byte()? as usize;
754 for _ in 0..num_pps {
755 let len = br.read_u16be()? as usize;
756 let offset = br.tell() as usize;
757 validate!((br.peek_byte()? & 0x1F) == 8);
758 let _size = unescape_nal(&edata[offset..][..len], &mut nal_buf);
759 self.handle_nal(&nal_buf, supp, true)?;
764 100 | 110 | 122 | 144 => {
765 let b = br.read_byte()?;
766 // some encoders put something different here
767 if (b & 0xFC) != 0xFC {
770 // b & 3 -> chroma format
771 let b = br.read_byte()?;
772 validate!((b & 0xF8) == 0xF8);
773 // b & 7 -> luma depth minus 8
774 let b = br.read_byte()?;
775 validate!((b & 0xF8) == 0xF8);
776 // b & 7 -> chroma depth minus 8
777 let num_spsext = br.read_byte()? as usize;
778 for _ in 0..num_spsext {
779 let len = br.read_u16be()? as usize;
788 return Err(DecoderError::NotImplemented);
791 self.width = vinfo.get_width();
792 self.height = vinfo.get_height();
793 self.disp_w = self.width;
794 self.disp_h = self.height;
796 if (self.width == 0 || self.height == 0) && !self.sps.is_empty() {
797 self.width = self.sps[0].pic_width_in_mbs * 16;
798 self.height = self.sps[0].pic_height_in_mbs * 16;
801 let num_bufs = if !self.sps.is_empty() {
802 self.sps[0].num_ref_frames + 1
806 supp.pool_u8.set_dec_bufs(num_bufs);
807 supp.pool_u8.prealloc_video(NAVideoInfo::new(self.width, self.height, false, fmt), 4)?;
811 Err(DecoderError::InvalidData)
814 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
815 let src = pkt.get_buffer();
817 let mut mr = MemoryReader::new_read(&src);
818 let mut br = ByteReader::new(&mut mr);
819 let mut nal_buf = Vec::with_capacity(src.len());
820 if self.nal_len > 0 {
821 let mut skip_decoding = false;
822 if self.skip_mode != FrameSkipMode::None {
823 let mut pic_type = FrameType::I;
824 let mut is_ref = false;
825 while br.left() > 0 {
826 let size = match self.nal_len {
827 1 => br.read_byte()? as usize,
828 2 => br.read_u16be()? as usize,
829 3 => br.read_u24be()? as usize,
830 4 => br.read_u32be()? as usize,
833 validate!(br.left() >= (size as i64));
834 let offset = br.tell() as usize;
835 let size = unescape_nal(&src[offset..][..size], &mut nal_buf);
837 let nal_ref_idc = nal_buf[0] >> 5;
838 let nal_unit_type = nal_buf[0] & 0x1F;
839 if nal_unit_type == 1 || nal_unit_type == 5 {
840 let mut bitr = BitReader::new(&nal_buf[1..], BitReaderMode::BE);
841 let (first_mb, slice_type) = parse_slice_header_minimal(&mut bitr)?;
842 if first_mb == 0 && nal_ref_idc != 0 {
845 let new_type = slice_type.to_frame_type();
846 pic_type = match (pic_type, new_type) {
847 (FrameType::I, _) => new_type,
848 (_, FrameType::B) => FrameType::B,
854 match self.skip_mode {
855 FrameSkipMode::IntraOnly => {
856 skip_decoding = pic_type != FrameType::I;
858 FrameSkipMode::KeyframesOnly => {
860 skip_decoding = true;
865 br.seek(SeekFrom::Start(0))?;
867 while br.left() > 0 {
868 let size = match self.nal_len {
869 1 => br.read_byte()? as usize,
870 2 => br.read_u16be()? as usize,
871 3 => br.read_u24be()? as usize,
872 4 => br.read_u32be()? as usize,
875 validate!(br.left() >= (size as i64));
876 let offset = br.tell() as usize;
877 let _size = unescape_nal(&src[offset..][..size], &mut nal_buf);
878 self.handle_nal(nal_buf.as_slice(), supp, skip_decoding)?;
886 let (bufinfo, ftype, dts) = if self.has_pic && self.cur_pic.is_some() {
888 std::mem::swap(&mut self.cur_pic, &mut npic);
889 let cpic = npic.unwrap();
890 let ret = (NABufferType::Video(cpic.buf.clone()), cpic.pic_type, Some(u64::from(cpic.full_id)));
892 self.frame_refs.add_short_term(cpic.clone(), self.sps[self.cur_sps].num_ref_frames);
894 if let Some(lt_idx) = cpic.long_term {
895 self.frame_refs.add_long_term(lt_idx, cpic);
899 (NABufferType::None, FrameType::Skip, None)
902 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
903 frm.set_keyframe(ftype == FrameType::I);
904 if let (Some(mydts), None) = (dts, frm.get_dts()) {
905 frm.set_dts(Some(mydts));
907 if let Some(dts) = dts {
908 frm.set_id(dts as i64);
910 frm.set_frame_type(ftype);
913 fn flush(&mut self) {
917 impl NAOptionHandler for H264Decoder {
918 fn get_supported_options(&self) -> &[NAOptionDefinition] { DECODER_OPTIONS }
919 fn set_options(&mut self, options: &[NAOption]) {
920 for option in options.iter() {
921 for opt_def in DECODER_OPTIONS.iter() {
922 if opt_def.check(option).is_ok() {
923 match (option.name, &option.value) {
924 (FRAME_SKIP_OPTION, NAValue::String(ref strval)) => {
925 if let Ok(smode) = FrameSkipMode::from_str(strval) {
926 self.skip_mode = smode;
929 (DEBLOCK_SKIP_OPTION, NAValue::Bool(val)) => {
930 self.deblock_skip = *val;
938 fn query_option_value(&self, name: &str) -> Option<NAValue> {
940 FRAME_SKIP_OPTION => Some(NAValue::String(self.skip_mode.to_string())),
941 DEBLOCK_SKIP_OPTION => Some(NAValue::Bool(self.deblock_skip)),
947 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
948 Box::new(H264Decoder::new())