3 use nihav_core::codecs::*;
4 use nihav_core::io::bitreader::*;
14 sps: Vec<Arc<SeqParameterSet>>,
16 pps: Vec<Arc<PicParameterSet>>,
19 skip_mode: FrameSkipMode,
24 cavlc_cb: CAVLCTables,
28 cur_pic: Option<PictureInfo>,
31 frame_refs: FrameRefs,
39 ipcm_buf: [u8; 256 + 64 + 64],
43 transform_8x8_mode: bool,
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();
51 info: NACodecInfoRef::default(),
56 sps: Vec::with_capacity(1),
58 pps: Vec::with_capacity(3),
61 skip_mode: FrameSkipMode::default(),
66 cavlc_cb: CAVLCTables::new(),
68 sstate: SliceState::new(),
72 frame_refs: FrameRefs::new(),
80 ipcm_buf: [0; 256 + 64 + 64],
82 mc_dsp: H264MC::new(avg_buf),
84 transform_8x8_mode: false,
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;
93 let mut full_size = src.len() * 8;
94 for &byte in src.iter().rev() {
98 full_size -= (byte.trailing_zeros() + 1) as usize;
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);
109 let slice_hdr = parse_slice_header(&mut br, self.sps.as_slice(), self.pps.as_slice(), is_idr, nal_ref_idc)?;
110 validate!(br.tell() < full_size);
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 {
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 {
127 full_id = self.frame_refs.calc_picture_num(&slice_hdr, is_idr, nal_ref_idc, &self.sps[self.cur_sps]);
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 {
131 println!(" chroma fmt {} bits {}/{}", sps.chroma_format_idc, sps.bit_depth_luma, sps.bit_depth_chroma);
132 return Err(DecoderError::NotImplemented);
134 //let pps = &self.pps[self.cur_pps];
137 self.frame_refs.clear_refs();
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);
145 self.is_mbaff = sps.mb_adaptive_frame_field && !slice_hdr.field_pic;
148 return Err(DecoderError::NotImplemented);
150 if !sps.frame_mbs_only {
152 return Err(DecoderError::NotImplemented);
155 //if slice_hdr.slice_type.is_b() { return Ok(()); }
156 self.cur_id = full_id as u16;
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,
166 full_id = pic.full_id;
168 return Ok(());//Err(DecoderError::InvalidData);
170 validate!(self.cur_pps < self.pps.len() && self.pps[self.cur_pps].pic_parameter_set_id == slice_hdr.pic_parameter_set_id);
173 let sps = &self.sps[self.cur_sps];
174 let pps = &self.pps[self.cur_pps];
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;
182 self.frame_refs.select_refs(sps, &slice_hdr, full_id);
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)?;
187 if slice_hdr.first_mb_in_slice == 0 {
188 let ret = supp.pool_u8.get_free();
190 return Err(DecoderError::AllocError);
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();
199 return Err(DecoderError::AllocError);
203 self.cur_pic = Some(PictureInfo {
204 id: slice_hdr.frame_num,
207 time: NATimeInfo::new(None, None, None, 0, 0),
208 pic_type: slice_hdr.slice_type.to_frame_type(),
211 is_ref: nal_ref_idc != 0,
213 long_term: get_long_term_id(is_idr, &slice_hdr),
214 mv_info: NABufferRef::new(FrameMV::new(sps.pic_width_in_mbs, sps.pic_height_in_mbs)),
218 self.transform_8x8_mode = pps.transform_8x8_mode;
220 self.sstate.reset(sps.pic_width_in_mbs, sps.pic_height_in_mbs, slice_hdr.first_mb_in_slice);
221 if !pps.entropy_coding_mode {
222 self.has_pic = self.decode_slice_cavlc(&mut br, &slice_hdr, full_size)?;
225 let start = br.tell() / 8;
226 let csrc = &src[start..];
227 validate!(csrc.len() >= 2);
228 let mut cabac = CABAC::new(csrc, slice_hdr.slice_type, slice_hdr.slice_qp, slice_hdr.cabac_init_idc as usize)?;
229 self.has_pic = self.decode_slice_cabac(&mut cabac, &slice_hdr)?;
232 2 => { // slice data partition A
234 //slice id = read_ue()
235 //cat 2 slice data (all but MB layer residual)
236 return Err(DecoderError::NotImplemented);
238 3 => { // slice data partition B
239 //slice id = read_ue()
240 //if pps.redundant_pic_cnt_present { redundant_pic_cnt = read_ue() }
241 //cat 3 slice data (MB layer residual)
242 return Err(DecoderError::NotImplemented);
244 4 => { // slice data partition C
245 //slice id = read_ue()
246 //if pps.redundant_pic_cnt_present { redundant_pic_cnt = read_ue() }
247 //cat 4 slice data (MB layer residual)
248 return Err(DecoderError::NotImplemented);
252 let sps = parse_sps(&src[1..])?;
253 self.sps.push(Arc::new(sps));
256 validate!(full_size >= 8 + 16);
257 let pps = parse_pps(&src[1..], &self.sps, full_size - 8)?;
258 let mut found = false;
259 for stored_pps in self.pps.iter_mut() {
260 if stored_pps.pic_parameter_set_id == pps.pic_parameter_set_id {
261 *stored_pps = Arc::clone(&pps);
270 9 => { // access unit delimiter
272 10 => {}, //end of sequence
273 11 => {}, //end of stream
280 fn pred_mv(sstate: &mut SliceState, frame_refs: &SliceRefs, mb_info: &mut CurrentMBInfo, cur_id: u16, temporal_mv: bool, direct_8x8: bool) {
281 let mb_type = mb_info.mb_type;
282 if !mb_type.is_4x4() {
283 let (pw, ph) = mb_type.size();
286 if mb_type == MBType::Direct || mb_type == MBType::BSkip {
287 sstate.predict_direct_mb(frame_refs, temporal_mv, direct_8x8, cur_id);
289 for part in 0..mb_type.num_parts() {
290 if !mb_type.is_l1(part) {
292 MBType::PSkip => sstate.predict_pskip(),
293 MBType::BSkip | MBType::Direct => {
296 sstate.predict(xoff, yoff, pw, ph, 0,
297 mb_info.mv_l0[part], mb_info.ref_l0[part]);
301 if !mb_type.is_l0(part) && mb_type != MBType::BSkip && mb_type != MBType::Direct {
302 sstate.predict(xoff, yoff, pw, ph, 1, mb_info.mv_l1[part], mb_info.ref_l1[part]);
312 let sub_type = mb_info.sub_mb_type[part];
313 let mut xoff = (part & 1) * 8;
314 let mut yoff = (part & 2) * 4;
316 let (pw, ph) = sub_type.size();
317 for subpart in 0..sub_type.num_parts() {
318 if sub_type != SubMBType::Direct8x8 {
319 if !sub_type.is_l1() {
320 sstate.predict(xoff, yoff, pw, ph, 0, mb_info.mv_l0[part * 4 + subpart], mb_info.ref_l0[part]);
322 if !sub_type.is_l0() {
323 sstate.predict(xoff, yoff, pw, ph, 1, mb_info.mv_l1[part * 4 + subpart], mb_info.ref_l1[part]);
327 sstate.predict_direct_sub(frame_refs, temporal_mv, direct_8x8, cur_id, (xoff / 4) + (sblk & 1) + (yoff / 4) * 4 + (sblk & 2) * 2);
331 if xoff == orig_x + 8 {
339 #[allow(clippy::cognitive_complexity)]
340 fn handle_macroblock(&mut self, slice_hdr: &SliceHeader, mb_info: &mut CurrentMBInfo) {
341 let pps = &self.pps[self.cur_pps];
343 let qp_y = mb_info.qp_y;
344 let qpr = ((qp_y as i8) + pps.chroma_qp_index_offset).max(0).min(51) as usize;
345 let qp_u = CHROMA_QUANTS[qpr];
346 let qpb = ((qp_y as i8) + pps.second_chroma_qp_index_offset).max(0).min(51) as usize;
347 let qp_v = CHROMA_QUANTS[qpb];
349 let tx_bypass = qp_y == 0 && self.sps[self.cur_sps].qpprime_y_zero_transform_bypass;
351 self.sstate.get_cur_mb().mb_type = mb_info.mb_type.into();
352 if mb_info.mb_type != MBType::PCM {
353 self.sstate.get_cur_mb().qp_y = qp_y;
354 self.sstate.get_cur_mb().qp_u = qp_u;
355 self.sstate.get_cur_mb().qp_v = qp_v;
356 self.sstate.get_cur_mb().transform_8x8 = mb_info.transform_size_8x8;
358 let has_dc = mb_info.mb_type.is_intra16x16() && mb_info.coded[24];
360 idct_luma_dc(&mut mb_info.coeffs[24], qp_y);
362 mb_info.coeffs[i][0] = mb_info.coeffs[24][i];
366 if !mb_info.transform_size_8x8 {
367 let quant_dc = !mb_info.mb_type.is_intra16x16();
368 for (coded, coeffs) in mb_info.coded[..16].iter_mut().zip(mb_info.coeffs[..16].iter_mut()) {
370 idct(coeffs, qp_y, quant_dc);
372 idct_dc(coeffs, qp_y, quant_dc);
378 if mb_info.coded[(i & 1) * 2 + (i & 2) * 4] {
379 dequant8x8(&mut mb_info.coeffs8x8[i].coeffs, &pps.scaling_list_8x8[!mb_info.mb_type.is_intra() as usize]);
380 idct8x8(&mut mb_info.coeffs8x8[i].coeffs, qp_y);
384 } else if !mb_info.transform_size_8x8 {
386 if !mb_info.coded[i] && has_dc {
387 mb_info.coded[i] = true;
392 let qp_c = if chroma == 0 { qp_u } else { qp_v };
393 if mb_info.cbpc != 0 {
394 chroma_dc_transform(&mut mb_info.chroma_dc[chroma], qp_c);
397 let blk_no = 16 + chroma * 4 + i;
398 mb_info.coeffs[blk_no][0] = mb_info.chroma_dc[chroma][i];
399 if mb_info.coded[blk_no] {
400 idct(&mut mb_info.coeffs[blk_no], qp_c, false);
401 } else if mb_info.coeffs[blk_no][0] != 0 {
402 idct_dc(&mut mb_info.coeffs[blk_no], qp_c, false);
403 mb_info.coded[blk_no] = true;
407 if !pps.entropy_coding_mode || mb_info.mb_type.is_skip() || mb_info.mb_type.is_intra() {
408 self.sstate.reset_mb_mv();
410 if !mb_info.mb_type.is_intra() {
411 Self::pred_mv(&mut self.sstate, &self.frame_refs.cur_refs, mb_info, self.cur_id, self.temporal_mv, self.sps[self.cur_sps].direct_8x8_inference);
413 if !pps.constrained_intra_pred && mb_info.mb_type != MBType::Intra4x4 && mb_info.mb_type != MBType::Intra8x8 {
414 self.sstate.fill_ipred(IntraPredMode::DC);
417 let xpos = self.sstate.mb_x * 16;
418 let ypos = self.sstate.mb_y * 16;
419 if let Some(ref mut pic) = self.cur_pic {
420 let mut frm = NASimpleVideoFrame::from_video_buf(&mut pic.buf).unwrap();
421 if mb_info.mb_type != MBType::PCM {
422 let weight_mode = if self.pps[self.cur_pps].weighted_pred && slice_hdr.slice_type.is_p() {
424 } else if slice_hdr.slice_type.is_b() {
425 self.pps[self.cur_pps].weighted_bipred_idc
429 recon_mb(&mut frm, slice_hdr, mb_info, &mut self.sstate, &self.frame_refs.cur_refs, &mut self.mc_dsp, weight_mode);
431 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)) {
432 dline[..16].copy_from_slice(src);
434 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)) {
435 dline[..8].copy_from_slice(src);
437 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)) {
438 dline[..8].copy_from_slice(src);
441 /*match mb_info.mb_type {
442 MBType::BSkip | MBType::Direct | MBType::B16x16(_) | MBType::B16x8(_, _) | MBType::B8x16(_, _) | MBType::B8x8 => {
443 let dstride = frm.stride[0];
444 let dst = &mut frm.data[frm.offset[0] + self.sstate.mb_x * 16 + self.sstate.mb_y * 16 * dstride..];
445 for el in dst[..16].iter_mut() { *el = 255; }
446 for row in dst.chunks_mut(dstride).skip(1).take(15) {
452 self.sstate.save_ipred_context(&frm);
454 if let Some(ref mut pic) = self.cur_pic {
455 let mv_info = &mut pic.mv_info;
456 let mb_pos = self.sstate.mb_x + self.sstate.mb_y * mv_info.mb_stride;
457 let mut mb = FrameMBInfo::new();
458 mb.mb_type = mb_info.mb_type.into();
460 mb.mv[blk4] = self.sstate.get_cur_blk4(blk4).mv;
463 mb.ref_poc[blk8] = self.frame_refs.cur_refs.map_refs(self.sstate.get_cur_blk8(blk8).ref_idx);
464 mb.ref_idx[blk8] = self.sstate.get_cur_blk8(blk8).ref_idx;
466 mv_info.mbs[mb_pos] = mb;
468 if !self.deblock_skip && self.deblock_mode != 1 {
469 self.sstate.fill_deblock(&self.frame_refs.cur_refs, self.deblock_mode, self.is_s);
470 if let Some(ref mut pic) = self.cur_pic {
471 let mut frm = NASimpleVideoFrame::from_video_buf(&mut pic.buf).unwrap();
472 loop_filter_mb(&mut frm, &self.sstate, self.lf_alpha, self.lf_beta);
475 self.sstate.next_mb();
477 fn decode_slice_cavlc(&mut self, br: &mut BitReader, slice_hdr: &SliceHeader, full_size: usize) -> DecoderResult<bool> {
478 const INTRA_CBP: [u8; 48] = [
479 47, 31, 15, 0, 23, 27, 29, 30, 7, 11, 13, 14, 39, 43, 45, 46,
480 16, 3, 5, 10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1, 2, 4,
481 8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41
483 const INTER_CBP: [u8; 48] = [
484 0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13,
485 14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46,
486 17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41
489 let mut mb_idx = slice_hdr.first_mb_in_slice;
490 let mut mb_info = CurrentMBInfo { qp_y: slice_hdr.slice_qp, ..Default::default() };
491 let skip_type = if slice_hdr.slice_type.is_p() { MBType::PSkip } else { MBType::BSkip };
492 while br.tell() < full_size && mb_idx < self.num_mbs {
493 mb_info.coded = [false; 25];
494 mb_info.ref_l0 = [ZERO_REF; 4];
495 mb_info.ref_l1 = [ZERO_REF; 4];
496 mb_info.mv_l0 = [ZERO_MV; 16];
497 mb_info.mv_l1 = [ZERO_MV; 16];
498 mb_info.chroma_dc = [[0; 4]; 2];
502 if !slice_hdr.slice_type.is_intra() {
503 let mb_skip_run = br.read_ue()? as usize;
504 validate!(mb_idx + mb_skip_run <= self.num_mbs);
505 mb_info.mb_type = skip_type;
506 for _ in 0..mb_skip_run {
507 self.handle_macroblock(slice_hdr, &mut mb_info);
510 if mb_idx == self.num_mbs || br.tell() >= full_size {
514 if br.tell() < full_size {
515 if self.is_mbaff && ((mb_idx & 1) == 0) {
516 let _mb_field_decoding = br.read_bool()?;
518 let mut mb_type = decode_mb_type_cavlc(br, slice_hdr)?;
519 mb_info.mb_type = mb_type;
520 mb_info.transform_size_8x8 = false;
521 if mb_type == MBType::PCM {
523 for pix in self.ipcm_buf[..256 + 64 + 64].iter_mut() {
524 *pix = br.read(8)? as u8;
526 self.sstate.fill_ncoded(16);
528 if self.transform_8x8_mode && mb_type == MBType::Intra4x4 {
529 mb_info.transform_size_8x8 = br.read_bool()?;
530 if mb_info.transform_size_8x8 {
531 mb_type = MBType::Intra8x8;
532 mb_info.mb_type = MBType::Intra8x8;
535 decode_mb_pred_cavlc(br, slice_hdr, mb_type, &mut self.sstate, &mut mb_info)?;
536 let (cbpy, cbpc) = if let MBType::Intra16x16(_, cbpy, cbpc) = mb_type {
539 let cbp_id = br.read_ue()? as usize;
540 validate!(cbp_id < INTRA_CBP.len());
541 let cbp = if mb_type == MBType::Intra4x4 || mb_type == MBType::Intra8x8 {
546 if self.transform_8x8_mode && (cbp & 0xF) != 0 && mb_info.can_have_8x8_tx(self.sps[self.cur_sps].direct_8x8_inference) {
547 mb_info.transform_size_8x8 = br.read_bool()?;
549 ((cbp & 0xF), (cbp >> 4))
553 self.sstate.get_cur_mb().cbp = (cbpc << 4) | cbpy;
554 if cbpy != 0 || cbpc != 0 || mb_type.is_intra16x16() {
555 let mb_qp_delta = br.read_se()?;
556 validate!(mb_qp_delta >= -26 && mb_qp_delta <= 25);
557 let new_qp = mb_qp_delta + i32::from(mb_info.qp_y);
558 mb_info.qp_y = if new_qp < 0 {
560 } else if new_qp >= 52 {
565 mb_info.coeffs = [[0; 16]; 25];
566 if self.transform_8x8_mode {
567 mb_info.clear_coeffs8x8();
569 mb_info.chroma_dc = [[0; 4]; 2];
570 decode_residual_cavlc(br, &mut self.sstate, &mut mb_info, &self.cavlc_cb)?;
573 self.handle_macroblock(slice_hdr, &mut mb_info);
577 if let Some(ref mut pic) = self.cur_pic {
580 Ok(mb_idx == self.num_mbs)
582 fn decode_slice_cabac(&mut self, cabac: &mut CABAC, slice_hdr: &SliceHeader) -> DecoderResult<bool> {
583 let mut mb_idx = slice_hdr.first_mb_in_slice;
584 let mut prev_mb_skipped = false;
585 let skip_type = if slice_hdr.slice_type.is_p() { MBType::PSkip } else { MBType::BSkip };
586 let mut last_qp_diff = false;
588 let mut mb_info = CurrentMBInfo { qp_y: slice_hdr.slice_qp, ..Default::default() };
590 while mb_idx < self.num_mbs {
591 mb_info.coded = [false; 25];
592 mb_info.ref_l0 = [ZERO_REF; 4];
593 mb_info.ref_l1 = [ZERO_REF; 4];
594 mb_info.mv_l0 = [ZERO_MV; 16];
595 mb_info.mv_l1 = [ZERO_MV; 16];
596 mb_info.chroma_dc = [[0; 4]; 2];
599 let mb_skip = cabac_decode_mbskip(cabac, &self.sstate, slice_hdr);
601 if self.is_mbaff && (((mb_idx & 1) == 0) || (prev_mb_skipped && ((mb_idx & 1) == 1))) {
602 let _mb_field_decoding = cabac.decode_bit(70);
604 let mut mb_type = cabac_decode_mb_type(cabac, slice_hdr, &self.sstate);
605 mb_info.mb_type = mb_type;
606 mb_info.transform_size_8x8 = false;
607 if mb_type == MBType::PCM {
608 let ipcm_size = 256 + 64 + 64;
609 validate!(cabac.pos + ipcm_size <= cabac.src.len());
610 self.ipcm_buf[..ipcm_size].copy_from_slice(&cabac.src[cabac.pos..][..ipcm_size]);
611 cabac.pos += ipcm_size;
613 last_qp_diff = false;
615 if self.transform_8x8_mode && mb_type == MBType::Intra4x4 {
617 if self.sstate.get_top_mb().transform_8x8 {
620 if self.sstate.get_left_mb().transform_8x8 {
623 mb_info.transform_size_8x8 = cabac.decode_bit(399 + ctx);
624 if mb_info.transform_size_8x8 {
625 mb_type = MBType::Intra8x8;
626 mb_info.mb_type = MBType::Intra8x8;
629 decode_mb_pred_cabac(cabac, slice_hdr, mb_type, &mut self.sstate, &mut mb_info);
630 let (cbpy, cbpc) = if let MBType::Intra16x16(_, cbpy, cbpc) = mb_type {
633 decode_cbp_cabac(cabac, &self.sstate)
635 if self.transform_8x8_mode && cbpy != 0 && mb_info.can_have_8x8_tx(self.sps[self.cur_sps].direct_8x8_inference) {
637 if self.sstate.get_top_mb().transform_8x8 {
640 if self.sstate.get_left_mb().transform_8x8 {
643 mb_info.transform_size_8x8 = cabac.decode_bit(399 + ctx);
645 if mb_type.is_intra() {
646 self.sstate.get_cur_mb().cmode = mb_info.chroma_ipred;
650 self.sstate.get_cur_mb().cbp = (cbpc << 4) | cbpy;
651 if cbpy != 0 || cbpc != 0 || mb_type.is_intra16x16() {
652 let mb_qp_delta = decode_mb_qp_delta_cabac(cabac, last_qp_diff as usize);
653 validate!(mb_qp_delta >= -26 && mb_qp_delta <= 25);
654 last_qp_diff = mb_qp_delta != 0;
655 let new_qp = mb_qp_delta + i32::from(mb_info.qp_y);
656 mb_info.qp_y = if new_qp < 0 {
658 } else if new_qp >= 52 {
663 mb_info.coeffs = [[0; 16]; 25];
664 if self.transform_8x8_mode {
665 mb_info.clear_coeffs8x8();
667 mb_info.chroma_dc = [[0; 4]; 2];
668 decode_residual_cabac(cabac, &mut self.sstate, &mut mb_info);
670 last_qp_diff = false;
674 mb_info.mb_type = skip_type;
675 mb_info.transform_size_8x8 = false;
676 last_qp_diff = false;
678 self.handle_macroblock(slice_hdr, &mut mb_info);
679 prev_mb_skipped = mb_skip;
680 if !(self.is_mbaff && ((mb_idx & 1) == 0)) && cabac.decode_terminate() {
681 if let Some(ref mut pic) = self.cur_pic {
682 pic.cur_mb = mb_idx + 1;
684 return Ok(mb_idx + 1 == self.num_mbs);
688 Err(DecoderError::InvalidData)
692 impl NADecoder for H264Decoder {
693 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
694 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
695 let fmt = YUV420_FORMAT;
696 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, false, fmt));
697 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
699 let edata = info.get_extradata().unwrap();
700 //print!("edata:"); for &el in edata.iter() { print!(" {:02X}", el); } println!();
701 if edata.len() > 11 && &edata[0..4] == b"avcC" {
702 let mut mr = MemoryReader::new_read(edata.as_slice());
703 let mut br = ByteReader::new(&mut mr);
704 let mut nal_buf = Vec::new();
707 let version = br.read_byte()?;
708 validate!(version == 1);
709 let profile = br.read_byte()?;
710 let _compatibility = br.read_byte()?;
711 let _level = br.read_byte()?;
712 let b = br.read_byte()?;
713 validate!((b & 0xFC) == 0xFC);
714 self.nal_len = (b & 3) + 1;
715 let b = br.read_byte()?;
716 validate!((b & 0xE0) == 0xE0);
717 let num_sps = (b & 0x1F) as usize;
718 for _ in 0..num_sps {
719 let len = br.read_u16be()? as usize;
720 let offset = br.tell() as usize;
721 validate!((br.peek_byte()? & 0x1F) == 7);
722 let _size = unescape_nal(&edata[offset..][..len], &mut nal_buf);
723 self.handle_nal(&nal_buf, supp, true)?;
726 let num_pps = br.read_byte()? as usize;
727 for _ in 0..num_pps {
728 let len = br.read_u16be()? as usize;
729 let offset = br.tell() as usize;
730 validate!((br.peek_byte()? & 0x1F) == 8);
731 let _size = unescape_nal(&edata[offset..][..len], &mut nal_buf);
732 self.handle_nal(&nal_buf, supp, true)?;
737 100 | 110 | 122 | 144 => {
738 let b = br.read_byte()?;
739 validate!((b & 0xFC) == 0xFC);
740 // b & 3 -> chroma format
741 let b = br.read_byte()?;
742 validate!((b & 0xF8) == 0xF8);
743 // b & 7 -> luma depth minus 8
744 let b = br.read_byte()?;
745 validate!((b & 0xF8) == 0xF8);
746 // b & 7 -> chroma depth minus 8
747 let num_spsext = br.read_byte()? as usize;
748 for _ in 0..num_spsext {
749 let len = br.read_u16be()? as usize;
758 return Err(DecoderError::NotImplemented);
761 self.width = vinfo.get_width();
762 self.height = vinfo.get_height();
764 if (self.width == 0 || self.height == 0) && !self.sps.is_empty() {
765 self.width = self.sps[0].pic_width_in_mbs * 16;
766 self.height = self.sps[0].pic_height_in_mbs * 16;
769 let num_bufs = if !self.sps.is_empty() {
770 self.sps[0].num_ref_frames + 1
774 supp.pool_u8.set_dec_bufs(num_bufs);
775 supp.pool_u8.prealloc_video(NAVideoInfo::new(self.width, self.height, false, fmt), 4)?;
779 Err(DecoderError::InvalidData)
782 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
783 let src = pkt.get_buffer();
785 let mut mr = MemoryReader::new_read(&src);
786 let mut br = ByteReader::new(&mut mr);
787 let mut nal_buf = Vec::with_capacity(src.len());
788 if self.nal_len > 0 {
789 let mut skip_decoding = false;
790 if self.skip_mode != FrameSkipMode::None {
791 let mut pic_type = FrameType::I;
792 let mut is_ref = false;
793 while br.left() > 0 {
794 let size = match self.nal_len {
795 1 => br.read_byte()? as usize,
796 2 => br.read_u16be()? as usize,
797 3 => br.read_u24be()? as usize,
798 4 => br.read_u32be()? as usize,
801 validate!(br.left() >= (size as i64));
802 let offset = br.tell() as usize;
803 let size = unescape_nal(&src[offset..][..size], &mut nal_buf);
805 let nal_ref_idc = nal_buf[0] >> 5;
806 let nal_unit_type = nal_buf[0] & 0x1F;
807 if nal_unit_type == 1 || nal_unit_type == 5 {
808 let mut bitr = BitReader::new(&nal_buf[1..], BitReaderMode::BE);
809 let (first_mb, slice_type) = parse_slice_header_minimal(&mut bitr)?;
810 if first_mb == 0 && nal_ref_idc != 0 {
813 let new_type = slice_type.to_frame_type();
814 pic_type = match (pic_type, new_type) {
815 (FrameType::I, _) => new_type,
816 (_, FrameType::B) => FrameType::B,
822 match self.skip_mode {
823 FrameSkipMode::IntraOnly => {
824 skip_decoding = pic_type != FrameType::I;
826 FrameSkipMode::KeyframesOnly => {
828 skip_decoding = true;
833 br.seek(SeekFrom::Start(0))?;
835 while br.left() > 0 {
836 let size = match self.nal_len {
837 1 => br.read_byte()? as usize,
838 2 => br.read_u16be()? as usize,
839 3 => br.read_u24be()? as usize,
840 4 => br.read_u32be()? as usize,
843 validate!(br.left() >= (size as i64));
844 let offset = br.tell() as usize;
845 let _size = unescape_nal(&src[offset..][..size], &mut nal_buf);
846 self.handle_nal(nal_buf.as_slice(), supp, skip_decoding)?;
854 let (bufinfo, ftype, dts) = if self.has_pic && self.cur_pic.is_some() {
856 std::mem::swap(&mut self.cur_pic, &mut npic);
857 let cpic = npic.unwrap();
858 let ret = (NABufferType::Video(cpic.buf.clone()), cpic.pic_type, Some(u64::from(cpic.full_id)));
860 self.frame_refs.add_short_term(cpic.clone(), self.sps[self.cur_sps].num_ref_frames);
862 if let Some(lt_idx) = cpic.long_term {
863 self.frame_refs.add_long_term(lt_idx, cpic);
867 (NABufferType::None, FrameType::Skip, None)
870 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
871 frm.set_keyframe(ftype == FrameType::I);
872 if let (Some(mydts), None) = (dts, frm.get_dts()) {
873 frm.set_dts(Some(mydts));
875 if let Some(dts) = dts {
876 frm.set_id(dts as i64);
878 frm.set_frame_type(ftype);
881 fn flush(&mut self) {
885 impl NAOptionHandler for H264Decoder {
886 fn get_supported_options(&self) -> &[NAOptionDefinition] { DECODER_OPTIONS }
887 fn set_options(&mut self, options: &[NAOption]) {
888 for option in options.iter() {
889 for opt_def in DECODER_OPTIONS.iter() {
890 if opt_def.check(option).is_ok() {
891 match (option.name, &option.value) {
892 (FRAME_SKIP_OPTION, NAValue::String(ref strval)) => {
893 if let Ok(smode) = FrameSkipMode::from_str(strval) {
894 self.skip_mode = smode;
897 (DEBLOCK_SKIP_OPTION, NAValue::Bool(val)) => {
898 self.deblock_skip = *val;
906 fn query_option_value(&self, name: &str) -> Option<NAValue> {
908 FRAME_SKIP_OPTION => Some(NAValue::String(self.skip_mode.to_string())),
909 DEBLOCK_SKIP_OPTION => Some(NAValue::Bool(self.deblock_skip)),
915 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
916 Box::new(H264Decoder::new())