2 known bugs and limitations:
3 * weighted motion compensation is not implemented
4 * wrong slice boundary filtering
5 * not fully correct deblock strength selection for P/B-macroblocks
6 * scaling lists for 4x4 blocks
8 use nihav_core::codecs::*;
9 use nihav_core::io::byteio::*;
10 use nihav_core::io::bitreader::*;
11 use nihav_core::io::intcode::*;
12 use nihav_codec_support::codecs::{MV, ZERO_MV};
34 fn read_ue(&mut self) -> DecoderResult<u32>;
35 fn read_te(&mut self, range: u32) -> DecoderResult<u32>;
36 fn read_ue_lim(&mut self, max_val: u32) -> DecoderResult<u32> {
37 let val = self.read_ue()?;
38 validate!(val <= max_val);
41 fn read_se(&mut self) -> DecoderResult<i32> {
42 let val = self.read_ue()?;
44 Ok (((val >> 1) as i32) + 1)
46 Ok (-((val >> 1) as i32))
51 impl<'a> ReadUE for BitReader<'a> {
52 fn read_ue(&mut self) -> DecoderResult<u32> {
53 Ok(self.read_code(UintCodeType::GammaP)? - 1)
55 fn read_te(&mut self, range: u32) -> DecoderResult<u32> {
57 if self.read_bool()? {
63 let val = self.read_ue()?;
64 validate!(val <= range);
72 pub coeffs: [i16; 64],
77 self.coeffs = [0; 64];
81 impl Default for Coeff8x8 {
82 fn default() -> Self {
89 #[derive(Clone,Copy,Default)]
90 pub struct CurrentMBInfo {
92 pub sub_mb_type: [SubMBType; 4],
93 pub ipred: [IntraPredMode; 16],
95 pub luma_ipred: [u8; 16],
97 pub ref_l0: [PicRef; 4],
99 pub ref_l1: [PicRef; 4],
103 pub coeffs: [[i16; 16]; 25],
104 pub coeffs8x8: [Coeff8x8; 4],
105 pub chroma_dc: [[i16; 4]; 2],
106 pub coded: [bool; 25],
107 pub transform_size_8x8: bool,
111 fn clear_coeffs8x8(&mut self) {
112 for c in self.coeffs8x8.iter_mut() {
116 fn can_have_8x8_tx(&self, inference_flag: bool) -> bool {
118 MBType::Intra4x4 | MBType::Intra8x8 | MBType::Intra16x16(_, _, _) | MBType::PCM => false,
119 MBType::P8x8 | MBType::P8x8Ref0 | MBType::B8x8 => {
120 for &sub_id in self.sub_mb_type.iter() {
126 => if !inference_flag { return false; },
132 MBType::Direct => inference_flag,
138 fn get_long_term_id(is_idr: bool, slice_hdr: &SliceHeader) -> Option<usize> {
139 if is_idr && !slice_hdr.long_term_reference {
142 let marking = &slice_hdr.adaptive_ref_pic_marking;
143 for (&op, &arg) in marking.memory_management_control_op.iter().zip(marking.operation_arg.iter()).take(marking.num_ops) {
145 return Some(arg as usize);
153 info: NACodecInfoRef,
158 sps: Vec<SeqParameterSet>,
160 pps: Vec<PicParameterSet>,
163 skip_mode: FrameSkipMode,
168 cavlc_cb: CAVLCTables,
172 cur_pic: Option<PictureInfo>,
175 frame_refs: FrameRefs,
183 ipcm_buf: [u8; 256 + 64 + 64],
185 avg_buf: NAVideoBufferRef<u8>,
187 transform_8x8_mode: bool,
190 fn unescape_nal(src: &[u8], dst: &mut Vec<u8>) -> usize {
194 dst.reserve(src.len());
195 while off < src.len() {
201 if zrun == 2 && off + 1 < src.len() && src[off + 1] == 0x03 {
205 if zrun >= 3 && off + 1 < src.len() && src[off + 1] == 0x01 {
218 let avg_vi = NAVideoInfo { width: 32, height: 32, flipped: false, format: YUV420_FORMAT, bits: 12 };
219 let avg_buf = alloc_video_buffer(avg_vi, 4).unwrap().get_vbuf().unwrap();
221 info: NACodecInfoRef::default(),
226 sps: Vec::with_capacity(1),
228 pps: Vec::with_capacity(3),
231 skip_mode: FrameSkipMode::default(),
236 cavlc_cb: CAVLCTables::new(),
238 sstate: SliceState::new(),
242 frame_refs: FrameRefs::new(),
250 ipcm_buf: [0; 256 + 64 + 64],
254 transform_8x8_mode: false,
257 fn handle_nal(&mut self, src: &[u8], supp: &mut NADecoderSupport, skip_decoding: bool) -> DecoderResult<()> {
258 validate!(!src.is_empty());
259 validate!((src[0] & 0x80) == 0);
260 let nal_ref_idc = src[0] >> 5;
261 let nal_unit_type = src[0] & 0x1F;
263 let mut full_size = src.len() * 8;
264 for &byte in src.iter().rev() {
268 full_size -= (byte.trailing_zeros() + 1) as usize;
272 validate!(full_size > 0);
273 match nal_unit_type {
274 1 | 5 if !skip_decoding => {
275 let is_idr = nal_unit_type == 5;
276 let mut br = BitReader::new(&src[..(full_size + 7)/8], BitReaderMode::BE);
279 let slice_hdr = parse_slice_header(&mut br, &self.sps, &self.pps, is_idr, nal_ref_idc)?;
280 validate!(br.tell() < full_size);
282 if slice_hdr.first_mb_in_slice == 0 {
283 validate!(self.cur_pic.is_none());
284 for (i, pps) in self.pps.iter().enumerate() {
285 if pps.pic_parameter_set_id == slice_hdr.pic_parameter_set_id {
290 for (i, sps) in self.sps.iter().enumerate() {
291 if sps.seq_parameter_set_id == self.pps[self.cur_pps].seq_parameter_set_id {
297 full_id = self.frame_refs.calc_picture_num(&slice_hdr, is_idr, nal_ref_idc, &self.sps[self.cur_sps]);
299 let sps = &self.sps[self.cur_sps];
300 if sps.chroma_format_idc != 1 || sps.bit_depth_luma != 8 || sps.bit_depth_chroma != 8 {
301 println!(" chroma fmt {} bits {}/{}", sps.chroma_format_idc, sps.bit_depth_luma, sps.bit_depth_chroma);
302 return Err(DecoderError::NotImplemented);
304 //let pps = &self.pps[self.cur_pps];
307 self.frame_refs.clear_refs();
310 self.width = sps.pic_width_in_mbs << 4;
311 self.height = sps.pic_height_in_mbs << 4;
312 self.num_mbs = sps.pic_width_in_mbs * sps.pic_height_in_mbs;
314 self.is_mbaff = sps.mb_adaptive_frame_field && !slice_hdr.field_pic;
317 return Err(DecoderError::NotImplemented);
319 if !sps.frame_mbs_only {
321 return Err(DecoderError::NotImplemented);
324 //if slice_hdr.slice_type.is_b() { return Ok(()); }
325 self.cur_id = full_id as u16;
327 if let Some(ref mut pic) = self.cur_pic {
328 validate!(pic.cur_mb == slice_hdr.first_mb_in_slice);
329 let new_type = slice_hdr.slice_type.to_frame_type();
330 pic.pic_type = match (pic.pic_type, new_type) {
331 (FrameType::I, _) => new_type,
332 (_, FrameType::B) => FrameType::B,
335 full_id = pic.full_id;
337 return Ok(());//Err(DecoderError::InvalidData);
339 validate!(self.cur_pps < self.pps.len() && self.pps[self.cur_pps].pic_parameter_set_id == slice_hdr.pic_parameter_set_id);
342 let sps = &self.sps[self.cur_sps];
343 let pps = &self.pps[self.cur_pps];
345 self.temporal_mv = !slice_hdr.direct_spatial_mv_pred;
346 self.is_s = slice_hdr.slice_type == SliceType::SI || slice_hdr.slice_type == SliceType::SP;
347 self.deblock_mode = slice_hdr.disable_deblocking_filter_idc;
348 self.lf_alpha = slice_hdr.slice_alpha_c0_offset;
349 self.lf_beta = slice_hdr.slice_beta_offset;
351 self.frame_refs.select_refs(sps, &slice_hdr, full_id);
353 if slice_hdr.adaptive_ref_pic_marking_mode {
354 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)?;
356 if slice_hdr.first_mb_in_slice == 0 {
357 let ret = supp.pool_u8.get_free();
359 return Err(DecoderError::AllocError);
361 let tmp_vinfo = NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT);
362 let mut buf = ret.unwrap();
363 if buf.get_info() != tmp_vinfo {
364 supp.pool_u8.reset();
365 supp.pool_u8.prealloc_video(tmp_vinfo, 4)?;
366 let ret = supp.pool_u8.get_free();
368 return Err(DecoderError::AllocError);
372 self.cur_pic = Some(PictureInfo {
373 id: slice_hdr.frame_num,
375 pic_type: slice_hdr.slice_type.to_frame_type(),
378 is_ref: nal_ref_idc != 0,
379 long_term: get_long_term_id(is_idr, &slice_hdr),
380 mv_info: FrameMV::new(sps.pic_width_in_mbs, sps.pic_height_in_mbs),
384 self.transform_8x8_mode = pps.transform_8x8_mode;
386 self.sstate.reset(sps.pic_width_in_mbs, sps.pic_height_in_mbs, slice_hdr.first_mb_in_slice);
387 if !pps.entropy_coding_mode {
388 self.has_pic = self.decode_slice_cavlc(&mut br, &slice_hdr, full_size)?;
391 let start = (br.tell() / 8) as usize;
392 let csrc = &src[start..];
393 validate!(csrc.len() >= 2);
394 let mut cabac = CABAC::new(csrc, slice_hdr.slice_type, slice_hdr.slice_qp, slice_hdr.cabac_init_idc as usize)?;
395 self.has_pic = self.decode_slice_cabac(&mut cabac, &slice_hdr)?;
397 if !self.deblock_skip && self.deblock_mode != 1 {
398 if let Some(ref mut pic) = self.cur_pic {
399 let mut frm = NASimpleVideoFrame::from_video_buf(&mut pic.buf).unwrap();
400 if self.sstate.mb_x != 0 {
401 loop_filter_row(&mut frm, &self.sstate, self.lf_alpha, self.lf_beta);
403 loop_filter_last(&mut frm, &self.sstate, self.lf_alpha, self.lf_beta);
407 2 => { // slice data partition A
409 //slice id = read_ue()
410 //cat 2 slice data (all but MB layer residual)
411 return Err(DecoderError::NotImplemented);
413 3 => { // slice data partition B
414 //slice id = read_ue()
415 //if pps.redundant_pic_cnt_present { redundant_pic_cnt = read_ue() }
416 //cat 3 slice data (MB layer residual)
417 return Err(DecoderError::NotImplemented);
419 4 => { // slice data partition C
420 //slice id = read_ue()
421 //if pps.redundant_pic_cnt_present { redundant_pic_cnt = read_ue() }
422 //cat 4 slice data (MB layer residual)
423 return Err(DecoderError::NotImplemented);
427 let sps = parse_sps(&src[1..])?;
431 validate!(full_size >= 8 + 16);
432 let pps = parse_pps(&src[1..], &self.sps, full_size - 8)?;
433 let mut found = false;
434 for stored_pps in self.pps.iter_mut() {
435 if stored_pps.pic_parameter_set_id == pps.pic_parameter_set_id {
436 *stored_pps = pps.clone();
445 9 => { // access unit delimiter
447 10 => {}, //end of sequence
448 11 => {}, //end of stream
455 fn pred_intra(frm: &mut NASimpleVideoFrame<u8>, sstate: &SliceState, mb_info: &CurrentMBInfo) {
456 let yoff = frm.offset[0] + sstate.mb_x * 16 + sstate.mb_y * 16 * frm.stride[0];
457 match mb_info.mb_type {
458 MBType::Intra16x16(imode, _, _) => {
459 let id = if imode != 2 || (sstate.has_top && sstate.has_left) {
461 } else if !sstate.has_top && !sstate.has_left {
463 } else if !sstate.has_left {
468 IPRED_FUNCS16X16[id](frm.data, yoff, frm.stride[0]);
470 MBType::Intra8x8 => {
471 let mut ictx = IPred8Context::new();
473 let x = (part & 1) * 2;
475 let blk4 = x + y * 4;
477 let cur_yoff = yoff + x * 4 + y * 4 * frm.stride[0];
478 let has_top = y > 0 || sstate.has_top;
479 let has_left = x > 0 || sstate.has_left;
480 let imode = mb_info.ipred[blk4];
481 let id = if imode != IntraPredMode::DC || (has_top && has_left) {
482 let im_id: u8 = imode.into();
484 } else if !has_top && !has_left {
486 } else if !has_left {
491 let mb_idx = sstate.mb_x + sstate.mb_y * sstate.mb_w;
492 let noright = (y == 2 || sstate.mb_x == sstate.mb_w - 1 || mb_idx < sstate.mb_start + sstate.mb_w) && (x == 2);
493 let has_tl = (has_top && x > 0) || (has_left && y > 0) || (x == 0 && y == 0 && sstate.mb_x > 0 && mb_idx > sstate.mb_start + sstate.mb_w);
494 if id != IPRED4_DC128 {
495 ictx.fill(frm.data, cur_yoff, frm.stride[0], has_top, has_top && !noright, has_left, has_tl);
497 IPRED_FUNCS8X8_LUMA[id](&mut frm.data[cur_yoff..], frm.stride[0], &ictx);
498 if mb_info.coded[blk4] {
499 add_coeffs8(frm.data, cur_yoff, frm.stride[0], &mb_info.coeffs8x8[part].coeffs);
503 MBType::Intra4x4 => {
504 for &(x,y) in I4X4_SCAN.iter() {
507 let cur_yoff = yoff + x * 4 + y * 4 * frm.stride[0];
508 let has_top = y > 0 || sstate.has_top;
509 let has_left = x > 0 || sstate.has_left;
510 let imode = mb_info.ipred[x + y * 4];
511 let id = if imode != IntraPredMode::DC || (has_top && has_left) {
512 let im_id: u8 = imode.into();
514 } else if !has_top && !has_left {
516 } else if !has_left {
521 let noright = (sstate.mb_x == sstate.mb_w - 1 || sstate.mb_x + sstate.mb_y * sstate.mb_w < sstate.mb_start + sstate.mb_w) && (x == 3);
522 let tr: [u8; 4] = if y == 0 {
523 if has_top && !noright {
524 let i = cur_yoff - frm.stride[0];
525 [frm.data[i + 4], frm.data[i + 5], frm.data[i + 6], frm.data[i + 7]]
527 let i = cur_yoff - frm.stride[0];
528 [frm.data[i + 3], frm.data[i + 3], frm.data[i + 3], frm.data[i + 3]]
532 } else if (x & 1) == 0 || (x == 1 && y == 2) {
533 let i = cur_yoff - frm.stride[0];
534 [frm.data[i + 4], frm.data[i + 5], frm.data[i + 6], frm.data[i + 7]]
536 let i = cur_yoff - frm.stride[0];
537 [frm.data[i + 3], frm.data[i + 3], frm.data[i + 3], frm.data[i + 3]]
539 IPRED_FUNCS4X4[id](frm.data, cur_yoff, frm.stride[0], &tr);
540 if mb_info.coded[x + y * 4] {
541 add_coeffs(frm.data, cur_yoff, frm.stride[0], &mb_info.coeffs[x + y * 4]);
547 let id = if mb_info.chroma_ipred != 0 || (sstate.has_top && sstate.has_left) {
548 mb_info.chroma_ipred as usize
549 } else if !sstate.has_top && !sstate.has_left {
551 } else if !sstate.has_left {
557 let off = frm.offset[chroma] + sstate.mb_x * 8 + sstate.mb_y * 8 * frm.stride[chroma];
558 IPRED_FUNCS8X8_CHROMA[id](frm.data, off, frm.stride[chroma]);
561 fn add_luma(frm: &mut NASimpleVideoFrame<u8>, sstate: &SliceState, mb_info: &CurrentMBInfo) {
562 let mut yoff = frm.offset[0] + sstate.mb_x * 16 + sstate.mb_y * 16 * frm.stride[0];
563 if !mb_info.transform_size_8x8 {
566 if mb_info.coded[x + y * 4] {
567 add_coeffs(frm.data, yoff + x * 4, frm.stride[0], &mb_info.coeffs[x + y * 4]);
570 yoff += frm.stride[0] * 4;
575 if mb_info.coded[x * 2 + y * 2 * 4] {
576 add_coeffs8(frm.data, yoff + x * 8, frm.stride[0], &mb_info.coeffs8x8[x + y * 2].coeffs);
579 yoff += frm.stride[0] * 8;
583 fn add_chroma(frm: &mut NASimpleVideoFrame<u8>, sstate: &SliceState, mb_info: &CurrentMBInfo) {
585 let mut off = frm.offset[chroma] + sstate.mb_x * 8 + sstate.mb_y * 8 * frm.stride[chroma];
588 let blk_no = 16 + (chroma - 1) * 4 + x + y * 2;
589 if mb_info.coded[blk_no] || mb_info.coeffs[blk_no][0] != 0 {
590 add_coeffs(frm.data, off + x * 4, frm.stride[chroma], &mb_info.coeffs[blk_no]);
593 off += frm.stride[chroma] * 4;
597 fn pred_mv(sstate: &mut SliceState, frame_refs: &FrameRefs, mb_info: &mut CurrentMBInfo, cur_id: u16, temporal_mv: bool) {
598 let mb_type = mb_info.mb_type;
599 if !mb_type.is_4x4() {
600 let (pw, ph) = mb_type.size();
603 if mb_type == MBType::Direct || mb_type == MBType::BSkip {
604 sstate.predict_direct_mb(frame_refs, temporal_mv, cur_id);
606 for part in 0..mb_type.num_parts() {
607 if !mb_type.is_l1(part) {
609 MBType::PSkip => sstate.predict_pskip(),
610 MBType::BSkip | MBType::Direct => {
613 sstate.predict(xoff, yoff, pw, ph, 0,
614 mb_info.mv_l0[part], mb_info.ref_l0[part]);
618 if !mb_type.is_l0(part) && mb_type != MBType::BSkip && mb_type != MBType::Direct {
619 sstate.predict(xoff, yoff, pw, ph, 1, mb_info.mv_l1[part], mb_info.ref_l1[part]);
629 let sub_type = mb_info.sub_mb_type[part];
630 let mut xoff = (part & 1) * 8;
631 let mut yoff = (part & 2) * 4;
633 let (pw, ph) = sub_type.size();
634 for subpart in 0..sub_type.num_parts() {
635 if sub_type != SubMBType::Direct8x8 {
636 if !sub_type.is_l1() {
637 sstate.predict(xoff, yoff, pw, ph, 0, mb_info.mv_l0[part * 4 + subpart], mb_info.ref_l0[part]);
639 if !sub_type.is_l0() {
640 sstate.predict(xoff, yoff, pw, ph, 1, mb_info.mv_l1[part * 4 + subpart], mb_info.ref_l1[part]);
644 sstate.predict_direct_sub(frame_refs, temporal_mv, cur_id, (xoff / 4) + (sblk & 1) + (yoff / 4) * 4 + (sblk & 2) * 2);
648 if xoff == orig_x + 8 {
656 fn handle_macroblock(&mut self, mb_info: &mut CurrentMBInfo) {
657 let pps = &self.pps[self.cur_pps];
659 let qp_y = mb_info.qp_y;
660 let qpr = ((qp_y as i8) + pps.chroma_qp_index_offset).max(0).min(51) as usize;
661 let qp_u = CHROMA_QUANTS[qpr];
662 let qpb = ((qp_y as i8) + pps.second_chroma_qp_index_offset).max(0).min(51) as usize;
663 let qp_v = CHROMA_QUANTS[qpb];
665 let tx_bypass = qp_y == 0 && self.sps[self.cur_sps].qpprime_y_zero_transform_bypass;
667 self.sstate.get_cur_mb().mb_type = mb_info.mb_type.into();
668 if mb_info.mb_type != MBType::PCM {
669 self.sstate.get_cur_mb().qp_y = qp_y;
670 self.sstate.get_cur_mb().qp_u = qp_u;
671 self.sstate.get_cur_mb().qp_v = qp_v;
672 self.sstate.get_cur_mb().transform_8x8 = mb_info.transform_size_8x8;
674 let has_dc = mb_info.mb_type.is_intra16x16() && mb_info.coded[24];
676 idct_luma_dc(&mut mb_info.coeffs[24], qp_y);
678 mb_info.coeffs[i][0] = mb_info.coeffs[24][i];
681 if !mb_info.transform_size_8x8 {
682 let quant_dc = !mb_info.mb_type.is_intra16x16();
684 if mb_info.coded[i] {
686 idct(&mut mb_info.coeffs[i], qp_y, quant_dc);
690 idct_dc(&mut mb_info.coeffs[i], qp_y, quant_dc);
692 mb_info.coded[i] = true;
697 if mb_info.coded[(i & 1) * 2 + (i & 2) * 4] && !tx_bypass {
698 dequant8x8(&mut mb_info.coeffs8x8[i].coeffs, &pps.scaling_list_8x8[!mb_info.mb_type.is_intra() as usize]);
699 idct8x8(&mut mb_info.coeffs8x8[i].coeffs, qp_y);
704 let qp_c = if chroma == 0 { qp_u } else { qp_v };
705 if mb_info.cbpc != 0 {
706 chroma_dc_transform(&mut mb_info.chroma_dc[chroma], qp_c);
709 let blk_no = 16 + chroma * 4 + i;
710 mb_info.coeffs[blk_no][0] = mb_info.chroma_dc[chroma][i];
711 if mb_info.coded[blk_no] {
712 idct(&mut mb_info.coeffs[blk_no], qp_c, false);
713 } else if mb_info.coeffs[blk_no][0] != 0 {
714 idct_dc(&mut mb_info.coeffs[blk_no], qp_c, false);
715 mb_info.coded[blk_no] = true;
719 if !pps.entropy_coding_mode || mb_info.mb_type.is_skip() || mb_info.mb_type.is_intra() {
720 self.sstate.reset_mb_mv();
722 if !mb_info.mb_type.is_intra() {
723 Self::pred_mv(&mut self.sstate, &self.frame_refs, mb_info, self.cur_id, self.temporal_mv);
725 if !pps.constrained_intra_pred && mb_info.mb_type != MBType::Intra4x4 && mb_info.mb_type != MBType::Intra8x8 {
726 self.sstate.fill_ipred(IntraPredMode::DC);
729 let xpos = self.sstate.mb_x * 16;
730 let ypos = self.sstate.mb_y * 16;
731 if let Some(ref mut pic) = self.cur_pic {
732 let mut frm = NASimpleVideoFrame::from_video_buf(&mut pic.buf).unwrap();
733 match mb_info.mb_type {
734 MBType::Intra16x16(_, _, _) => {
735 Self::pred_intra(&mut frm, &self.sstate, &mb_info);
737 MBType::Intra4x4 | MBType::Intra8x8 => {
738 Self::pred_intra(&mut frm, &self.sstate, &mb_info);
742 let mv = self.sstate.get_cur_blk4(0).mv[0];
743 let rpic = self.frame_refs.select_ref_pic(0, 0);
744 Self::do_p_mc(&mut frm, xpos, ypos, 16, 16, mv, rpic);
747 let mv = self.sstate.get_cur_blk4(0).mv[0];
748 let rpic = self.frame_refs.select_ref_pic(0, mb_info.ref_l0[0].index());
749 Self::do_p_mc(&mut frm, xpos, ypos, 16, 16, mv, rpic);
751 MBType::P16x8 | MBType::P8x16 => {
752 let (bw, bh, bx, by) = if mb_info.mb_type == MBType::P16x8 {
757 let mv = self.sstate.get_cur_blk4(0).mv[0];
758 let rpic = self.frame_refs.select_ref_pic(0, mb_info.ref_l0[0].index());
759 Self::do_p_mc(&mut frm, xpos, ypos, bw, bh, mv, rpic);
760 let mv = self.sstate.get_cur_blk4(bx / 4 + by).mv[0];
761 let rpic = self.frame_refs.select_ref_pic(0, mb_info.ref_l0[1].index());
762 Self::do_p_mc(&mut frm, xpos + bx, ypos + by, bw, bh, mv, rpic);
764 MBType::P8x8 | MBType::P8x8Ref0 => {
766 let bx = (part & 1) * 8;
767 let by = (part & 2) * 4;
768 if let Some(buf) = self.frame_refs.select_ref_pic(0, mb_info.ref_l0[part].index()) {
769 let mv = self.sstate.get_cur_blk4(bx / 4 + by).mv[0];
771 match mb_info.sub_mb_type[part] {
773 do_mc(&mut frm, buf, xpos + bx, ypos + by, 8, 8, mv);
776 do_mc(&mut frm, buf.clone(), xpos + bx, ypos + by, 8, 4, mv);
777 let mv = self.sstate.get_cur_blk4(bx / 4 + by + 4).mv[0];
778 do_mc(&mut frm, buf, xpos + bx, ypos + by + 4, 8, 4, mv);
781 do_mc(&mut frm, buf.clone(), xpos + bx, ypos + by, 4, 8, mv);
782 let mv = self.sstate.get_cur_blk4(bx / 4 + by + 1).mv[0];
783 do_mc(&mut frm, buf, xpos + bx + 4, ypos + by, 4, 8, mv);
787 let sxpos = xpos + bx + (sb_no & 1) * 4;
788 let sypos = ypos + by + (sb_no & 2) * 2;
789 let sblk_no = (bx / 4 + (sb_no & 1)) + ((by / 4) + (sb_no >> 1)) * 4;
790 let mv = self.sstate.get_cur_blk4(sblk_no).mv[0];
791 do_mc(&mut frm, buf.clone(), sxpos, sypos, 4, 4, mv);
797 gray_block(&mut frm, xpos + bx, ypos + by, 8, 8);
801 MBType::B16x16(mode) => {
802 let mv0 = self.sstate.get_cur_blk4(0).mv[0];
803 let rpic0 = self.frame_refs.select_ref_pic(0, mb_info.ref_l0[0].index());
804 let mv1 = self.sstate.get_cur_blk4(0).mv[1];
805 let rpic1 = self.frame_refs.select_ref_pic(1, mb_info.ref_l1[0].index());
806 Self::do_b_mc(&mut frm, mode, xpos, ypos, 16, 16, mv0, rpic0, mv1, rpic1, &mut self.avg_buf);
808 MBType::B16x8(mode0, mode1) | MBType::B8x16(mode0, mode1) => {
809 let (pw, ph) = mb_info.mb_type.size();
810 let (px, py) = (pw & 8, ph & 8);
811 let modes = [mode0, mode1];
812 let (mut bx, mut by) = (0, 0);
814 let blk = if part == 0 { 0 } else { (px / 4) + py };
815 let mv0 = self.sstate.get_cur_blk4(blk).mv[0];
816 let rpic0 = self.frame_refs.select_ref_pic(0, mb_info.ref_l0[part].index());
817 let mv1 = self.sstate.get_cur_blk4(blk).mv[1];
818 let rpic1 = self.frame_refs.select_ref_pic(1, mb_info.ref_l1[part].index());
819 Self::do_b_mc(&mut frm, modes[part], xpos + bx, ypos + by, pw, ph, mv0, rpic0, mv1, rpic1, &mut self.avg_buf);
824 MBType::Direct | MBType::BSkip => {
825 let is_16x16 = self.frame_refs.get_colocated_info(self.sstate.mb_x, self.sstate.mb_y).0.mb_type.is_16x16();
826 if is_16x16 || !self.temporal_mv {
827 let mv = self.sstate.get_cur_blk4(0).mv;
828 let ref_idx = self.sstate.get_cur_blk8(0).ref_idx;
829 let rpic0 = self.frame_refs.select_ref_pic(0, ref_idx[0].index());
830 let rpic1 = self.frame_refs.select_ref_pic(1, ref_idx[1].index());
831 Self::do_b_mc(&mut frm, BMode::Bi, xpos, ypos, 16, 16, mv[0], rpic0, mv[1], rpic1, &mut self.avg_buf);
834 let mv = self.sstate.get_cur_blk4(blk4).mv;
835 let ref_idx = self.sstate.get_cur_blk8(blk4_to_blk8(blk4)).ref_idx;
836 let rpic0 = self.frame_refs.select_ref_pic(0, ref_idx[0].index());
837 let rpic1 = self.frame_refs.select_ref_pic(1, ref_idx[1].index());
838 Self::do_b_mc(&mut frm, BMode::Bi, xpos + (blk4 & 3) * 4, ypos + (blk4 >> 2) * 4, 4, 4, mv[0], rpic0, mv[1], rpic1, &mut self.avg_buf);
841 self.sstate.apply_to_blk8(|blk8| { blk8.ref_idx[0].set_direct(); blk8.ref_idx[1].set_direct(); });
845 let ridx = self.sstate.get_cur_blk8(part).ref_idx;
846 let rpic0 = self.frame_refs.select_ref_pic(0, ridx[0].index());
847 let rpic1 = self.frame_refs.select_ref_pic(1, ridx[1].index());
848 let subtype = mb_info.sub_mb_type[part];
849 let blk8 = (part & 1) * 2 + (part & 2) * 4;
850 let mut bx = (part & 1) * 8;
851 let mut by = (part & 2) * 4;
853 SubMBType::Direct8x8 => {
855 let mv = self.sstate.get_cur_blk4(bx / 4 + (by / 4) * 4).mv;
856 let ref_idx = self.sstate.get_cur_blk8(bx / 8 + (by / 8) * 2).ref_idx;
857 let rpic0 = self.frame_refs.select_ref_pic(0, ref_idx[0].index());
858 let rpic1 = self.frame_refs.select_ref_pic(1, ref_idx[1].index());
859 Self::do_b_mc(&mut frm, BMode::Bi, xpos + bx, ypos + by, 4, 4, mv[0], rpic0, mv[1], rpic1, &mut self.avg_buf);
866 self.sstate.get_cur_blk8(part).ref_idx[0].set_direct();
867 self.sstate.get_cur_blk8(part).ref_idx[1].set_direct();
869 SubMBType::B8x8(mode) => {
870 let mv = self.sstate.get_cur_blk4(blk8).mv;
871 Self::do_b_mc(&mut frm, mode, xpos + bx, ypos + by, 8, 8, mv[0], rpic0, mv[1], rpic1, &mut self.avg_buf);
873 SubMBType::B8x4(mode) | SubMBType::B4x8(mode) => {
874 let (pw, ph) = subtype.size();
875 let mv = self.sstate.get_cur_blk4(blk8).mv;
876 Self::do_b_mc(&mut frm, mode, xpos + bx, ypos + by, pw, ph, mv[0], rpic0.clone(), mv[1], rpic1.clone(), &mut self.avg_buf);
877 let addr2 = blk8 + (pw & 4) / 4 + (ph & 4);
878 let mv = self.sstate.get_cur_blk4(addr2).mv;
879 Self::do_b_mc(&mut frm, mode, xpos + bx + (pw & 4), ypos + by + (ph & 4), pw, ph, mv[0], rpic0, mv[1], rpic1, &mut self.avg_buf);
881 SubMBType::B4x4(mode) => {
883 let addr2 = blk8 + (i & 1) + (i & 2) * 2;
884 let mv = self.sstate.get_cur_blk4(addr2).mv;
885 Self::do_b_mc(&mut frm, mode, xpos + bx, ypos + by, 4, 4, mv[0], rpic0.clone(), mv[1], rpic1.clone(), &mut self.avg_buf);
898 if mb_info.mb_type == MBType::PCM {
899 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)) {
900 dline[..16].copy_from_slice(src);
902 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)) {
903 dline[..8].copy_from_slice(src);
905 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)) {
906 dline[..8].copy_from_slice(src);
908 } else if !mb_info.mb_type.is_skip() {
909 if mb_info.mb_type != MBType::Intra4x4 && mb_info.mb_type != MBType::Intra8x8 {
910 Self::add_luma(&mut frm, &self.sstate, &mb_info);
912 Self::add_chroma(&mut frm, &self.sstate, &mb_info);
914 /*match mb_info.mb_type {
915 MBType::BSkip | MBType::Direct | MBType::B16x16(_) | MBType::B16x8(_, _) | MBType::B8x16(_, _) | MBType::B8x8 => {
916 let dstride = frm.stride[0];
917 let dst = &mut frm.data[frm.offset[0] + self.sstate.mb_x * 16 + self.sstate.mb_y * 16 * dstride..];
918 for el in dst[..16].iter_mut() { *el = 255; }
919 for row in dst.chunks_mut(dstride).skip(1).take(15) {
926 if let Some(ref mut pic) = self.cur_pic {
927 let mv_info = &mut pic.mv_info;
928 let mb_pos = self.sstate.mb_x + self.sstate.mb_y * mv_info.mb_stride;
929 let mut mb = FrameMBInfo::new();
930 mb.mb_type = mb_info.mb_type.into();
932 mb.mv[blk4] = self.sstate.get_cur_blk4(blk4).mv;
935 mb.ref_poc[blk8] = self.frame_refs.map_refs(self.sstate.get_cur_blk8(blk8).ref_idx);
936 mb.ref_idx[blk8] = self.sstate.get_cur_blk8(blk8).ref_idx;
938 mv_info.mbs[mb_pos] = mb;
940 self.sstate.fill_deblock(self.deblock_mode, self.is_s);
941 if !self.deblock_skip && self.sstate.mb_x + 1 == self.sstate.mb_w && self.deblock_mode != 1 {
942 if let Some(ref mut pic) = self.cur_pic {
943 let mut frm = NASimpleVideoFrame::from_video_buf(&mut pic.buf).unwrap();
944 loop_filter_row(&mut frm, &self.sstate, self.lf_alpha, self.lf_beta);
947 self.sstate.next_mb();
949 fn do_p_mc(frm: &mut NASimpleVideoFrame<u8>, xpos: usize, ypos: usize, w: usize, h: usize, mv: MV, ref_pic: Option<NAVideoBufferRef<u8>>) {
950 if let Some(buf) = ref_pic {
951 do_mc(frm, buf, xpos, ypos, w, h, mv);
953 gray_block(frm, xpos, ypos, w, h);
956 fn do_b_mc(frm: &mut NASimpleVideoFrame<u8>, mode: BMode, xpos: usize, ypos: usize, w: usize, h: usize, mv0: MV, ref_pic0: Option<NAVideoBufferRef<u8>>, mv1: MV, ref_pic1: Option<NAVideoBufferRef<u8>>, avg_buf: &mut NAVideoBufferRef<u8>) {
959 if let Some(buf) = ref_pic0 {
960 do_mc(frm, buf, xpos, ypos, w, h, mv0);
962 gray_block(frm, xpos, ypos, w, h);
966 if let Some(buf) = ref_pic1 {
967 do_mc(frm, buf, xpos, ypos, w, h, mv1);
969 gray_block(frm, xpos, ypos, w, h);
973 match (ref_pic0, ref_pic1) {
974 (Some(buf0), Some(buf1)) => {
975 do_mc(frm, buf0, xpos, ypos, w, h, mv0);
976 do_mc_avg(frm, buf1, xpos, ypos, w, h, mv1, avg_buf);
978 (Some(buf0), None) => {
979 do_mc(frm, buf0, xpos, ypos, w, h, mv0);
981 (None, Some(buf1)) => {
982 do_mc(frm, buf1, xpos, ypos, w, h, mv1);
985 gray_block(frm, xpos, ypos, w, h);
991 fn decode_slice_cavlc(&mut self, br: &mut BitReader, slice_hdr: &SliceHeader, full_size: usize) -> DecoderResult<bool> {
992 const INTRA_CBP: [u8; 48] = [
993 47, 31, 15, 0, 23, 27, 29, 30, 7, 11, 13, 14, 39, 43, 45, 46,
994 16, 3, 5, 10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1, 2, 4,
995 8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41
997 const INTER_CBP: [u8; 48] = [
998 0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13,
999 14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46,
1000 17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41
1003 let mut mb_idx = slice_hdr.first_mb_in_slice as usize;
1004 let mut mb_info = CurrentMBInfo::default();
1005 mb_info.qp_y = slice_hdr.slice_qp;
1006 let skip_type = if slice_hdr.slice_type.is_p() { MBType::PSkip } else { MBType::BSkip };
1007 while br.tell() < full_size && mb_idx < self.num_mbs {
1008 mb_info.coded = [false; 25];
1009 mb_info.ref_l0 = [ZERO_REF; 4];
1010 mb_info.ref_l1 = [ZERO_REF; 4];
1011 mb_info.mv_l0 = [ZERO_MV; 16];
1012 mb_info.mv_l1 = [ZERO_MV; 16];
1013 mb_info.chroma_dc = [[0; 4]; 2];
1017 if !slice_hdr.slice_type.is_intra() {
1018 let mb_skip_run = br.read_ue()? as usize;
1019 validate!(mb_idx + mb_skip_run <= self.num_mbs);
1020 mb_info.mb_type = skip_type;
1021 for _ in 0..mb_skip_run {
1022 self.handle_macroblock(&mut mb_info);
1025 if mb_idx == self.num_mbs || br.tell() >= full_size {
1029 if br.tell() < full_size {
1030 if self.is_mbaff && ((mb_idx & 1) == 0) {
1031 let _mb_field_decoding = br.read_bool()?;
1033 let mut mb_type = decode_mb_type_cavlc(br, slice_hdr)?;
1034 mb_info.mb_type = mb_type;
1035 mb_info.transform_size_8x8 = false;
1036 if mb_type == MBType::PCM {
1038 for pix in self.ipcm_buf[..256 + 64 + 64].iter_mut() {
1039 *pix = br.read(8)? as u8;
1041 self.sstate.fill_ncoded(16);
1043 if self.transform_8x8_mode && mb_type == MBType::Intra4x4 {
1044 mb_info.transform_size_8x8 = br.read_bool()?;
1045 if mb_info.transform_size_8x8 {
1046 mb_type = MBType::Intra8x8;
1047 mb_info.mb_type = MBType::Intra8x8;
1050 decode_mb_pred_cavlc(br, slice_hdr, mb_type, &mut self.sstate, &mut mb_info)?;
1051 let (cbpy, cbpc) = if let MBType::Intra16x16(_, cbpy, cbpc) = mb_type {
1054 let cbp_id = br.read_ue()? as usize;
1055 validate!(cbp_id < INTRA_CBP.len());
1056 let cbp = if mb_type == MBType::Intra4x4 || mb_type == MBType::Intra8x8 {
1061 if self.transform_8x8_mode && (cbp & 0xF) != 0 && mb_info.can_have_8x8_tx(self.sps[self.cur_sps].direct_8x8_inference) {
1062 mb_info.transform_size_8x8 = br.read_bool()?;
1064 ((cbp & 0xF), (cbp >> 4))
1066 mb_info.cbpy = cbpy;
1067 mb_info.cbpc = cbpc;
1068 self.sstate.get_cur_mb().cbp = (cbpc << 4) | cbpy;
1069 if cbpy != 0 || cbpc != 0 || mb_type.is_intra16x16() {
1070 let mb_qp_delta = br.read_se()?;
1071 validate!(mb_qp_delta >= -26 && mb_qp_delta <= 25);
1072 let new_qp = mb_qp_delta + i32::from(mb_info.qp_y);
1073 mb_info.qp_y = if new_qp < 0 {
1075 } else if new_qp >= 52 {
1080 mb_info.coeffs = [[0; 16]; 25];
1081 if self.transform_8x8_mode {
1082 mb_info.clear_coeffs8x8();
1084 mb_info.chroma_dc = [[0; 4]; 2];
1085 decode_residual_cavlc(br, &mut self.sstate, &mut mb_info, &self.cavlc_cb)?;
1088 self.handle_macroblock(&mut mb_info);
1092 if let Some(ref mut pic) = self.cur_pic {
1093 pic.cur_mb = mb_idx;
1095 Ok(mb_idx == self.num_mbs)
1097 fn decode_slice_cabac(&mut self, cabac: &mut CABAC, slice_hdr: &SliceHeader) -> DecoderResult<bool> {
1098 let mut mb_idx = slice_hdr.first_mb_in_slice as usize;
1099 let mut prev_mb_skipped = false;
1100 let skip_type = if slice_hdr.slice_type.is_p() { MBType::PSkip } else { MBType::BSkip };
1101 let mut last_qp_diff = false;
1103 let mut mb_info = CurrentMBInfo::default();
1104 mb_info.qp_y = slice_hdr.slice_qp;
1106 while mb_idx < self.num_mbs {
1107 mb_info.coded = [false; 25];
1108 mb_info.ref_l0 = [ZERO_REF; 4];
1109 mb_info.ref_l1 = [ZERO_REF; 4];
1110 mb_info.mv_l0 = [ZERO_MV; 16];
1111 mb_info.mv_l1 = [ZERO_MV; 16];
1112 mb_info.chroma_dc = [[0; 4]; 2];
1115 let mb_skip = cabac_decode_mbskip(cabac, &self.sstate, slice_hdr);
1117 if self.is_mbaff && (((mb_idx & 1) == 0) || (prev_mb_skipped && ((mb_idx & 1) == 1))) {
1118 let _mb_field_decoding = cabac.decode_bit(70);
1120 let mut mb_type = cabac_decode_mb_type(cabac, &slice_hdr, &self.sstate);
1121 mb_info.mb_type = mb_type;
1122 mb_info.transform_size_8x8 = false;
1123 if mb_type == MBType::PCM {
1124 let ipcm_size = 256 + 64 + 64;
1125 validate!(cabac.pos + ipcm_size <= cabac.src.len());
1126 self.ipcm_buf[..ipcm_size].copy_from_slice(&cabac.src[cabac.pos..][..ipcm_size]);
1127 cabac.pos += ipcm_size;
1129 last_qp_diff = false;
1131 if self.transform_8x8_mode && mb_type == MBType::Intra4x4 {
1133 if self.sstate.get_top_mb().transform_8x8 {
1136 if self.sstate.get_left_mb().transform_8x8 {
1139 mb_info.transform_size_8x8 = cabac.decode_bit(399 + ctx);
1140 if mb_info.transform_size_8x8 {
1141 mb_type = MBType::Intra8x8;
1142 mb_info.mb_type = MBType::Intra8x8;
1145 decode_mb_pred_cabac(cabac, slice_hdr, mb_type, &mut self.sstate, &mut mb_info);
1146 let (cbpy, cbpc) = if let MBType::Intra16x16(_, cbpy, cbpc) = mb_type {
1149 decode_cbp_cabac(cabac, &self.sstate)
1151 if self.transform_8x8_mode && cbpy != 0 && mb_info.can_have_8x8_tx(self.sps[self.cur_sps].direct_8x8_inference) {
1153 if self.sstate.get_top_mb().transform_8x8 {
1156 if self.sstate.get_left_mb().transform_8x8 {
1159 mb_info.transform_size_8x8 = cabac.decode_bit(399 + ctx);
1161 if mb_type.is_intra() {
1162 self.sstate.get_cur_mb().cmode = mb_info.chroma_ipred;
1164 mb_info.cbpy = cbpy;
1165 mb_info.cbpc = cbpc;
1166 self.sstate.get_cur_mb().cbp = (cbpc << 4) | cbpy;
1167 if cbpy != 0 || cbpc != 0 || mb_type.is_intra16x16() {
1168 let mb_qp_delta = decode_mb_qp_delta_cabac(cabac, last_qp_diff as usize);
1169 validate!(mb_qp_delta >= -26 && mb_qp_delta <= 25);
1170 last_qp_diff = mb_qp_delta != 0;
1171 let new_qp = mb_qp_delta + i32::from(mb_info.qp_y);
1172 mb_info.qp_y = if new_qp < 0 {
1174 } else if new_qp >= 52 {
1179 mb_info.coeffs = [[0; 16]; 25];
1180 if self.transform_8x8_mode {
1181 mb_info.clear_coeffs8x8();
1183 mb_info.chroma_dc = [[0; 4]; 2];
1184 decode_residual_cabac(cabac, &mut self.sstate, &mut mb_info);
1186 last_qp_diff = false;
1190 mb_info.mb_type = skip_type;
1191 mb_info.transform_size_8x8 = false;
1192 last_qp_diff = false;
1194 self.handle_macroblock(&mut mb_info);
1195 prev_mb_skipped = mb_skip;
1196 if !(self.is_mbaff && ((mb_idx & 1) == 0)) && cabac.decode_terminate() {
1197 if let Some(ref mut pic) = self.cur_pic {
1198 pic.cur_mb = mb_idx + 1;
1200 return Ok(mb_idx + 1 == self.num_mbs);
1204 Err(DecoderError::InvalidData)
1208 impl NADecoder for H264Decoder {
1209 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
1210 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
1211 let fmt = YUV420_FORMAT;
1212 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, false, fmt));
1213 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
1215 let edata = info.get_extradata().unwrap();
1216 //print!("edata:"); for &el in edata.iter() { print!(" {:02X}", el); } println!();
1217 if edata.len() > 11 && &edata[0..4] == b"avcC" {
1218 let mut mr = MemoryReader::new_read(edata.as_slice());
1219 let mut br = ByteReader::new(&mut mr);
1220 let mut nal_buf = Vec::new();
1223 let version = br.read_byte()?;
1224 validate!(version == 1);
1225 let profile = br.read_byte()?;
1226 let _compatibility = br.read_byte()?;
1227 let _level = br.read_byte()?;
1228 let b = br.read_byte()?;
1229 validate!((b & 0xFC) == 0xFC);
1230 self.nal_len = (b & 3) + 1;
1231 let b = br.read_byte()?;
1232 validate!((b & 0xE0) == 0xE0);
1233 let num_sps = (b & 0x1F) as usize;
1234 for _ in 0..num_sps {
1235 let len = br.read_u16be()? as usize;
1236 let offset = br.tell() as usize;
1237 validate!((br.peek_byte()? & 0x1F) == 7);
1238 let _size = unescape_nal(&edata[offset..][..len], &mut nal_buf);
1239 self.handle_nal(&nal_buf, supp, true)?;
1242 let num_pps = br.read_byte()? as usize;
1243 for _ in 0..num_pps {
1244 let len = br.read_u16be()? as usize;
1245 let offset = br.tell() as usize;
1246 validate!((br.peek_byte()? & 0x1F) == 8);
1247 let _size = unescape_nal(&edata[offset..][..len], &mut nal_buf);
1248 self.handle_nal(&nal_buf, supp, true)?;
1253 100 | 110 | 122 | 144 => {
1254 let b = br.read_byte()?;
1255 validate!((b & 0xFC) == 0xFC);
1256 // b & 3 -> chroma format
1257 let b = br.read_byte()?;
1258 validate!((b & 0xF8) == 0xF8);
1259 // b & 7 -> luma depth minus 8
1260 let b = br.read_byte()?;
1261 validate!((b & 0xF8) == 0xF8);
1262 // b & 7 -> chroma depth minus 8
1263 let num_spsext = br.read_byte()? as usize;
1264 for _ in 0..num_spsext {
1265 let len = br.read_u16be()? as usize;
1274 return Err(DecoderError::NotImplemented);
1277 self.width = vinfo.get_width();
1278 self.height = vinfo.get_height();
1280 if (self.width == 0 || self.height == 0) && !self.sps.is_empty() {
1281 self.width = self.sps[0].pic_width_in_mbs * 16;
1282 self.height = self.sps[0].pic_height_in_mbs * 16;
1285 let num_bufs = if !self.sps.is_empty() {
1286 self.sps[0].num_ref_frames as usize + 1
1290 supp.pool_u8.set_dec_bufs(num_bufs);
1291 supp.pool_u8.prealloc_video(NAVideoInfo::new(self.width, self.height, false, fmt), 4)?;
1296 Err(DecoderError::InvalidData)
1299 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
1300 let src = pkt.get_buffer();
1302 let mut mr = MemoryReader::new_read(&src);
1303 let mut br = ByteReader::new(&mut mr);
1304 let mut nal_buf = Vec::with_capacity(src.len());
1305 if self.nal_len > 0 {
1306 let mut skip_decoding = false;
1307 if self.skip_mode != FrameSkipMode::None {
1308 let mut pic_type = FrameType::I;
1309 let mut is_ref = false;
1310 while br.left() > 0 {
1311 let size = match self.nal_len {
1312 1 => br.read_byte()? as usize,
1313 2 => br.read_u16be()? as usize,
1314 3 => br.read_u24be()? as usize,
1315 4 => br.read_u32be()? as usize,
1316 _ => unreachable!(),
1318 validate!(br.left() >= (size as i64));
1319 let offset = br.tell() as usize;
1320 let size = unescape_nal(&src[offset..][..size], &mut nal_buf);
1321 validate!(size > 0);
1322 let nal_ref_idc = nal_buf[0] >> 5;
1323 let nal_unit_type = nal_buf[0] & 0x1F;
1324 if nal_unit_type == 1 || nal_unit_type == 5 {
1325 let mut bitr = BitReader::new(&nal_buf[1..], BitReaderMode::BE);
1326 let (first_mb, slice_type) = parse_slice_header_minimal(&mut bitr)?;
1327 if first_mb == 0 && nal_ref_idc != 0 {
1330 let new_type = slice_type.to_frame_type();
1331 pic_type = match (pic_type, new_type) {
1332 (FrameType::I, _) => new_type,
1333 (_, FrameType::B) => FrameType::B,
1337 br.read_skip(size)?;
1339 match self.skip_mode {
1340 FrameSkipMode::IntraOnly => {
1341 skip_decoding = pic_type != FrameType::I;
1343 FrameSkipMode::KeyframesOnly => {
1345 skip_decoding = true;
1350 br.seek(SeekFrom::Start(0))?;
1352 while br.left() > 0 {
1353 let size = match self.nal_len {
1354 1 => br.read_byte()? as usize,
1355 2 => br.read_u16be()? as usize,
1356 3 => br.read_u24be()? as usize,
1357 4 => br.read_u32be()? as usize,
1358 _ => unreachable!(),
1360 validate!(br.left() >= (size as i64));
1361 let offset = br.tell() as usize;
1362 let _size = unescape_nal(&src[offset..][..size], &mut nal_buf);
1363 self.handle_nal(nal_buf.as_slice(), supp, skip_decoding)?;
1364 br.read_skip(size)?;
1367 //todo NAL detection
1371 let (bufinfo, ftype, dts) = if self.has_pic && self.cur_pic.is_some() {
1372 let mut npic = None;
1373 std::mem::swap(&mut self.cur_pic, &mut npic);
1374 let cpic = npic.unwrap();
1375 let ret = (NABufferType::Video(cpic.buf.clone()), cpic.pic_type, Some(u64::from(cpic.full_id)));
1377 self.frame_refs.add_short_term(cpic.clone(), self.sps[self.cur_sps].num_ref_frames);
1379 if let Some(lt_idx) = cpic.long_term {
1380 self.frame_refs.add_long_term(lt_idx, cpic);
1384 (NABufferType::None, FrameType::Skip, None)
1387 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
1388 frm.set_keyframe(ftype == FrameType::I);
1389 if let (Some(mydts), None) = (dts, frm.get_dts()) {
1390 frm.set_dts(Some(mydts));
1392 if let Some(dts) = dts {
1393 frm.set_id(dts as i64);
1395 frm.set_frame_type(ftype);
1398 fn flush(&mut self) {
1402 const DEBLOCK_SKIP_OPTION: &str = "skip_deblock";
1404 const DECODER_OPTIONS: &[NAOptionDefinition] = &[
1405 NAOptionDefinition {
1406 name: FRAME_SKIP_OPTION, description: FRAME_SKIP_OPTION_DESC,
1407 opt_type: NAOptionDefinitionType::Bool },
1408 NAOptionDefinition {
1409 name: DEBLOCK_SKIP_OPTION, description: "Loop filter skipping mode",
1410 opt_type: NAOptionDefinitionType::String(Some(&[
1411 FRAME_SKIP_OPTION_VAL_NONE,
1412 FRAME_SKIP_OPTION_VAL_KEYFRAME,
1413 FRAME_SKIP_OPTION_VAL_INTRA
1417 impl NAOptionHandler for H264Decoder {
1418 fn get_supported_options(&self) -> &[NAOptionDefinition] { DECODER_OPTIONS }
1419 fn set_options(&mut self, options: &[NAOption]) {
1420 for option in options.iter() {
1421 for opt_def in DECODER_OPTIONS.iter() {
1422 if opt_def.check(option).is_ok() {
1423 match (option.name, &option.value) {
1424 (FRAME_SKIP_OPTION, NAValue::String(ref str)) => {
1425 if let Ok(smode) = FrameSkipMode::from_str(str) {
1426 self.skip_mode = smode;
1429 (DEBLOCK_SKIP_OPTION, NAValue::Bool(val)) => {
1430 self.deblock_skip = *val;
1438 fn query_option_value(&self, name: &str) -> Option<NAValue> {
1440 FRAME_SKIP_OPTION => Some(NAValue::String(self.skip_mode.to_string())),
1441 DEBLOCK_SKIP_OPTION => Some(NAValue::Bool(self.deblock_skip)),
1447 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
1448 Box::new(H264Decoder::new())
1453 use nihav_core::codecs::RegisteredDecoders;
1454 use nihav_core::demuxers::RegisteredDemuxers;
1455 use nihav_codec_support::test::dec_video::*;
1456 use crate::itu_register_all_decoders;
1457 use nihav_commonfmt::generic_register_all_demuxers;
1461 use self::raw_demux::RawH264DemuxerCreator;
1464 fn test_h264_perframe() {
1465 let mut dmx_reg = RegisteredDemuxers::new();
1466 dmx_reg.add_demuxer(&RawH264DemuxerCreator{});
1467 generic_register_all_demuxers(&mut dmx_reg);
1468 let mut dec_reg = RegisteredDecoders::new();
1469 itu_register_all_decoders(&mut dec_reg);
1471 test_decoding("rawh264", "h264",
1472 "assets/ITU/h264-conformance/CABAST3_Sony_E.jsv",
1473 None, &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
1474 [0x85fc4b44, 0xc9aefdc9, 0x568d0592, 0x2eccf9a0],
1475 [0xbd8d11bc, 0x97acf592, 0x45a3cdbb, 0xa254a882],
1476 [0xbda0e0b9, 0x9fbe1974, 0x1540b244, 0x46a050ca],
1477 [0x471f0057, 0x125ef3b4, 0x4a87515f, 0xba254bbb],
1478 [0x466a7df2, 0xb392c2a4, 0xed66b68b, 0xfdaad2da],
1479 [0x96334b41, 0x41bac7ef, 0xe87154f1, 0xa5fc3551],
1480 [0x0fd4e9b8, 0x4269bbec, 0x00a1978f, 0xe6224851],
1481 [0x68be82af, 0x856615a7, 0x387a253d, 0x8473e6b9],
1482 [0xc4bed119, 0x14ba7fe0, 0x447cb680, 0x555da4c5],
1483 [0x85d127d6, 0x04b85928, 0x26740281, 0x4d848db5],
1484 [0xe44fe461, 0x0d0b64ce, 0xf191179b, 0xabdab686],
1485 [0x347c8edb, 0x847ad11f, 0x8f16b84e, 0xdc915d75],
1486 [0xeb1364a6, 0x91c9d99d, 0x324f5427, 0xcc9f11a2],
1487 [0x7aeb5a3f, 0xebc9c4dd, 0x8f12c8e4, 0x37a2db97],
1488 [0xa11e5c33, 0x656df4c0, 0x1e8b98d8, 0x1736722f],
1489 [0x239f2ef2, 0xe32b0603, 0x448366bb, 0x9331051c],
1490 [0x1815a1b1, 0xfb7e7cf0, 0xd5c7dd5b, 0x0135a8fb],
1491 [0xea3b85dd, 0xa96e7015, 0xa91c576d, 0x5c127ca1],
1492 [0x1c49148f, 0x6d9e7045, 0x093f0b7c, 0x42c2ebaa],
1493 [0x4b4c2863, 0x95709d8c, 0xeb72e251, 0x096632dc],
1494 [0x727418e5, 0x2c015383, 0x59580212, 0x0302dd99],
1495 [0xbe57dfa4, 0xf2aa7d70, 0xa068ee62, 0x77372861],
1496 [0x2faef43a, 0x73da6654, 0xb9d9c22e, 0xc59520bc],
1497 [0x138cff40, 0x3e6c108a, 0xa981e654, 0x903da85b],
1498 [0xa90454f5, 0x7875d5db, 0xbab234bd, 0xe6ce1193]]));
1502 fn test_h264_real1() {
1503 let mut dmx_reg = RegisteredDemuxers::new();
1504 dmx_reg.add_demuxer(&RawH264DemuxerCreator{});
1505 generic_register_all_demuxers(&mut dmx_reg);
1506 let mut dec_reg = RegisteredDecoders::new();
1507 itu_register_all_decoders(&mut dec_reg);
1509 test_decoding("mov", "h264", "assets/ITU/1.mp4",
1510 Some(60), &dmx_reg, &dec_reg,
1511 ExpectedTestResult::MD5Frames(vec![
1512 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1513 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1514 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1515 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1516 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1517 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1518 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1519 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1520 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1521 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1522 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1523 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1524 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1525 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1526 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1527 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1528 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1529 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1530 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1531 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1532 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1533 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1534 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1535 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1536 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1537 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1538 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1539 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1540 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1541 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1542 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1543 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1544 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1545 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1546 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1547 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1548 [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970],
1549 [0xf1c88c12, 0x7da871f5, 0xdaf3153f, 0x66e72d72],
1550 [0x3d4765f1, 0x8ac472f6, 0x7ffd13a6, 0xc7a45dae],
1551 [0x60e5e13a, 0xd2d7f239, 0x1a793d71, 0x19f8c190],
1552 [0xdd80c3e4, 0xb1500149, 0x43925280, 0x9e5f3230],
1553 [0x2adf6e64, 0x39012d45, 0x7a776cb5, 0x3df76e84],
1554 [0x44319007, 0xbc837dd2, 0x486b2703, 0x451d0651],
1555 [0x922386ef, 0xaf101e9b, 0xf2094a40, 0xc8c454c0],
1556 [0x0d81e398, 0x04192a56, 0xa31f39d0, 0x5e0a2deb],
1557 [0xcdd144b3, 0xd1c7743e, 0x5753b0f4, 0xc070efa9],
1558 [0xe1c67e39, 0x6065ddaf, 0x576bf9f1, 0x8e6825aa],
1559 [0xaf817b0d, 0xdc6c345a, 0xf7f289c7, 0x6cc482d8],
1560 [0x81dc4bcb, 0xee4fc5e5, 0x9b87c7ef, 0xdd0fb034],
1561 [0x8b07f523, 0x4168799f, 0x990cb270, 0x858b9f2c],
1562 [0x31855a80, 0xadbcc562, 0xe60628be, 0x5f04be09],
1563 [0x9c614acc, 0xbd08a3f4, 0x91b02c45, 0x41899a83],
1564 [0x89d09064, 0xbff810a3, 0x9c674179, 0x305225a6],
1565 [0xba1fc8d3, 0x15d34fae, 0x565d363b, 0x4f4d0604],
1566 [0x1cb15a1b, 0xa0be111e, 0x45cc801f, 0x01a2c691],
1567 [0xd898be48, 0xd19bf58d, 0xe22fe44f, 0x6a2914fb],
1568 [0xec6712af, 0xa13b55c0, 0x2915a746, 0xb29a5c48],
1569 [0x745798fa, 0x4ef0f882, 0x59335c08, 0xb1d9dbb4],
1570 [0x4045b495, 0xdb3d969c, 0x1f0d9220, 0x5a34067b],
1571 [0x94fee093, 0x78ad89b3, 0xf20e882b, 0x941425db],
1572 [0xc3eb1a78, 0x4b4e098a, 0xcbcf9bb4, 0xfd5b5426]]));
1575 fn test_h264_real2() {
1576 let mut dmx_reg = RegisteredDemuxers::new();
1577 dmx_reg.add_demuxer(&RawH264DemuxerCreator{});
1578 generic_register_all_demuxers(&mut dmx_reg);
1579 let mut dec_reg = RegisteredDecoders::new();
1580 itu_register_all_decoders(&mut dec_reg);
1581 test_decoding("mov", "h264", "assets/ITU/DimpledSpanishCuckoo-mobile.mp4",
1582 Some(10), &dmx_reg, &dec_reg,
1583 ExpectedTestResult::MD5Frames(vec![
1584 [0x1addcb8e, 0xde58b857, 0x17222c32, 0x75455fa8],
1585 [0xae63141a, 0x79435b2e, 0xfe606c48, 0xf676da66],
1586 [0xfdb80404, 0x6a288e23, 0x45cc4106, 0xdd5eb57c],
1587 [0xd603a3ff, 0x872dcb9b, 0x43f7a71c, 0x2ad4eecc],
1588 [0x639ed6a5, 0xbb1cfec6, 0x0ee5443a, 0x1694772a],
1589 [0xf8ef3f48, 0x152de238, 0xb1995f9a, 0xf82ad1d5],
1590 [0x604f6265, 0xb9d82f56, 0x21f00cf4, 0xc69c18a7],
1591 [0xd932c16e, 0x25cbf060, 0xcb66543b, 0xfe8a5019],
1592 [0xf2a3dac0, 0x0f4678dd, 0xf64c8228, 0x47f14676],
1593 [0x267041ee, 0x3b6b8b64, 0x8bfe1697, 0x1fba508b],
1594 [0x9f917e72, 0x75d882a9, 0xa5e3e684, 0x4ed87eff]]));
1598 pub const I4X4_SCAN: [(u8, u8); 16] = [
1599 (0,0), (1,0), (0,1), (1,1), (2,0), (3,0), (2,1), (3,1),
1600 (0,2), (1,2), (0,3), (1,3), (2,2), (3,2), (2,3), (3,3)