1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3 use nihav_codec_support::codecs::{MV, ZERO_MV};
4 use super::vpcommon::*;
6 use super::vp78data::*;
10 const PITCH_MODE_NORMAL: u8 = 0;
11 const PITCH_MODE_FOUR: u8 = 1;
12 const PITCH_MODE_X2: u8 = 2;
13 const PITCH_MODE_X4: u8 = 3;
15 #[derive(Clone,Copy,Default)]
23 coef_probs: &'a [[[[u8; 11]; 3]; 8]; 4],
24 scan: &'a [usize; 16],
28 fn decode_subblock(bc: &mut BoolCoder, coeffs: &mut [i16; 16], ctype: usize, pctx: u8, sbparams: &SBParams) -> u8 {
29 const COEF_BANDS: [usize; 16] = [ 0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7 ];
32 let start = if ctype != 0 { 0 } else { 1 };
34 let mut cval = pctx as usize;
35 for idx in start..16 {
36 let probs = &sbparams.coef_probs[ctype][COEF_BANDS[idx]][cval];
37 let tok = bc.read_tree(COEF_TREE, probs);
38 if tok == DCTToken::EOB { break; }
39 let level = expand_token(bc, tok);
40 coeffs[sbparams.scan[idx]] = level.wrapping_mul(sbparams.qmat[idx]);
41 cval = level.abs().min(2) as usize;
44 if has_nz > 0 { 1 } else { 0 }
47 #[derive(Clone,Copy,Default)]
58 features: [Option<MBFeature>; 4],
65 loop_filter_level: u8,
71 kf_ymode_prob: [u8; 4],
72 kf_uvmode_prob: [u8; 3],
77 coef_probs: [[[[u8; 11]; 3]; 8]; 4],
78 mv_probs: [[u8; 17]; 2],
80 force_quant: Option<u8>,
81 force_loop_str: Option<u8>,
82 force_gf_update: bool,
83 force_pitch: Option<u8>,
86 pdc_pred_val: [i16; 2],
87 pdc_pred_count: [usize; 2],
89 ipred_ctx_y: IPredContext,
90 ipred_ctx_u: IPredContext,
91 ipred_ctx_v: IPredContext,
96 self.kf_ymode_prob.copy_from_slice(Y_MODE_TREE_PROBS);
97 self.kf_uvmode_prob.copy_from_slice(UV_MODE_TREE_PROBS);
98 self.coef_probs.copy_from_slice(&DEFAULT_DCT_PROBS);
99 self.mv_probs.copy_from_slice(&DEFAULT_MV_PROBS);
103 fn decode_mv_component(bc: &mut BoolCoder, probs: &[u8; 17]) -> i16 {
104 const LONG_VECTOR_ORDER: [usize; 7] = [ 0, 1, 2, 7, 6, 5, 4 ];
106 let val = if !bc.read_prob(probs[0]) {
107 bc.read_tree(SMALL_MV_TREE, &probs[2..9])
109 let raw_probs = &probs[9..];
111 for ord in LONG_VECTOR_ORDER.iter() {
112 raw |= (bc.read_prob(raw_probs[*ord]) as i16) << *ord;
114 if (raw & 0xF0) != 0 {
115 raw |= (bc.read_prob(raw_probs[3]) as i16) << 3;
121 if (val == 0) || !bc.read_prob(probs[1]) {
129 info: NACodecInfoRef,
136 mb_info: Vec<MBInfo>,
140 ymodes: Vec<PredMode>,
142 uvmodes: Vec<PredMode>,
143 uvmode_stride: usize,
145 dstate: DecoderState,
148 coeffs: [[i16; 16]; 25],
150 qmat: [[[i16; 16]; 3]; 5],
152 mc_buf: NAVideoBufferRef<u8>,
154 tmp_scan: [usize; 16],
159 let vt = alloc_video_buffer(NAVideoInfo::new(128, 128, false, YUV420_FORMAT), 4).unwrap();
160 let mut scan = [0; 16];
161 scan.copy_from_slice(&DEFAULT_SCAN_ORDER);
162 let mc_buf = vt.get_vbuf().unwrap();
164 info: NACodecInfoRef::default(),
166 shuf: VPShuffler::new(),
180 dstate: DecoderState::default(),
181 pcache: PredCache::new(),
183 coeffs: [[0; 16]; 25],
186 qmat: [[[0; 16]; 3]; 5],
191 fn set_dimensions(&mut self, width: usize, height: usize) {
192 if (width == self.width) && (height == self.height) {
196 self.height = height;
197 self.mb_w = (self.width + 15) >> 4;
198 self.mb_h = (self.height + 15) >> 4;
199 self.mb_info.resize(self.mb_w * self.mb_h, MBInfo::default());
200 self.mv_stride = self.mb_w * 4;
201 self.mvs.resize(self.mv_stride * self.mb_h * 4, ZERO_MV);
203 self.ymode_stride = self.mb_w * 4;
204 self.uvmode_stride = self.mb_w;
205 self.ymodes.resize(self.ymode_stride * self.mb_h * 4, PredMode::default());
206 self.uvmodes.resize(self.uvmode_stride * self.mb_h, PredMode::default());
208 self.pcache.resize(self.mb_w);
210 fn read_features(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
211 for (i, feat) in self.dstate.features.iter_mut().enumerate() {
213 let mut feature = MBFeature::default();
214 feature.present_prob = bc.read_byte();
215 for tp in feature.tree_probs.iter_mut() {
217 *tp = bc.read_byte();
223 let fbits = match i {
226 _ => if self.dstate.version == 0 { 8 } else { 5 },
228 for dval in feature.def_val.iter_mut() {
230 *dval = bc.read_bits(fbits) as u8;
236 *feat = Some(feature);
243 fn read_dct_coef_prob_upd(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
248 if bc.read_prob(DCT_UPDATE_PROBS[i][j][k][l]) {
249 self.dstate.coef_probs[i][j][k][l] = bc.read_byte();
257 fn read_mv_prob_upd(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
260 if bc.read_prob(MV_UPDATE_PROBS[comp][i]) {
261 self.dstate.mv_probs[comp][i] = bc.read_probability();
267 fn decode_mb_features(&mut self, bc: &mut BoolCoder, _mb_x: usize, _mb_y: usize) -> DecoderResult<()> {
268 self.dstate.force_quant = None;
269 self.dstate.force_loop_str = None;
270 self.dstate.force_gf_update = false;
271 self.dstate.force_pitch = None;
272 for (i, feat) in self.dstate.features.iter().enumerate() {
273 if let Some(feat) = feat {
274 let present = bc.read_prob(feat.present_prob);
276 let ftype_idx = bc.read_tree(FEATURE_TREE, &feat.tree_probs);
277 let val = feat.def_val[ftype_idx];
279 0 => self.dstate.force_quant = Some(ftype_idx as u8),
280 1 => self.dstate.force_loop_str = Some(val),
281 2 => self.dstate.force_gf_update = true,
282 _ => self.dstate.force_pitch = Some(val),
289 fn decode_residue(&mut self, bc: &mut BoolCoder, mb_x: usize, mb_idx: usize, use_last: bool) {
290 let qmat_idx = if let Some(idx) = self.dstate.force_quant { (idx as usize) + 1 } else { 0 };
291 let mut sbparams = SBParams {
292 scan: &DEFAULT_SCAN_ORDER,
293 qmat: &self.qmat[qmat_idx][2],
294 coef_probs: &self.dstate.coef_probs,
296 let mut has_ac = [false; 25];
298 if self.dstate.has_y2 {
299 let pred = &self.pcache.y2_pred;
300 let pidx = pred.xpos + mb_x;
301 let pctx = self.pcache.y2_pred_left + pred.data[pidx - pred.stride];
303 let has_nz = decode_subblock(bc, &mut self.coeffs[24], 1, pctx, &sbparams);
304 self.pcache.y2_pred.data[pidx] = has_nz;
305 self.pcache.y2_pred_left = has_nz;
306 has_ac[24] = has_nz > 0;
310 let pred = &mut self.pcache.y2_pred;
311 let pidx = pred.xpos + mb_x;
312 pred.data[pidx] = pred.data[pidx - pred.stride];
316 sbparams.scan = &self.scan;
317 sbparams.qmat = &self.qmat[qmat_idx][0];
321 let pred = &self.pcache.y_pred;
322 let pidx = pred.xpos + mb_x * 4 + bx + by * pred.stride;
323 let pctx = self.pcache.y_pred_left[by] + pred.data[pidx - pred.stride];
325 let has_nz = decode_subblock(bc, &mut self.coeffs[i], ytype, pctx, &sbparams);
326 self.pcache.y_pred.data[pidx] = has_nz;
327 self.pcache.y_pred_left[by] = has_nz;
328 has_ac[i] = has_nz > 0;
330 sbparams.qmat = &self.qmat[qmat_idx][1];
333 let by = (i >> 1) & 1;
334 let pred = &self.pcache.u_pred;
335 let pidx = pred.xpos + mb_x * 2 + bx + by * pred.stride;
336 let pctx = self.pcache.u_pred_left[by] + pred.data[pidx - pred.stride];
338 let has_nz = decode_subblock(bc, &mut self.coeffs[i], 2, pctx, &sbparams);
339 self.pcache.u_pred.data[pidx] = has_nz;
340 self.pcache.u_pred_left[by] = has_nz;
341 has_ac[i] = has_nz > 0;
345 let by = (i >> 1) & 1;
346 let pred = &self.pcache.v_pred;
347 let pidx = pred.xpos + mb_x * 2 + bx + by * pred.stride;
348 let pctx = self.pcache.v_pred_left[by] + pred.data[pidx - pred.stride];
350 let has_nz = decode_subblock(bc, &mut self.coeffs[i], 2, pctx, &sbparams);
351 self.pcache.v_pred.data[pidx] = has_nz;
352 self.pcache.v_pred_left[by] = has_nz;
353 has_ac[i] = has_nz > 0;
356 if self.dstate.has_y2 {
357 let y2block = &mut self.coeffs[24];
358 if self.mb_info[mb_idx].mb_type != VPMBType::Intra {
359 let mut dc = y2block[0];
360 let pdc_idx = if use_last { 0 } else { 1 };
361 let pval = self.dstate.pdc_pred_val[pdc_idx];
363 if self.dstate.pdc_pred_count[pdc_idx] > 3 {
367 if (pval == 0) || (dc == 0) || ((pval ^ dc) < 0) {
368 self.dstate.pdc_pred_count[pdc_idx] = 0;
369 } else if dc == pval {
370 self.dstate.pdc_pred_count[pdc_idx] += 1;
372 self.dstate.pdc_pred_val[pdc_idx] = dc;
376 } else if y2block[0] != 0 {
380 self.coeffs[i][0] = self.coeffs[24][i];
385 idct4x4(&mut self.coeffs[i]);
386 } else if self.coeffs[i][0] != 0 {
387 idct4x4_dc(&mut self.coeffs[i]);
392 fn set_qmat(&mut self, y_dc_q: usize, y_ac_q: usize, y2_dc_q: usize, y2_ac_q: usize, uv_dc_q: usize, uv_ac_q: usize) {
393 self.qmat[0][0][0] = Y_DC_QUANTS[y_dc_q];
395 self.qmat[0][0][i] = Y_AC_QUANTS[y_ac_q];
397 self.qmat[0][1][0] = UV_DC_QUANTS[uv_dc_q];
399 self.qmat[0][1][i] = UV_AC_QUANTS[uv_ac_q];
401 self.qmat[0][2][0] = Y2_DC_QUANTS[y2_dc_q];
403 self.qmat[0][2][i] = Y2_AC_QUANTS[y2_ac_q];
405 if let Some(ref feat) = self.dstate.features[0] {
407 let q = feat.def_val[j] as usize;
408 self.qmat[j + 1][0][0] = Y_DC_QUANTS[q];
410 self.qmat[j + 1][0][i] = Y_AC_QUANTS[q];
412 self.qmat[j + 1][1][0] = UV_DC_QUANTS[q];
414 self.qmat[j + 1][1][i] = UV_AC_QUANTS[q];
416 self.qmat[j + 1][2][0] = Y2_DC_QUANTS[q];
418 self.qmat[j + 1][2][i] = Y2_AC_QUANTS[q];
423 fn fill_ymode(&mut self, mb_x: usize, mb_y: usize, ymode: PredMode) {
424 let mut iidx = mb_x * 4 + mb_y * 4 * self.ymode_stride;
427 self.ymodes[iidx + x] = ymode;
429 iidx += self.ymode_stride;
432 fn fill_mv(&mut self, mb_x: usize, mb_y: usize, mv: MV) {
433 let mut iidx = mb_x * 4 + mb_y * 4 * self.mv_stride;
436 self.mvs[iidx + x] = mv;
438 iidx += self.mb_w * 4;
441 fn find_mv_pred(&self, mb_x: usize, mb_y: usize) -> ([u8; 4], MV, MV, MV) {
442 const CAND_POS: [(i8, i8, u8, u8); 12] = [
443 (-1, 0, 8, 12), ( 0, -1, 8, 3),
444 (-1, -1, 2, 15), (-1, 1, 2, 12),
445 (-2, 0, 2, 12), ( 0, -2, 2, 3),
446 (-1, -2, 1, 15), (-2, -1, 1, 15),
447 (-2, 1, 1, 12), (-1, 2, 1, 12),
448 (-2, -2, 1, 15), (-2, 2, 1, 12)
451 let mut nearest_mv = ZERO_MV;
452 let mut near_mv = ZERO_MV;
454 let mut ct: [u8; 4] = [0; 4];
456 let start = if self.dstate.version == 0 { 1 } else { 0 };
457 let mvwrap = (self.mb_w as isize) + 1;
458 for (yoff, xoff, weight, blk_no) in CAND_POS.iter() {
459 let cx = (mb_x as isize) + (*xoff as isize);
460 let cy = (mb_y as isize) + (*yoff as isize);
461 let mvpos = cx + cy * mvwrap;
462 if (mvpos < start) || ((mvpos % mvwrap) == (mvwrap - 1)) {
466 let cx = (mvpos % mvwrap) as usize;
467 let cy = (mvpos / mvwrap) as usize;
468 let bx = (*blk_no as usize) & 3;
469 let by = (*blk_no as usize) >> 2;
470 let blk_pos = cx * 4 + bx + (cy * 4 + by) * self.mv_stride;
471 let mv = self.mvs[blk_pos];
477 if (nearest_mv == ZERO_MV) || (nearest_mv == mv) {
480 } else if near_mv == ZERO_MV {
484 idx = if mv == near_mv { 2 } else { 3 };
488 let pred_mv = if ct[1] > ct[2] {
489 if ct[1] >= ct[0] { nearest_mv } else { ZERO_MV }
491 if ct[2] >= ct[0] { near_mv } else { ZERO_MV }
494 let mvprobs = [INTER_MODE_PROBS[ct[0] as usize][0],
495 INTER_MODE_PROBS[ct[1] as usize][1],
496 INTER_MODE_PROBS[ct[2] as usize][2],
497 INTER_MODE_PROBS[ct[2] as usize][3]];
499 (mvprobs, nearest_mv, near_mv, pred_mv)
501 fn get_split_mv(&self, bc: &mut BoolCoder, mb_x: usize, mb_y: usize, bx: usize, by: usize, pred_mv: MV) -> MV {
502 let mode = bc.read_tree(SUB_MV_REF_TREE, &SUB_MV_REF_PROBS);
503 let mvidx = mb_x * 4 + bx + (mb_y * 4 + by) * self.mv_stride;
506 if (mb_x > 0) || (bx > 0) {
513 if (mb_y > 0) || (by > 0) {
514 self.mvs[mvidx - self.mv_stride]
519 SubMVRef::Zero => ZERO_MV,
521 let dmy = decode_mv_component(bc, &self.dstate.mv_probs[0]);
522 let dmx = decode_mv_component(bc, &self.dstate.mv_probs[1]);
523 pred_mv + MV{ x: dmx, y: dmy }
527 fn do_split_mv(&mut self, bc: &mut BoolCoder, mb_x: usize, mb_y: usize, pred_mv: MV) -> DecoderResult<()> {
528 let split_mode = bc.read_tree(MV_SPLIT_MODE_TREE, &MV_SPLIT_MODE_PROBS);
529 let mut mvidx = mb_x * 4 + mb_y * 4 * self.mv_stride;
531 MVSplitMode::TopBottom => {
532 let top_mv = self.get_split_mv(bc, mb_x, mb_y, 0, 0, pred_mv);
534 for x in 0..4 { self.mvs[mvidx + x] = top_mv; }
535 mvidx += self.mv_stride;
537 let bot_mv = self.get_split_mv(bc, mb_x, mb_y, 0, 2, pred_mv);
539 for x in 0..4 { self.mvs[mvidx + x] = bot_mv; }
540 mvidx += self.mv_stride;
543 MVSplitMode::LeftRight => {
544 let left_mv = self.get_split_mv(bc, mb_x, mb_y, 0, 0, pred_mv);
545 self.mvs[mvidx + 1] = left_mv;
546 let right_mv = self.get_split_mv(bc, mb_x, mb_y, 2, 0, pred_mv);
548 self.mvs[mvidx + 0] = left_mv;
549 self.mvs[mvidx + 1] = left_mv;
550 self.mvs[mvidx + 2] = right_mv;
551 self.mvs[mvidx + 3] = right_mv;
552 mvidx += self.mv_stride;
555 MVSplitMode::Quarters => {
556 for y in (0..4).step_by(2) {
557 for x in (0..4).step_by(2) {
558 self.mvs[mvidx + x] = self.get_split_mv(bc, mb_x, mb_y, x, y, pred_mv);
559 self.mvs[mvidx + x + 1] = self.mvs[mvidx + x];
562 self.mvs[mvidx + x + self.mv_stride] = self.mvs[mvidx + x];
564 mvidx += self.mv_stride * 2;
567 MVSplitMode::Sixteenths => {
570 self.mvs[mvidx + x] = self.get_split_mv(bc, mb_x, mb_y, x, y, pred_mv);
572 mvidx += self.mv_stride;
579 fn add_residue(&self, dframe: &mut NASimpleVideoFrame<u8>, mb_x: usize, mb_y: usize, do_luma: bool, pitch_mode: u8) {
581 let ydst = &mut dframe.data[dframe.offset[0]..];
582 let ystride = dframe.stride[0];
583 let mut yoff = mb_x * 16 + mb_y * 16 * ystride;
585 PITCH_MODE_NORMAL => {
588 add_coeffs4x4(ydst, yoff + x * 4, ystride, &self.coeffs[x + y * 4]);
595 add_coeffs16x1(ydst, yoff, &self.coeffs[y]);
602 add_coeffs4x4(ydst, yoff + x * 4, ystride * 2, &self.coeffs[x + y * 4]);
606 yoff -= 15 * ystride;
609 add_coeffs4x4(ydst, yoff + x * 4, ystride * 2, &self.coeffs[x + y * 4]);
617 add_coeffs4x4(ydst, yoff + x * 4, ystride * 4, &self.coeffs[x + y * 4]);
625 let dst = &mut dframe.data[0..];
626 let mut uoff = dframe.offset[1] + mb_x * 8 + mb_y * 8 * dframe.stride[1];
627 let ustride = dframe.stride[1];
628 let mut voff = dframe.offset[2] + mb_x * 8 + mb_y * 8 * dframe.stride[2];
629 let vstride = dframe.stride[2];
630 if (pitch_mode == PITCH_MODE_NORMAL) || (pitch_mode == PITCH_MODE_FOUR) {
633 add_coeffs4x4(dst, uoff + x * 4, ustride, &self.coeffs[16 + x + y * 2]);
634 add_coeffs4x4(dst, voff + x * 4, vstride, &self.coeffs[20 + x + y * 2]);
642 add_coeffs4x4(dst, uoff + x * 4, ustride * 2, &self.coeffs[16 + x + y * 2]);
643 add_coeffs4x4(dst, voff + x * 4, vstride * 2, &self.coeffs[20 + x + y * 2]);
650 fn recon_intra_mb(&mut self, dframe: &mut NASimpleVideoFrame<u8>, mb_x: usize, mb_y: usize) -> DecoderResult<()> {
651 let pitch = self.dstate.force_pitch.unwrap_or(0);
652 let pitch_mode = (pitch >> 3) & 3;
654 let mb_idx = mb_x + mb_y * self.mb_w;
655 let has_top = mb_y > 0;
656 let has_left = mb_x > 0;
657 let ydst = &mut dframe.data[dframe.offset[0]..];
658 let ystride = dframe.stride[0];
659 let mut yoff = mb_x * 16 + mb_y * 16 * ystride;
660 let ipred_ctx_y = &mut self.dstate.ipred_ctx_y;
661 ipred_ctx_y.has_top = has_top;
662 ipred_ctx_y.has_left = has_left;
663 let is_normal = self.mb_info[mb_idx].ymode != PredMode::BPred;
665 ipred_ctx_y.fill(ydst, yoff, ystride, 16, 16);
666 match self.mb_info[mb_idx].ymode {
667 PredMode::DCPred => IPred16x16::ipred_dc(ydst, yoff, ystride, ipred_ctx_y),
668 PredMode::HPred => IPred16x16::ipred_h (ydst, yoff, ystride, ipred_ctx_y),
669 PredMode::VPred => IPred16x16::ipred_v (ydst, yoff, ystride, ipred_ctx_y),
670 PredMode::TMPred => IPred16x16::ipred_tm(ydst, yoff, ystride, ipred_ctx_y),
674 validate!((pitch_mode == PITCH_MODE_NORMAL) || (pitch_mode == PITCH_MODE_X2));
675 let mut iidx = mb_x * 4 + mb_y * 4 * self.ymode_stride;
676 let mut tr_save = [0x80u8; 16];
677 if pitch_mode == PITCH_MODE_X2 {
678 // reorganise coefficient data for interlaced case
679 for y in (0..4).step_by(2) {
681 let mut tmpblock = [0i16; 16 * 2];
682 let eidx = x + y * 4;
683 let oidx = x + y * 4 + 4;
686 tmpblock[i * 8 + 0 + j] = self.coeffs[eidx][i * 4 + j];
687 tmpblock[i * 8 + 4 + j] = self.coeffs[oidx][i * 4 + j];
690 self.coeffs[eidx].copy_from_slice(&tmpblock[0..16]);
691 self.coeffs[oidx].copy_from_slice(&tmpblock[16..32]);
695 let tr_edge = if has_top { ydst[yoff - ystride + 15] } else { 0x80 };
698 ipred_ctx_y.has_left = has_left || x > 0;
699 let bmode = self.ymodes[iidx + x];
700 let cur_yoff = yoff + x * 4;
701 let has_tr = ipred_ctx_y.has_top && ((x < 3) || ((y == 0) && (mb_y < self.mb_w - 1)));
702 let has_dl = ipred_ctx_y.has_left && (x == 0) && (y < 3);
703 ipred_ctx_y.fill(ydst, cur_yoff, ystride,
704 if has_tr { 8 } else { 4 },
705 if has_dl { 8 } else { 4 });
708 ipred_ctx_y.top[i + 4] = tr_save[x * 4 + i];
712 tr_save[x * 4 + i] = ipred_ctx_y.top[i + 4];
715 if (mb_x == self.mb_w - 1) && has_top && (x == 3) {
717 ipred_ctx_y.top[i + 4] = tr_edge;
721 PredMode::DCPred => IPred4x4::ipred_dc(ydst, cur_yoff, ystride, ipred_ctx_y),
722 PredMode::TMPred => IPred4x4::ipred_tm(ydst, cur_yoff, ystride, ipred_ctx_y),
723 PredMode::HPred => IPred4x4::ipred_he(ydst, cur_yoff, ystride, ipred_ctx_y),
724 PredMode::VPred => IPred4x4::ipred_ve(ydst, cur_yoff, ystride, ipred_ctx_y),
725 PredMode::LDPred => IPred4x4::ipred_ld(ydst, cur_yoff, ystride, ipred_ctx_y),
726 PredMode::RDPred => IPred4x4::ipred_rd(ydst, cur_yoff, ystride, ipred_ctx_y),
727 PredMode::VRPred => IPred4x4::ipred_vr(ydst, cur_yoff, ystride, ipred_ctx_y),
728 PredMode::VLPred => IPred4x4::ipred_vl(ydst, cur_yoff, ystride, ipred_ctx_y),
729 PredMode::HDPred => IPred4x4::ipred_hd(ydst, cur_yoff, ystride, ipred_ctx_y),
730 PredMode::HUPred => IPred4x4::ipred_hu(ydst, cur_yoff, ystride, ipred_ctx_y),
733 add_coeffs4x4(ydst, cur_yoff, ystride, &self.coeffs[x + y * 4]);
735 ipred_ctx_y.has_top = true;
737 iidx += self.ymode_stride;
740 let dst = &mut dframe.data[0..];
741 let uoff = dframe.offset[1] + mb_x * 8 + mb_y * 8 * dframe.stride[1];
742 let ustride = dframe.stride[1];
743 let voff = dframe.offset[2] + mb_x * 8 + mb_y * 8 * dframe.stride[2];
744 let vstride = dframe.stride[2];
745 let ipred_ctx_u = &mut self.dstate.ipred_ctx_u;
746 let ipred_ctx_v = &mut self.dstate.ipred_ctx_v;
747 ipred_ctx_u.has_top = has_top;
748 ipred_ctx_v.has_top = has_top;
749 ipred_ctx_u.has_left = has_left;
750 ipred_ctx_v.has_left = has_left;
751 ipred_ctx_u.fill(dst, uoff, ustride, 8, 8);
752 ipred_ctx_v.fill(dst, voff, vstride, 8, 8);
753 match self.mb_info[mb_idx].uvmode {
754 PredMode::DCPred => {
755 IPred8x8::ipred_dc(dst, uoff, ustride, ipred_ctx_u);
756 IPred8x8::ipred_dc(dst, voff, vstride, ipred_ctx_v);
759 IPred8x8::ipred_h(dst, uoff, ustride, ipred_ctx_u);
760 IPred8x8::ipred_h(dst, voff, vstride, ipred_ctx_v);
763 IPred8x8::ipred_v(dst, uoff, ustride, ipred_ctx_u);
764 IPred8x8::ipred_v(dst, voff, vstride, ipred_ctx_v);
766 PredMode::TMPred => {
767 IPred8x8::ipred_tm(dst, uoff, ustride, ipred_ctx_u);
768 IPred8x8::ipred_tm(dst, voff, vstride, ipred_ctx_v);
772 self.add_residue(dframe, mb_x, mb_y, is_normal, pitch_mode);
775 fn recon_inter_mb(&mut self, dframe: &mut NASimpleVideoFrame<u8>, mb_x: usize, mb_y: usize, use_last: bool) {
776 let pitch = self.dstate.force_pitch.unwrap_or(0);
777 let pitch_dmode = (pitch >> 3) & 3;
778 let pitch_smode = pitch & 7;
780 let refframe = (if use_last { self.shuf.get_last() } else { self.shuf.get_golden() }).unwrap();
781 let single_mv = self.mb_info[mb_x + mb_y * self.mb_w].mb_type != VPMBType::InterFourMV;
782 let mut iidx = mb_x * 4 + mb_y * 4 * self.mv_stride;
783 let mut mc_buf = self.mc_buf.get_data_mut().unwrap();
785 let dst = &mut dframe.data[0..];
786 let ystride = dframe.stride[0];
787 let mut yoff = dframe.offset[0] + mb_x * 16 + mb_y * 16 * ystride;
788 if pitch_smode == 0 {
790 mc_block16x16(dst, yoff, ystride, mb_x * 16, mb_y * 16,
791 self.mvs[iidx].x * 2, self.mvs[iidx].y * 2, refframe.clone(), 0, &mut mc_buf);
795 mc_block4x4(dst, yoff + x * 4, ystride, mb_x * 16 + x * 4, mb_y * 16 + y * 4,
796 self.mvs[iidx + x].x * 2, self.mvs[iidx + x].y * 2, refframe.clone(), 0, &mut mc_buf);
799 iidx += self.mv_stride;
804 mc_block_special(dst, yoff, ystride, mb_x * 16, mb_y * 16,
805 self.mvs[iidx].x * 2, self.mvs[iidx].y * 2,
806 refframe.clone(), 0, &mut mc_buf, 16, pitch_smode);
810 mc_block_special(dst, yoff + x * 4, ystride,
811 mb_x * 16 + x * 4, mb_y * 16 + y * 4,
812 self.mvs[iidx + x].x * 2, self.mvs[iidx + x].y * 2,
813 refframe.clone(), 0, &mut mc_buf, 4, pitch_smode);
816 iidx += self.mv_stride;
821 let mut iidx = mb_x * 4 + mb_y * 4 * self.mv_stride;
822 let mut uoff = dframe.offset[1] + mb_x * 8 + mb_y * 8 * dframe.stride[1];
823 let ustride = dframe.stride[1];
824 let mut voff = dframe.offset[2] + mb_x * 8 + mb_y * 8 * dframe.stride[2];
825 let vstride = dframe.stride[2];
827 let chroma_mv = self.mvs[iidx];
829 if pitch_smode == 0 {
830 mc_block8x8(dst, uoff, ustride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y, refframe.clone(), 1, &mut mc_buf);
831 mc_block8x8(dst, voff, vstride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y, refframe, 2, &mut mc_buf);
833 mc_block_special(dst, uoff, ustride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y,
834 refframe.clone(), 1, &mut mc_buf, 8, pitch_smode);
835 mc_block_special(dst, voff, vstride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y,
836 refframe, 2, &mut mc_buf, 8, pitch_smode);
841 let mut chroma_mv = self.mvs[iidx + x * 2] + self.mvs[iidx + x * 2 + 1]
842 + self.mvs[iidx + x * 2 + self.mv_stride]
843 + self.mvs[iidx + x * 2 + self.mv_stride + 1];
857 if pitch_smode == 0 {
858 mc_block4x4(dst, uoff + x * 4, ustride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
859 chroma_mv.x, chroma_mv.y, refframe.clone(), 1, &mut mc_buf);
860 mc_block4x4(dst, voff + x * 4, vstride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
861 chroma_mv.x, chroma_mv.y, refframe.clone(), 2, &mut mc_buf);
863 mc_block_special(dst, uoff + x * 4, ustride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
864 chroma_mv.x, chroma_mv.y, refframe.clone(), 1, &mut mc_buf,
866 mc_block_special(dst, voff + x * 4, vstride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
867 chroma_mv.x, chroma_mv.y, refframe.clone(), 2, &mut mc_buf,
873 iidx += 2 * self.mv_stride;
876 self.add_residue(dframe, mb_x, mb_y, true, pitch_dmode);
878 fn loop_filter_mb(&mut self, dframe: &mut NASimpleVideoFrame<u8>, mb_x: usize, mb_y: usize, loop_str: u8) {
879 const HIGH_EDGE_VAR_THR: [[u8; 64]; 2] = [
881 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
882 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
883 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
884 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
886 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
887 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
888 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
889 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
892 let edge_thr = i16::from(loop_str) + 2;
893 let luma_thr = i16::from(loop_str);
894 let chroma_thr = i16::from(loop_str) * 2;
895 let inner_thr = if self.dstate.loop_sharpness == 0 {
898 let bound1 = i16::from(9 - self.dstate.loop_sharpness);
899 let shift = (self.dstate.loop_sharpness + 3) >> 2;
900 (i16::from(loop_str) >> shift).min(bound1)
902 let hev_thr = i16::from(HIGH_EDGE_VAR_THR[if self.dstate.is_intra { 1 } else { 0 }][loop_str as usize]);
904 let ystride = dframe.stride[0];
905 let ustride = dframe.stride[1];
906 let vstride = dframe.stride[2];
907 let ypos = dframe.offset[0] + mb_x * 16 + mb_y * 16 * ystride;
908 let upos = dframe.offset[1] + mb_x * 8 + mb_y * 8 * ustride;
909 let vpos = dframe.offset[2] + mb_x * 8 + mb_y * 8 * vstride;
911 let (loop_edge, loop_inner) = if self.dstate.lf_simple {
912 (simple_loop_filter as LoopFilterFunc, simple_loop_filter as LoopFilterFunc)
914 (normal_loop_filter_edge as LoopFilterFunc, normal_loop_filter_inner as LoopFilterFunc)
918 loop_edge(dframe.data, ypos, 1, ystride, 16, edge_thr, inner_thr, hev_thr);
919 loop_edge(dframe.data, upos, 1, ustride, 8, edge_thr, inner_thr, hev_thr);
920 loop_edge(dframe.data, vpos, 1, vstride, 8, edge_thr, inner_thr, hev_thr);
923 loop_edge(dframe.data, ypos, ystride, 1, 16, edge_thr, inner_thr, hev_thr);
924 loop_edge(dframe.data, upos, ustride, 1, 8, edge_thr, inner_thr, hev_thr);
925 loop_edge(dframe.data, vpos, vstride, 1, 8, edge_thr, inner_thr, hev_thr);
929 loop_inner(dframe.data, ypos + y * 4 * ystride, ystride, 1, 16, luma_thr, inner_thr, hev_thr);
931 loop_inner(dframe.data, upos + 4 * ustride, ustride, 1, 8, chroma_thr, inner_thr, hev_thr);
932 loop_inner(dframe.data, vpos + 4 * vstride, vstride, 1, 8, chroma_thr, inner_thr, hev_thr);
935 loop_inner(dframe.data, ypos + x * 4, 1, ystride, 16, luma_thr, inner_thr, hev_thr);
937 loop_inner(dframe.data, upos + 4, 1, ustride, 8, chroma_thr, inner_thr, hev_thr);
938 loop_inner(dframe.data, vpos + 4, 1, vstride, 8, chroma_thr, inner_thr, hev_thr);
942 impl NADecoder for VP7Decoder {
943 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
944 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
945 let fmt = YUV420_FORMAT;
946 let myvinfo = NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, fmt);
947 let myinfo = NACodecTypeInfo::Video(myvinfo);
948 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
950 supp.pool_u8.set_dec_bufs(4);
951 supp.pool_u8.prealloc_video(NAVideoInfo::new(myvinfo.get_width(), myvinfo.get_height(), false, vinfo.get_format()), 4)?;
952 self.set_dimensions(myvinfo.get_width(), myvinfo.get_height());
955 Err(DecoderError::InvalidData)
958 #[allow(clippy::cognitive_complexity)]
959 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
960 let src = pkt.get_buffer();
962 validate!(src.len() > 4);
964 let frame_tag = read_u24le(src.as_slice())?;
965 self.dstate.is_intra = (frame_tag & 1) == 0;
966 self.dstate.version = ((frame_tag >> 1) & 7) as u8;
967 let part2_off = (frame_tag >> 4) as usize;
968 let part1_off = if self.dstate.version == 0 { 4 } else { 3 };
970 validate!(src.len() > part1_off + part2_off);
971 let mut bc = BoolCoder::new(&src[part1_off..][..part2_off])?;
972 let mut bc_main = BoolCoder::new(&src[part1_off + part2_off..])?;
973 if self.dstate.is_intra {
974 let width = bc.read_bits(12) as usize;
975 let height = bc.read_bits(12) as usize;
976 let _scalev = bc.read_bits(2);
977 let _scaleh = bc.read_bits(2);
978 validate!((width > 0) && (height > 0));
979 self.set_dimensions(width, height);
982 self.scan.copy_from_slice(&DEFAULT_SCAN_ORDER);
984 if !self.shuf.has_refs() {
985 return Err(DecoderError::MissingReference);
989 self.read_features(&mut bc)?;
991 let y_ac_q = bc.read_bits(7) as usize;
992 let y_dc_q = if bc.read_bool() { bc.read_bits(7) as usize } else { y_ac_q };
993 let y2_dc_q = if bc.read_bool() { bc.read_bits(7) as usize } else { y_ac_q };
994 let y2_ac_q = if bc.read_bool() { bc.read_bits(7) as usize } else { y_ac_q };
995 let uv_dc_q = if bc.read_bool() { bc.read_bits(7) as usize } else { y_ac_q };
996 let uv_ac_q = if bc.read_bool() { bc.read_bits(7) as usize } else { y_ac_q };
997 self.set_qmat(y_dc_q, y_ac_q, y2_dc_q, y2_ac_q, uv_dc_q, uv_ac_q);
999 let update_gf = if self.dstate.is_intra { true } else { bc.read_bool() };
1001 let mut has_fading_feature = true;
1002 let mut keep_probs = true;
1003 if self.dstate.version != 0 {
1004 keep_probs = bc.read_bool();
1005 if self.dstate.is_intra {
1006 has_fading_feature = true;
1008 has_fading_feature = bc.read_bool();
1012 if has_fading_feature {
1013 self.dstate.fading = bc.read_bool();
1014 if self.dstate.fading {
1015 self.dstate.fade_alpha = bc.read_sbits(8) as u16;
1016 self.dstate.fade_beta = bc.read_sbits(8) as u16;
1017 if let Some(pframe) = self.shuf.get_last() {
1018 let mut fframe = supp.pool_u8.get_free().unwrap();
1019 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut fframe).unwrap();
1020 fade_frame(pframe, &mut dframe, self.dstate.fade_alpha, self.dstate.fade_beta);
1021 self.shuf.add_frame(fframe);
1025 self.dstate.fading = false;
1028 if self.dstate.version == 0 {
1029 self.dstate.lf_simple = bc.read_bool();
1034 self.scan[i] = DEFAULT_SCAN_ORDER[bc.read_bits(4) as usize];
1038 if self.dstate.version != 0 {
1039 self.dstate.lf_simple = bc.read_bool();
1041 self.dstate.lf_simple = false;
1044 self.dstate.loop_filter_level = bc.read_bits(6) as u8;
1045 self.dstate.loop_sharpness = bc.read_bits(3) as u8;
1047 self.read_dct_coef_prob_upd(&mut bc)?;
1049 if !self.dstate.is_intra {
1050 self.dstate.prob_intra_pred = bc.read_byte();
1051 self.dstate.prob_last_pred = bc.read_byte();
1054 self.dstate.kf_ymode_prob[i] = bc.read_byte();
1059 self.dstate.kf_uvmode_prob[i] = bc.read_byte();
1062 self.read_mv_prob_upd(&mut bc)?;
1065 self.tmp_scan.copy_from_slice(&self.scan);
1068 let vinfo = NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT);
1069 let ret = supp.pool_u8.get_free();
1071 return Err(DecoderError::AllocError);
1073 let mut buf = ret.unwrap();
1074 if buf.get_info() != vinfo {
1076 supp.pool_u8.reset();
1077 supp.pool_u8.prealloc_video(vinfo, 4)?;
1078 let ret = supp.pool_u8.get_free();
1080 return Err(DecoderError::AllocError);
1084 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
1087 self.pcache.reset();
1088 if self.dstate.is_intra || (self.dstate.version > 0) {
1089 self.dstate.pdc_pred_val = [0; 2];
1090 self.dstate.pdc_pred_count = [0; 2];
1092 let mut use_last = true;
1093 for mb_y in 0..self.mb_h {
1094 for mb_x in 0..self.mb_w {
1095 self.decode_mb_features(&mut bc, mb_x, mb_y)?;
1096 self.dstate.has_y2 = true;
1097 if self.dstate.is_intra {
1098 let ymode = bc.read_tree(KF_Y_MODE_TREE, KF_Y_MODE_TREE_PROBS);
1099 if ymode == PredMode::BPred {
1100 self.dstate.has_y2 = false;
1101 let mut iidx = mb_x * 4 + mb_y * 4 * self.ymode_stride;
1104 let top_mode = if (y > 0) || (mb_y > 0) {
1105 self.ymodes[iidx + x - self.ymode_stride]
1109 let left_mode = if (x > 0) || (mb_x > 0) {
1110 self.ymodes[iidx + x - 1]
1114 let top_idx = top_mode.to_b_index();
1115 let left_idx = left_mode.to_b_index();
1116 let bmode = bc.read_tree(B_MODE_TREE, &KF_B_MODE_TREE_PROBS[top_idx][left_idx]);
1117 self.ymodes[iidx + x] = bmode;
1119 iidx += self.ymode_stride;
1122 self.fill_ymode(mb_x, mb_y, ymode.to_b_mode());
1124 let uvmode = bc.read_tree(UV_MODE_TREE, KF_UV_MODE_TREE_PROBS);
1125 self.mb_info[mb_idx].mb_type = VPMBType::Intra;
1126 self.mb_info[mb_idx].ymode = ymode;
1127 self.mb_info[mb_idx].uvmode = uvmode;
1128 } else if !bc.read_prob(self.dstate.prob_intra_pred) {
1129 let ymode = bc.read_tree(Y_MODE_TREE, &self.dstate.kf_ymode_prob);
1130 if ymode == PredMode::BPred {
1131 self.dstate.has_y2 = false;
1132 let mut iidx = mb_x * 4 + mb_y * 4 * self.ymode_stride;
1135 let bmode = bc.read_tree(B_MODE_TREE, B_MODE_TREE_PROBS);
1136 self.ymodes[iidx + x] = bmode;
1138 iidx += self.ymode_stride;
1141 self.fill_ymode(mb_x, mb_y, PredMode::Inter);
1143 let uvmode = bc.read_tree(UV_MODE_TREE, &self.dstate.kf_uvmode_prob);
1144 self.mb_info[mb_idx].mb_type = VPMBType::Intra;
1145 self.mb_info[mb_idx].ymode = ymode;
1146 self.mb_info[mb_idx].uvmode = uvmode;
1147 self.fill_mv(mb_x, mb_y, ZERO_MV);
1149 use_last = !bc.read_prob(self.dstate.prob_last_pred);
1151 let (mvprobs, nearest_mv, near_mv, pred_mv) = self.find_mv_pred(mb_x, mb_y);
1152 let mbtype = bc.read_tree(MV_REF_TREE, &mvprobs);
1155 VPMBType::InterNearest => {
1156 self.fill_mv(mb_x, mb_y, nearest_mv);
1158 VPMBType::InterNear => {
1159 self.fill_mv(mb_x, mb_y, near_mv);
1161 VPMBType::InterNoMV => {
1162 self.fill_mv(mb_x, mb_y, ZERO_MV);
1164 VPMBType::InterMV => {
1165 let dmy = decode_mv_component(&mut bc, &self.dstate.mv_probs[0]);
1166 let dmx = decode_mv_component(&mut bc, &self.dstate.mv_probs[1]);
1167 let new_mv = pred_mv + MV{ x: dmx, y: dmy };
1168 self.fill_mv(mb_x, mb_y, new_mv);
1170 VPMBType::InterFourMV => {
1171 self.do_split_mv(&mut bc, mb_x, mb_y, pred_mv)?;
1173 _ => unreachable!(),
1176 self.fill_ymode(mb_x, mb_y, PredMode::Inter);
1177 self.mb_info[mb_idx].mb_type = mbtype;
1178 self.mb_info[mb_idx].ymode = PredMode::Inter;
1179 self.mb_info[mb_idx].uvmode = PredMode::Inter;
1181 self.decode_residue(&mut bc_main, mb_x, mb_idx, use_last);
1182 match self.mb_info[mb_idx].mb_type {
1183 VPMBType::Intra => {
1184 self.recon_intra_mb(&mut dframe, mb_x, mb_y)?;
1187 self.recon_inter_mb(&mut dframe, mb_x, mb_y, use_last);
1190 if let Some(loop_str) = self.dstate.force_loop_str {
1191 self.mb_info[mb_idx].loop_str = loop_str;
1193 self.mb_info[mb_idx].loop_str = self.dstate.loop_filter_level;
1195 self.mb_info[mb_idx].upd_gf = self.dstate.force_gf_update;
1198 self.pcache.update_row();
1201 for mb_y in 0..self.mb_h {
1202 for mb_x in 0..self.mb_w {
1203 let loop_str = self.mb_info[mb_idx].loop_str;
1204 self.loop_filter_mb(&mut dframe, mb_x, mb_y, loop_str);
1208 if !update_gf && self.dstate.features[2].is_some() {
1209 let gf = self.shuf.get_golden().unwrap();
1210 let mut new_gf = supp.pool_u8.get_copy(&gf).unwrap();
1211 let dframe = NASimpleVideoFrame::from_video_buf(&mut new_gf).unwrap();
1213 let mut mc_buf = self.mc_buf.get_data_mut().unwrap();
1214 for mb_y in 0..self.mb_h {
1215 for mb_x in 0..self.mb_w {
1216 if self.mb_info[mb_idx].upd_gf {
1217 mc_block16x16(dframe.data, dframe.offset[0] + mb_x * 16 + mb_y * 16 * dframe.stride[0], dframe.stride[0], mb_x * 16, mb_y * 16, 0, 0, buf.clone(), 0, &mut mc_buf);
1218 mc_block8x8(dframe.data, dframe.offset[1] + mb_x * 8 + mb_y * 8 * dframe.stride[1], dframe.stride[1], mb_x * 8, mb_y * 8, 0, 0, buf.clone(), 1, &mut mc_buf);
1219 mc_block8x8(dframe.data, dframe.offset[2] + mb_x * 8 + mb_y * 8 * dframe.stride[2], dframe.stride[2], mb_x * 8, mb_y * 8, 0, 0, buf.clone(), 2, &mut mc_buf);
1224 self.shuf.add_golden_frame(new_gf);
1228 self.scan.copy_from_slice(&self.tmp_scan);
1231 self.shuf.add_golden_frame(buf.clone());
1233 self.shuf.add_frame(buf.clone());
1235 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
1236 frm.set_keyframe(self.dstate.is_intra);
1237 frm.set_frame_type(if self.dstate.is_intra { FrameType::I } else { FrameType::P });
1240 fn flush(&mut self) {
1245 impl NAOptionHandler for VP7Decoder {
1246 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
1247 fn set_options(&mut self, _options: &[NAOption]) { }
1248 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
1251 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
1252 Box::new(VP7Decoder::new())
1257 use nihav_core::codecs::RegisteredDecoders;
1258 use nihav_core::demuxers::RegisteredDemuxers;
1259 use nihav_codec_support::test::dec_video::*;
1260 use crate::duck_register_all_decoders;
1261 use nihav_commonfmt::generic_register_all_demuxers;
1265 let mut dmx_reg = RegisteredDemuxers::new();
1266 generic_register_all_demuxers(&mut dmx_reg);
1267 let mut dec_reg = RegisteredDecoders::new();
1268 duck_register_all_decoders(&mut dec_reg);
1270 test_decoding("avi", "vp7", "assets/Duck/interlaced_blit_pitch.avi", Some(12), &dmx_reg,
1271 &dec_reg, ExpectedTestResult::MD5Frames(vec![
1272 [0xb79fb6f8, 0xed51ac9e, 0x9e423456, 0xc0918e7f],
1273 [0xbf8d1274, 0x83515e15, 0x8c0887de, 0xfbfd05d3],
1274 [0x8ad00466, 0x80b6cbfb, 0x54de408e, 0x9efbc05e],
1275 [0x144122c5, 0x6897b553, 0x93474d29, 0x1a1274ec],
1276 [0x06ff5d07, 0x55825d38, 0x072b0a78, 0xfcb5020f],
1277 [0xfd01591b, 0xc42113e7, 0xc5a5550f, 0xb30f3b02],
1278 [0x155e0d6e, 0x96d75e06, 0x9bd7ce87, 0xacf868e1],
1279 [0xfd79103a, 0x695d21d3, 0xfeacb5b4, 0x1d869d08],
1280 [0xf4bcfeac, 0x0d2c305c, 0x11416c96, 0x626a5ef6],
1281 [0x3579b66c, 0x0a7d7dc0, 0xe80b0395, 0xf6a70661],
1282 [0x5773768c, 0x813442e9, 0x4dd6f793, 0xb10fe55f],
1283 [0xcaaf0ddb, 0x65c2410e, 0x95da5bba, 0x3b90128e],
1284 [0x74773773, 0xe1dbadeb, 0x57aaf64b, 0x9c21e3c7]]));
1288 const MV_UPDATE_PROBS: [[u8; 17]; 2] = [
1289 [ 237, 246, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 250, 250, 252 ],
1290 [ 231, 243, 245, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 251, 251, 254 ]
1292 const DEFAULT_MV_PROBS: [[u8; 17]; 2] = [
1293 [ 162, 128, 225, 146, 172, 147, 214, 39, 156, 247, 210, 135, 68, 138, 220, 239, 246 ],
1294 [ 164, 128, 204, 170, 119, 235, 140, 230, 228, 244, 184, 201, 44, 173, 221, 239, 253 ]
1297 const SUB_MV_REF_PROBS: [u8; 3] = [ 180, 162, 25 ];
1299 const Y_DC_QUANTS: [i16; 128] = [
1300 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1301 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1302 32, 33, 33, 34, 35, 36, 36, 37, 38, 39, 39, 40, 41, 41, 42, 43,
1303 43, 44, 45, 45, 46, 47, 48, 48, 49, 50, 51, 52, 53, 53, 54, 56,
1304 57, 58, 59, 60, 62, 63, 65, 66, 68, 70, 72, 74, 76, 79, 81, 84,
1305 87, 90, 93, 96, 100, 104, 108, 112, 116, 121, 126, 131, 136, 142, 148, 154,
1306 160, 167, 174, 182, 189, 198, 206, 215, 224, 234, 244, 254, 265, 277, 288, 301,
1307 313, 327, 340, 355, 370, 385, 401, 417, 434, 452, 470, 489, 509, 529, 550, 572
1309 const Y_AC_QUANTS: [i16; 128] = [
1310 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
1311 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41,
1312 42, 44, 45, 46, 48, 49, 50, 51, 53, 54, 55, 56, 57, 58, 59, 61,
1313 62, 63, 64, 65, 67, 68, 69, 70, 72, 73, 75, 76, 78, 80, 82, 84,
1314 86, 88, 91, 93, 96, 99, 102, 105, 109, 112, 116, 121, 125, 130, 135, 140,
1315 146, 152, 158, 165, 172, 180, 188, 196, 205, 214, 224, 234, 245, 256, 268, 281,
1316 294, 308, 322, 337, 353, 369, 386, 404, 423, 443, 463, 484, 506, 529, 553, 578,
1317 604, 631, 659, 688, 718, 749, 781, 814, 849, 885, 922, 960, 1000, 1041, 1083, 1127
1319 const Y2_DC_QUANTS: [i16; 128] = [
1320 7, 9, 11, 13, 15, 17, 19, 21, 23, 26, 28, 30, 33, 35, 37, 39,
1321 42, 44, 46, 48, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 70, 72,
1322 74, 75, 77, 78, 80, 81, 83, 84, 85, 87, 88, 89, 90, 92, 93, 94,
1323 95, 96, 97, 99, 100, 101, 102, 104, 105, 106, 108, 109, 111, 113, 114, 116,
1324 118, 120, 123, 125, 128, 131, 134, 137, 140, 144, 148, 152, 156, 161, 166, 171,
1325 176, 182, 188, 195, 202, 209, 217, 225, 234, 243, 253, 263, 274, 285, 297, 309,
1326 322, 336, 350, 365, 381, 397, 414, 432, 450, 470, 490, 511, 533, 556, 579, 604,
1327 630, 656, 684, 713, 742, 773, 805, 838, 873, 908, 945, 983, 1022, 1063, 1105, 1148
1329 const Y2_AC_QUANTS: [i16; 128] = [
1330 7, 9, 11, 13, 16, 18, 21, 24, 26, 29, 32, 35, 38, 41, 43, 46,
1331 49, 52, 55, 58, 61, 64, 66, 69, 72, 74, 77, 79, 82, 84, 86, 88,
1332 91, 93, 95, 97, 98, 100, 102, 104, 105, 107, 109, 110, 112, 113, 115, 116,
1333 117, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 136, 138, 141, 143, 146,
1334 149, 152, 155, 158, 162, 166, 171, 175, 180, 185, 191, 197, 204, 210, 218, 226,
1335 234, 243, 252, 262, 273, 284, 295, 308, 321, 335, 350, 365, 381, 398, 416, 435,
1336 455, 476, 497, 520, 544, 569, 595, 622, 650, 680, 711, 743, 776, 811, 848, 885,
1337 925, 965, 1008, 1052, 1097, 1144, 1193, 1244, 1297, 1351, 1407, 1466, 1526, 1588, 1652, 1719
1339 const UV_DC_QUANTS: [i16; 128] = [
1340 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1341 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1342 32, 33, 33, 34, 35, 36, 36, 37, 38, 39, 39, 40, 41, 41, 42, 43,
1343 43, 44, 45, 45, 46, 47, 48, 48, 49, 50, 51, 52, 53, 53, 54, 56,
1344 57, 58, 59, 60, 62, 63, 65, 66, 68, 70, 72, 74, 76, 79, 81, 84,
1345 87, 90, 93, 96, 100, 104, 108, 112, 116, 121, 126, 131, 132, 132, 132, 132,
1346 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
1347 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132
1349 const UV_AC_QUANTS: [i16; 128] = [
1350 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
1351 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41,
1352 42, 44, 45, 46, 48, 49, 50, 51, 53, 54, 55, 56, 57, 58, 59, 61,
1353 62, 63, 64, 65, 67, 68, 69, 70, 72, 73, 75, 76, 78, 80, 82, 84,
1354 86, 88, 91, 93, 96, 99, 102, 105, 109, 112, 116, 121, 125, 130, 135, 140,
1355 146, 152, 158, 165, 172, 180, 188, 196, 205, 214, 224, 234, 245, 256, 268, 281,
1356 294, 308, 322, 337, 353, 369, 386, 404, 423, 443, 463, 484, 506, 529, 553, 578,
1357 604, 631, 659, 688, 718, 749, 781, 814, 849, 885, 922, 960, 1000, 1041, 1083, 1127