da0ccc4be4b73dfcc656fd1fd2f29dfc1b1ce18a
[nihav.git] / nihav-duck / src / codecs / vp7.rs
1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3 use nihav_codec_support::codecs::{MV, ZERO_MV};
4 use super::vpcommon::*;
5 use super::vp78::*;
6 use super::vp78data::*;
7 use super::vp78dsp::*;
8 use super::vp7dsp::*;
9
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;
14
15 #[derive(Clone,Copy,Default)]
16 struct MBFeature {
17 present_prob: u8,
18 tree_probs: [u8; 3],
19 def_val: [u8; 4],
20 }
21
22 struct SBParams<'a> {
23 coef_probs: &'a [[[[u8; 11]; 3]; 8]; 4],
24 scan: &'a [usize; 16],
25 qmat: &'a [i16; 16],
26 }
27
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 ];
30
31 let mut has_nz = 0;
32 let start = if ctype != 0 { 0 } else { 1 };
33 *coeffs = [0; 16];
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;
42 has_nz |= cval;
43 }
44 if has_nz > 0 { 1 } else { 0 }
45 }
46
47 #[derive(Clone,Copy,Default)]
48 struct MBInfo {
49 mb_type: VPMBType,
50 ymode: PredMode,
51 uvmode: PredMode,
52 loop_str: u8,
53 upd_gf: bool,
54 }
55
56 #[derive(Default)]
57 struct DecoderState {
58 features: [Option<MBFeature>; 4],
59
60 fading: bool,
61 fade_alpha: u16,
62 fade_beta: u16,
63
64 lf_simple: bool,
65 loop_filter_level: u8,
66 loop_sharpness: u8,
67
68 is_intra: bool,
69 version: u8,
70
71 kf_ymode_prob: [u8; 4],
72 kf_uvmode_prob: [u8; 3],
73
74 prob_intra_pred: u8,
75 prob_last_pred: u8,
76
77 coef_probs: [[[[u8; 11]; 3]; 8]; 4],
78 mv_probs: [[u8; 17]; 2],
79
80 force_quant: Option<u8>,
81 force_loop_str: Option<u8>,
82 force_gf_update: bool,
83 force_pitch: Option<u8>,
84
85 has_y2: bool,
86 pdc_pred_val: [i16; 2],
87 pdc_pred_count: [usize; 2],
88
89 ipred_ctx_y: IPredContext,
90 ipred_ctx_u: IPredContext,
91 ipred_ctx_v: IPredContext,
92 }
93
94 impl DecoderState {
95 fn reset(&mut self) {
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);
100 }
101 }
102
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 ];
105
106 let val = if !bc.read_prob(probs[0]) {
107 bc.read_tree(SMALL_MV_TREE, &probs[2..9])
108 } else {
109 let raw_probs = &probs[9..];
110 let mut raw = 0;
111 for ord in LONG_VECTOR_ORDER.iter() {
112 raw |= (bc.read_prob(raw_probs[*ord]) as i16) << *ord;
113 }
114 if (raw & 0xF0) != 0 {
115 raw |= (bc.read_prob(raw_probs[3]) as i16) << 3;
116 } else {
117 raw |= 1 << 3;
118 }
119 raw
120 };
121 if (val == 0) || !bc.read_prob(probs[1]) {
122 val
123 } else {
124 -val
125 }
126 }
127
128 struct VP7Decoder {
129 info: NACodecInfoRef,
130
131 shuf: VPShuffler,
132 width: usize,
133 height: usize,
134 mb_w: usize,
135 mb_h: usize,
136 mb_info: Vec<MBInfo>,
137 mvs: Vec<MV>,
138 mv_stride: usize,
139
140 ymodes: Vec<PredMode>,
141 ymode_stride: usize,
142 uvmodes: Vec<PredMode>,
143 uvmode_stride: usize,
144
145 dstate: DecoderState,
146 pcache: PredCache,
147
148 coeffs: [[i16; 16]; 25],
149 scan: [usize; 16],
150 qmat: [[[i16; 16]; 3]; 5],
151
152 mc_buf: NAVideoBufferRef<u8>,
153
154 tmp_scan: [usize; 16],
155 }
156
157 impl VP7Decoder {
158 fn new() -> Self {
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();
163 Self {
164 info: NACodecInfoRef::default(),
165
166 shuf: VPShuffler::new(),
167 width: 0,
168 height: 0,
169 mb_w: 0,
170 mb_h: 0,
171 mb_info: Vec::new(),
172 mvs: Vec::new(),
173 mv_stride: 0,
174
175 ymodes: Vec::new(),
176 ymode_stride: 0,
177 uvmodes: Vec::new(),
178 uvmode_stride: 0,
179
180 dstate: DecoderState::default(),
181 pcache: PredCache::new(),
182
183 coeffs: [[0; 16]; 25],
184 scan,
185 tmp_scan: [0; 16],
186 qmat: [[[0; 16]; 3]; 5],
187
188 mc_buf,
189 }
190 }
191 fn set_dimensions(&mut self, width: usize, height: usize) {
192 if (width == self.width) && (height == self.height) {
193 return;
194 }
195 self.width = width;
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);
202
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());
207
208 self.pcache.resize(self.mb_w);
209 }
210 fn read_features(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
211 for (i, feat) in self.dstate.features.iter_mut().enumerate() {
212 if bc.read_bool() {
213 let mut feature = MBFeature::default();
214 feature.present_prob = bc.read_byte();
215 for tp in feature.tree_probs.iter_mut() {
216 if bc.read_bool() {
217 *tp = bc.read_byte();
218 } else {
219 *tp = 255;
220 }
221 }
222 if i != 2 {
223 let fbits = match i {
224 0 => 7,
225 1 => 6,
226 _ => if self.dstate.version == 0 { 8 } else { 5 },
227 };
228 for dval in feature.def_val.iter_mut() {
229 if bc.read_bool() {
230 *dval = bc.read_bits(fbits) as u8;
231 } else {
232 *dval = 0;
233 }
234 }
235 }
236 *feat = Some(feature);
237 } else {
238 *feat = None;
239 }
240 }
241 Ok(())
242 }
243 fn read_dct_coef_prob_upd(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
244 for i in 0..4 {
245 for j in 0..8 {
246 for k in 0..3 {
247 for l in 0..11 {
248 if bc.read_prob(DCT_UPDATE_PROBS[i][j][k][l]) {
249 self.dstate.coef_probs[i][j][k][l] = bc.read_byte();
250 }
251 }
252 }
253 }
254 }
255 Ok(())
256 }
257 fn read_mv_prob_upd(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
258 for comp in 0..2 {
259 for i in 0..17 {
260 if bc.read_prob(MV_UPDATE_PROBS[comp][i]) {
261 self.dstate.mv_probs[comp][i] = bc.read_probability();
262 }
263 }
264 }
265 Ok(())
266 }
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);
275 if present {
276 let ftype_idx = bc.read_tree(FEATURE_TREE, &feat.tree_probs);
277 let val = feat.def_val[ftype_idx];
278 match i {
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),
283 };
284 }
285 }
286 }
287 Ok(())
288 }
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,
295 };
296 let mut has_ac = [false; 25];
297 let ytype;
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];
302
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;
307
308 ytype = 0;
309 } else {
310 let pred = &mut self.pcache.y2_pred;
311 let pidx = pred.xpos + mb_x;
312 pred.data[pidx] = pred.data[pidx - pred.stride];
313
314 ytype = 3;
315 }
316 sbparams.scan = &self.scan;
317 sbparams.qmat = &self.qmat[qmat_idx][0];
318 for i in 0..16 {
319 let bx = i & 3;
320 let by = i >> 2;
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];
324
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;
329 }
330 sbparams.qmat = &self.qmat[qmat_idx][1];
331 for i in 16..20 {
332 let bx = i & 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];
337
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;
342 }
343 for i in 20..24 {
344 let bx = i & 1;
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];
349
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;
354 }
355
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];
362
363 if self.dstate.pdc_pred_count[pdc_idx] > 3 {
364 dc += pval;
365 y2block[0] = dc;
366 }
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;
371 }
372 self.dstate.pdc_pred_val[pdc_idx] = dc;
373 }
374 if has_ac[24] {
375 idct4x4(y2block);
376 } else if y2block[0] != 0 {
377 idct4x4_dc(y2block);
378 }
379 for i in 0..16 {
380 self.coeffs[i][0] = self.coeffs[24][i];
381 }
382 }
383 for i in 0..24 {
384 if has_ac[i] {
385 idct4x4(&mut self.coeffs[i]);
386 } else if self.coeffs[i][0] != 0 {
387 idct4x4_dc(&mut self.coeffs[i]);
388 }
389 }
390 }
391
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];
394 for i in 1..16 {
395 self.qmat[0][0][i] = Y_AC_QUANTS[y_ac_q];
396 }
397 self.qmat[0][1][0] = UV_DC_QUANTS[uv_dc_q];
398 for i in 1..16 {
399 self.qmat[0][1][i] = UV_AC_QUANTS[uv_ac_q];
400 }
401 self.qmat[0][2][0] = Y2_DC_QUANTS[y2_dc_q];
402 for i in 1..16 {
403 self.qmat[0][2][i] = Y2_AC_QUANTS[y2_ac_q];
404 }
405 if let Some(ref feat) = self.dstate.features[0] {
406 for j in 0..4 {
407 let q = feat.def_val[j] as usize;
408 self.qmat[j + 1][0][0] = Y_DC_QUANTS[q];
409 for i in 1..16 {
410 self.qmat[j + 1][0][i] = Y_AC_QUANTS[q];
411 }
412 self.qmat[j + 1][1][0] = UV_DC_QUANTS[q];
413 for i in 1..16 {
414 self.qmat[j + 1][1][i] = UV_AC_QUANTS[q];
415 }
416 self.qmat[j + 1][2][0] = Y2_DC_QUANTS[q];
417 for i in 1..16 {
418 self.qmat[j + 1][2][i] = Y2_AC_QUANTS[q];
419 }
420 }
421 }
422 }
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;
425 for _ in 0..4 {
426 for x in 0..4 {
427 self.ymodes[iidx + x] = ymode;
428 }
429 iidx += self.ymode_stride;
430 }
431 }
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;
434 for _ in 0..4 {
435 for x in 0..4 {
436 self.mvs[iidx + x] = mv;
437 }
438 iidx += self.mb_w * 4;
439 }
440 }
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)
449 ];
450
451 let mut nearest_mv = ZERO_MV;
452 let mut near_mv = ZERO_MV;
453
454 let mut ct: [u8; 4] = [0; 4];
455
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)) {
463 ct[0] += weight;
464 continue;
465 }
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];
472 if mv == ZERO_MV {
473 ct[0] += weight;
474 continue;
475 }
476 let idx;
477 if (nearest_mv == ZERO_MV) || (nearest_mv == mv) {
478 nearest_mv = mv;
479 idx = 1;
480 } else if near_mv == ZERO_MV {
481 near_mv = mv;
482 idx = 2;
483 } else {
484 idx = if mv == near_mv { 2 } else { 3 };
485 }
486 ct[idx] += weight;
487 }
488 let pred_mv = if ct[1] > ct[2] {
489 if ct[1] >= ct[0] { nearest_mv } else { ZERO_MV }
490 } else {
491 if ct[2] >= ct[0] { near_mv } else { ZERO_MV }
492 };
493
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]];
498
499 (mvprobs, nearest_mv, near_mv, pred_mv)
500 }
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;
504 match mode {
505 SubMVRef::Left => {
506 if (mb_x > 0) || (bx > 0) {
507 self.mvs[mvidx - 1]
508 } else {
509 ZERO_MV
510 }
511 },
512 SubMVRef::Above => {
513 if (mb_y > 0) || (by > 0) {
514 self.mvs[mvidx - self.mv_stride]
515 } else {
516 ZERO_MV
517 }
518 },
519 SubMVRef::Zero => ZERO_MV,
520 SubMVRef::New => {
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 }
524 },
525 }
526 }
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;
530 match split_mode {
531 MVSplitMode::TopBottom => {
532 let top_mv = self.get_split_mv(bc, mb_x, mb_y, 0, 0, pred_mv);
533 for _ in 0..2 {
534 for x in 0..4 { self.mvs[mvidx + x] = top_mv; }
535 mvidx += self.mv_stride;
536 }
537 let bot_mv = self.get_split_mv(bc, mb_x, mb_y, 0, 2, pred_mv);
538 for _ in 2..4 {
539 for x in 0..4 { self.mvs[mvidx + x] = bot_mv; }
540 mvidx += self.mv_stride;
541 }
542 },
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);
547 for _ in 0..4 {
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;
553 }
554 },
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];
560 }
561 for x in 0..4 {
562 self.mvs[mvidx + x + self.mv_stride] = self.mvs[mvidx + x];
563 }
564 mvidx += self.mv_stride * 2;
565 }
566 },
567 MVSplitMode::Sixteenths => {
568 for y in 0..4 {
569 for x in 0..4 {
570 self.mvs[mvidx + x] = self.get_split_mv(bc, mb_x, mb_y, x, y, pred_mv);
571 }
572 mvidx += self.mv_stride;
573 }
574 },
575 };
576 Ok(())
577 }
578
579 fn add_residue(&self, dframe: &mut NASimpleVideoFrame<u8>, mb_x: usize, mb_y: usize, do_luma: bool, pitch_mode: u8) {
580 if do_luma {
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;
584 match pitch_mode {
585 PITCH_MODE_NORMAL => {
586 for y in 0..4 {
587 for x in 0..4 {
588 add_coeffs4x4(ydst, yoff + x * 4, ystride, &self.coeffs[x + y * 4]);
589 }
590 yoff += 4 * ystride;
591 }
592 },
593 PITCH_MODE_FOUR => {
594 for y in 0..16 {
595 add_coeffs16x1(ydst, yoff, &self.coeffs[y]);
596 yoff += ystride;
597 }
598 },
599 PITCH_MODE_X2 => {
600 for y in 0..2 {
601 for x in 0..4 {
602 add_coeffs4x4(ydst, yoff + x * 4, ystride * 2, &self.coeffs[x + y * 4]);
603 }
604 yoff += 8 * ystride;
605 }
606 yoff -= 15 * ystride;
607 for y in 2..4 {
608 for x in 0..4 {
609 add_coeffs4x4(ydst, yoff + x * 4, ystride * 2, &self.coeffs[x + y * 4]);
610 }
611 yoff += 8 * ystride;
612 }
613 },
614 PITCH_MODE_X4 => {
615 for y in 0..4 {
616 for x in 0..4 {
617 add_coeffs4x4(ydst, yoff + x * 4, ystride * 4, &self.coeffs[x + y * 4]);
618 }
619 yoff += ystride;
620 }
621 },
622 _ => unreachable!(),
623 };
624 }
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) {
631 for y in 0..2 {
632 for x in 0..2 {
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]);
635 }
636 uoff += ustride * 4;
637 voff += vstride * 4;
638 }
639 } else {
640 for y in 0..2 {
641 for x in 0..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]);
644 }
645 uoff += ustride;
646 voff += vstride;
647 }
648 }
649 }
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;
653
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;
664 if is_normal {
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),
671 _ => unreachable!(),
672 };
673 } else {
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) {
680 for x in 0..4 {
681 let mut tmpblock = [0i16; 16 * 2];
682 let eidx = x + y * 4;
683 let oidx = x + y * 4 + 4;
684 for i in 0..4 {
685 for j in 0..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];
688 }
689 }
690 self.coeffs[eidx].copy_from_slice(&tmpblock[0..16]);
691 self.coeffs[oidx].copy_from_slice(&tmpblock[16..32]);
692 }
693 }
694 }
695 let tr_edge = if has_top { ydst[yoff - ystride + 15] } else { 0x80 };
696 for y in 0..4 {
697 for x in 0..4 {
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 });
706 if !has_tr {
707 for i in 0..4 {
708 ipred_ctx_y.top[i + 4] = tr_save[x * 4 + i];
709 }
710 } else {
711 for i in 0..4 {
712 tr_save[x * 4 + i] = ipred_ctx_y.top[i + 4];
713 }
714 }
715 if (mb_x == self.mb_w - 1) && has_top && (x == 3) {
716 for i in 0..4 {
717 ipred_ctx_y.top[i + 4] = tr_edge;
718 }
719 }
720 match bmode {
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),
731 _ => unreachable!(),
732 };
733 add_coeffs4x4(ydst, cur_yoff, ystride, &self.coeffs[x + y * 4]);
734 }
735 ipred_ctx_y.has_top = true;
736 yoff += 4 * ystride;
737 iidx += self.ymode_stride;
738 }
739 }
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);
757 },
758 PredMode::HPred => {
759 IPred8x8::ipred_h(dst, uoff, ustride, ipred_ctx_u);
760 IPred8x8::ipred_h(dst, voff, vstride, ipred_ctx_v);
761 },
762 PredMode::VPred => {
763 IPred8x8::ipred_v(dst, uoff, ustride, ipred_ctx_u);
764 IPred8x8::ipred_v(dst, voff, vstride, ipred_ctx_v);
765 },
766 PredMode::TMPred => {
767 IPred8x8::ipred_tm(dst, uoff, ustride, ipred_ctx_u);
768 IPred8x8::ipred_tm(dst, voff, vstride, ipred_ctx_v);
769 },
770 _ => unreachable!(),
771 };
772 self.add_residue(dframe, mb_x, mb_y, is_normal, pitch_mode);
773 Ok(())
774 }
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;
779
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();
784
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 {
789 if single_mv {
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);
792 } else {
793 for y in 0..4 {
794 for x in 0..4 {
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);
797 }
798 yoff += 4 * ystride;
799 iidx += self.mv_stride;
800 }
801 }
802 } else {
803 if single_mv {
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);
807 } else {
808 for y in 0..4 {
809 for x in 0..4 {
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);
814 }
815 yoff += 4 * ystride;
816 iidx += self.mv_stride;
817 }
818 }
819 }
820
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];
826 if single_mv {
827 let chroma_mv = self.mvs[iidx];
828
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);
832 } else {
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);
837 }
838 } else {
839 for y in 0..2 {
840 for x in 0..2 {
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];
844 if chroma_mv.x < 0 {
845 chroma_mv.x += 1;
846 } else {
847 chroma_mv.x += 2;
848 }
849 if chroma_mv.y < 0 {
850 chroma_mv.y += 1;
851 } else {
852 chroma_mv.y += 2;
853 }
854 chroma_mv.x >>= 2;
855 chroma_mv.y >>= 2;
856
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);
862 } else {
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,
865 4, pitch_smode);
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,
868 4, pitch_smode);
869 }
870 }
871 uoff += ustride * 4;
872 voff += vstride * 4;
873 iidx += 2 * self.mv_stride;
874 }
875 }
876 self.add_residue(dframe, mb_x, mb_y, true, pitch_dmode);
877 }
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] = [
880 [
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
885 ], [
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
890 ]];
891
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 {
896 i16::from(loop_str)
897 } else {
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)
901 };
902 let hev_thr = i16::from(HIGH_EDGE_VAR_THR[if self.dstate.is_intra { 1 } else { 0 }][loop_str as usize]);
903
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;
910
911 let (loop_edge, loop_inner) = if self.dstate.lf_simple {
912 (simple_loop_filter as LoopFilterFunc, simple_loop_filter as LoopFilterFunc)
913 } else {
914 (normal_loop_filter_edge as LoopFilterFunc, normal_loop_filter_inner as LoopFilterFunc)
915 };
916
917 if mb_x > 0 {
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);
921 }
922 if mb_y > 0 {
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);
926 }
927
928 for y in 1..4 {
929 loop_inner(dframe.data, ypos + y * 4 * ystride, ystride, 1, 16, luma_thr, inner_thr, hev_thr);
930 }
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);
933
934 for x in 1..4 {
935 loop_inner(dframe.data, ypos + x * 4, 1, ystride, 16, luma_thr, inner_thr, hev_thr);
936 }
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);
939 }
940 }
941
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();
949
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());
953 Ok(())
954 } else {
955 Err(DecoderError::InvalidData)
956 }
957 }
958 #[allow(clippy::cognitive_complexity)]
959 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
960 let src = pkt.get_buffer();
961
962 validate!(src.len() > 4);
963
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 };
969
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);
980
981 self.dstate.reset();
982 self.scan.copy_from_slice(&DEFAULT_SCAN_ORDER);
983 } else {
984 if !self.shuf.has_refs() {
985 return Err(DecoderError::MissingReference);
986 }
987 }
988
989 self.read_features(&mut bc)?;
990
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);
998
999 let update_gf = if self.dstate.is_intra { true } else { bc.read_bool() };
1000
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;
1007 } else {
1008 has_fading_feature = bc.read_bool();
1009 }
1010 }
1011
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);
1022 }
1023 }
1024 } else {
1025 self.dstate.fading = false;
1026 }
1027
1028 if self.dstate.version == 0 {
1029 self.dstate.lf_simple = bc.read_bool();
1030 }
1031
1032 if bc.read_bool() {
1033 for i in 1..16 {
1034 self.scan[i] = DEFAULT_SCAN_ORDER[bc.read_bits(4) as usize];
1035 }
1036 }
1037
1038 if self.dstate.version != 0 {
1039 self.dstate.lf_simple = bc.read_bool();
1040 } else {
1041 self.dstate.lf_simple = false;
1042 }
1043
1044 self.dstate.loop_filter_level = bc.read_bits(6) as u8;
1045 self.dstate.loop_sharpness = bc.read_bits(3) as u8;
1046
1047 self.read_dct_coef_prob_upd(&mut bc)?;
1048
1049 if !self.dstate.is_intra {
1050 self.dstate.prob_intra_pred = bc.read_byte();
1051 self.dstate.prob_last_pred = bc.read_byte();
1052 if bc.read_bool() {
1053 for i in 0..4 {
1054 self.dstate.kf_ymode_prob[i] = bc.read_byte();
1055 }
1056 }
1057 if bc.read_bool() {
1058 for i in 0..3 {
1059 self.dstate.kf_uvmode_prob[i] = bc.read_byte();
1060 }
1061 }
1062 self.read_mv_prob_upd(&mut bc)?;
1063 }
1064 if !keep_probs {
1065 self.tmp_scan.copy_from_slice(&self.scan);
1066 }
1067
1068 let vinfo = NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT);
1069 let ret = supp.pool_u8.get_free();
1070 if ret.is_none() {
1071 return Err(DecoderError::AllocError);
1072 }
1073 let mut buf = ret.unwrap();
1074 if buf.get_info() != vinfo {
1075 self.shuf.clear();
1076 supp.pool_u8.reset();
1077 supp.pool_u8.prealloc_video(vinfo, 4)?;
1078 let ret = supp.pool_u8.get_free();
1079 if ret.is_none() {
1080 return Err(DecoderError::AllocError);
1081 }
1082 buf = ret.unwrap();
1083 }
1084 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
1085
1086 let mut mb_idx = 0;
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];
1091 }
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;
1102 for y in 0..4 {
1103 for x in 0..4 {
1104 let top_mode = if (y > 0) || (mb_y > 0) {
1105 self.ymodes[iidx + x - self.ymode_stride]
1106 } else {
1107 PredMode::DCPred
1108 };
1109 let left_mode = if (x > 0) || (mb_x > 0) {
1110 self.ymodes[iidx + x - 1]
1111 } else {
1112 PredMode::DCPred
1113 };
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;
1118 }
1119 iidx += self.ymode_stride;
1120 }
1121 } else {
1122 self.fill_ymode(mb_x, mb_y, ymode.to_b_mode());
1123 }
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;
1133 for _y in 0..4 {
1134 for x in 0..4 {
1135 let bmode = bc.read_tree(B_MODE_TREE, B_MODE_TREE_PROBS);
1136 self.ymodes[iidx + x] = bmode;
1137 }
1138 iidx += self.ymode_stride;
1139 }
1140 } else {
1141 self.fill_ymode(mb_x, mb_y, PredMode::Inter);
1142 }
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);
1148 } else {
1149 use_last = !bc.read_prob(self.dstate.prob_last_pred);
1150
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);
1153
1154 match mbtype {
1155 VPMBType::InterNearest => {
1156 self.fill_mv(mb_x, mb_y, nearest_mv);
1157 },
1158 VPMBType::InterNear => {
1159 self.fill_mv(mb_x, mb_y, near_mv);
1160 },
1161 VPMBType::InterNoMV => {
1162 self.fill_mv(mb_x, mb_y, ZERO_MV);
1163 },
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);
1169 },
1170 VPMBType::InterFourMV => {
1171 self.do_split_mv(&mut bc, mb_x, mb_y, pred_mv)?;
1172 },
1173 _ => unreachable!(),
1174 };
1175
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;
1180 }
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)?;
1185 },
1186 _ => {
1187 self.recon_inter_mb(&mut dframe, mb_x, mb_y, use_last);
1188 },
1189 }
1190 if let Some(loop_str) = self.dstate.force_loop_str {
1191 self.mb_info[mb_idx].loop_str = loop_str;
1192 } else {
1193 self.mb_info[mb_idx].loop_str = self.dstate.loop_filter_level;
1194 }
1195 self.mb_info[mb_idx].upd_gf = self.dstate.force_gf_update;
1196 mb_idx += 1;
1197 }
1198 self.pcache.update_row();
1199 }
1200 let mut mb_idx = 0;
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);
1205 mb_idx += 1;
1206 }
1207 }
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();
1212 let mut mb_idx = 0;
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);
1220 }
1221 mb_idx += 1;
1222 }
1223 }
1224 self.shuf.add_golden_frame(new_gf);
1225 }
1226
1227 if !keep_probs {
1228 self.scan.copy_from_slice(&self.tmp_scan);
1229 }
1230 if update_gf {
1231 self.shuf.add_golden_frame(buf.clone());
1232 }
1233 self.shuf.add_frame(buf.clone());
1234
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 });
1238 Ok(frm.into_ref())
1239 }
1240 fn flush(&mut self) {
1241 self.shuf.clear();
1242 }
1243 }
1244
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 }
1249 }
1250
1251 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
1252 Box::new(VP7Decoder::new())
1253 }
1254
1255 #[cfg(test)]
1256 mod test {
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;
1262
1263 #[test]
1264 fn test_vp7() {
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);
1269
1270 // sample from https://trac.ffmpeg.org/ticket/5580
1271 test_decoding("avi", "vp7", "assets/Duck/interlaced_blit_pitch.avi", Some(12), &dmx_reg,
1272 &dec_reg, ExpectedTestResult::MD5Frames(vec![
1273 [0xb79fb6f8, 0xed51ac9e, 0x9e423456, 0xc0918e7f],
1274 [0xbf8d1274, 0x83515e15, 0x8c0887de, 0xfbfd05d3],
1275 [0x8ad00466, 0x80b6cbfb, 0x54de408e, 0x9efbc05e],
1276 [0x144122c5, 0x6897b553, 0x93474d29, 0x1a1274ec],
1277 [0x06ff5d07, 0x55825d38, 0x072b0a78, 0xfcb5020f],
1278 [0xfd01591b, 0xc42113e7, 0xc5a5550f, 0xb30f3b02],
1279 [0x155e0d6e, 0x96d75e06, 0x9bd7ce87, 0xacf868e1],
1280 [0xfd79103a, 0x695d21d3, 0xfeacb5b4, 0x1d869d08],
1281 [0xf4bcfeac, 0x0d2c305c, 0x11416c96, 0x626a5ef6],
1282 [0x3579b66c, 0x0a7d7dc0, 0xe80b0395, 0xf6a70661],
1283 [0x5773768c, 0x813442e9, 0x4dd6f793, 0xb10fe55f],
1284 [0xcaaf0ddb, 0x65c2410e, 0x95da5bba, 0x3b90128e],
1285 [0x74773773, 0xe1dbadeb, 0x57aaf64b, 0x9c21e3c7]]));
1286 }
1287 }
1288
1289 const MV_UPDATE_PROBS: [[u8; 17]; 2] = [
1290 [ 237, 246, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 250, 250, 252 ],
1291 [ 231, 243, 245, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 251, 251, 254 ]
1292 ];
1293 const DEFAULT_MV_PROBS: [[u8; 17]; 2] = [
1294 [ 162, 128, 225, 146, 172, 147, 214, 39, 156, 247, 210, 135, 68, 138, 220, 239, 246 ],
1295 [ 164, 128, 204, 170, 119, 235, 140, 230, 228, 244, 184, 201, 44, 173, 221, 239, 253 ]
1296 ];
1297
1298 const SUB_MV_REF_PROBS: [u8; 3] = [ 180, 162, 25 ];
1299
1300 const Y_DC_QUANTS: [i16; 128] = [
1301 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1302 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1303 32, 33, 33, 34, 35, 36, 36, 37, 38, 39, 39, 40, 41, 41, 42, 43,
1304 43, 44, 45, 45, 46, 47, 48, 48, 49, 50, 51, 52, 53, 53, 54, 56,
1305 57, 58, 59, 60, 62, 63, 65, 66, 68, 70, 72, 74, 76, 79, 81, 84,
1306 87, 90, 93, 96, 100, 104, 108, 112, 116, 121, 126, 131, 136, 142, 148, 154,
1307 160, 167, 174, 182, 189, 198, 206, 215, 224, 234, 244, 254, 265, 277, 288, 301,
1308 313, 327, 340, 355, 370, 385, 401, 417, 434, 452, 470, 489, 509, 529, 550, 572
1309 ];
1310 const Y_AC_QUANTS: [i16; 128] = [
1311 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
1312 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41,
1313 42, 44, 45, 46, 48, 49, 50, 51, 53, 54, 55, 56, 57, 58, 59, 61,
1314 62, 63, 64, 65, 67, 68, 69, 70, 72, 73, 75, 76, 78, 80, 82, 84,
1315 86, 88, 91, 93, 96, 99, 102, 105, 109, 112, 116, 121, 125, 130, 135, 140,
1316 146, 152, 158, 165, 172, 180, 188, 196, 205, 214, 224, 234, 245, 256, 268, 281,
1317 294, 308, 322, 337, 353, 369, 386, 404, 423, 443, 463, 484, 506, 529, 553, 578,
1318 604, 631, 659, 688, 718, 749, 781, 814, 849, 885, 922, 960, 1000, 1041, 1083, 1127
1319 ];
1320 const Y2_DC_QUANTS: [i16; 128] = [
1321 7, 9, 11, 13, 15, 17, 19, 21, 23, 26, 28, 30, 33, 35, 37, 39,
1322 42, 44, 46, 48, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 70, 72,
1323 74, 75, 77, 78, 80, 81, 83, 84, 85, 87, 88, 89, 90, 92, 93, 94,
1324 95, 96, 97, 99, 100, 101, 102, 104, 105, 106, 108, 109, 111, 113, 114, 116,
1325 118, 120, 123, 125, 128, 131, 134, 137, 140, 144, 148, 152, 156, 161, 166, 171,
1326 176, 182, 188, 195, 202, 209, 217, 225, 234, 243, 253, 263, 274, 285, 297, 309,
1327 322, 336, 350, 365, 381, 397, 414, 432, 450, 470, 490, 511, 533, 556, 579, 604,
1328 630, 656, 684, 713, 742, 773, 805, 838, 873, 908, 945, 983, 1022, 1063, 1105, 1148
1329 ];
1330 const Y2_AC_QUANTS: [i16; 128] = [
1331 7, 9, 11, 13, 16, 18, 21, 24, 26, 29, 32, 35, 38, 41, 43, 46,
1332 49, 52, 55, 58, 61, 64, 66, 69, 72, 74, 77, 79, 82, 84, 86, 88,
1333 91, 93, 95, 97, 98, 100, 102, 104, 105, 107, 109, 110, 112, 113, 115, 116,
1334 117, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 136, 138, 141, 143, 146,
1335 149, 152, 155, 158, 162, 166, 171, 175, 180, 185, 191, 197, 204, 210, 218, 226,
1336 234, 243, 252, 262, 273, 284, 295, 308, 321, 335, 350, 365, 381, 398, 416, 435,
1337 455, 476, 497, 520, 544, 569, 595, 622, 650, 680, 711, 743, 776, 811, 848, 885,
1338 925, 965, 1008, 1052, 1097, 1144, 1193, 1244, 1297, 1351, 1407, 1466, 1526, 1588, 1652, 1719
1339 ];
1340 const UV_DC_QUANTS: [i16; 128] = [
1341 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1342 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1343 32, 33, 33, 34, 35, 36, 36, 37, 38, 39, 39, 40, 41, 41, 42, 43,
1344 43, 44, 45, 45, 46, 47, 48, 48, 49, 50, 51, 52, 53, 53, 54, 56,
1345 57, 58, 59, 60, 62, 63, 65, 66, 68, 70, 72, 74, 76, 79, 81, 84,
1346 87, 90, 93, 96, 100, 104, 108, 112, 116, 121, 126, 131, 132, 132, 132, 132,
1347 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
1348 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132
1349 ];
1350 const UV_AC_QUANTS: [i16; 128] = [
1351 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
1352 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41,
1353 42, 44, 45, 46, 48, 49, 50, 51, 53, 54, 55, 56, 57, 58, 59, 61,
1354 62, 63, 64, 65, 67, 68, 69, 70, 72, 73, 75, 76, 78, 80, 82, 84,
1355 86, 88, 91, 93, 96, 99, 102, 105, 109, 112, 116, 121, 125, 130, 135, 140,
1356 146, 152, 158, 165, 172, 180, 188, 196, 205, 214, 224, 234, 245, 256, 268, 281,
1357 294, 308, 322, 337, 353, 369, 386, 404, 423, 443, 463, 484, 506, 529, 553, 578,
1358 604, 631, 659, 688, 718, 749, 781, 814, 849, 885, 922, 960, 1000, 1041, 1083, 1127
1359 ];