add bytes_left() to NAPacketiser so its internal buffer size can be monitored
[nihav.git] / nihav-duck / src / codecs / vp7.rs
CommitLineData
587a6d78
KS
1use nihav_core::codecs::*;
2use nihav_core::io::byteio::*;
b4d5b851 3use nihav_codec_support::codecs::{MV, ZERO_MV};
587a6d78 4use super::vpcommon::*;
0cc75664
KS
5use super::vp78::*;
6use super::vp78data::*;
7use super::vp78dsp::*;
587a6d78
KS
8use super::vp7dsp::*;
9
587a6d78
KS
10const PITCH_MODE_NORMAL: u8 = 0;
11const PITCH_MODE_FOUR: u8 = 1;
12const PITCH_MODE_X2: u8 = 2;
13const PITCH_MODE_X4: u8 = 3;
14
15#[derive(Clone,Copy,Default)]
16struct MBFeature {
17 present_prob: u8,
18 tree_probs: [u8; 3],
19 def_val: [u8; 4],
20}
21
587a6d78
KS
22struct SBParams<'a> {
23 coef_probs: &'a [[[[u8; 11]; 3]; 8]; 4],
24 scan: &'a [usize; 16],
25 qmat: &'a [i16; 16],
26}
27
47933c6d 28fn decode_subblock(bc: &mut BoolCoder, coeffs: &mut [i16; 16], ctype: usize, pctx: u8, sbparams: &SBParams) -> u8 {
587a6d78
KS
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)]
48struct MBInfo {
49 mb_type: VPMBType,
50 ymode: PredMode,
51 uvmode: PredMode,
52 loop_str: u8,
53 upd_gf: bool,
54}
55
56#[derive(Default)]
57struct 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,
99cc55ef
KS
86 pdc_pred_val: [i16; 2],
87 pdc_pred_count: [usize; 2],
587a6d78
KS
88
89 ipred_ctx_y: IPredContext,
90 ipred_ctx_u: IPredContext,
91 ipred_ctx_v: IPredContext,
92}
93
94impl 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
587a6d78
KS
103fn 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
587a6d78
KS
128struct 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
157impl 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 }
99cc55ef 289 fn decode_residue(&mut self, bc: &mut BoolCoder, mb_x: usize, mb_idx: usize, use_last: bool) {
587a6d78
KS
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];
99cc55ef
KS
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 {
587a6d78
KS
364 dc += pval;
365 y2block[0] = dc;
366 }
367 if (pval == 0) || (dc == 0) || ((pval ^ dc) < 0) {
99cc55ef 368 self.dstate.pdc_pred_count[pdc_idx] = 0;
587a6d78 369 } else if dc == pval {
99cc55ef 370 self.dstate.pdc_pred_count[pdc_idx] += 1;
587a6d78 371 }
99cc55ef 372 self.dstate.pdc_pred_val[pdc_idx] = dc;
587a6d78
KS
373 }
374 if has_ac[24] {
375 idct4x4(y2block);
4726ca2c 376 } else if y2block[0] != 0 {
587a6d78
KS
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]);
4726ca2c 386 } else if self.coeffs[i][0] != 0 {
587a6d78
KS
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 }
44901bc9 695 let tr_edge = if has_top { ydst[yoff - ystride + 15] } else { 0x80 };
587a6d78
KS
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;
44901bc9
KS
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);
587a6d78
KS
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 }
44901bc9
KS
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 }
587a6d78
KS
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);
b7c882c1 831 mc_block8x8(dst, voff, vstride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y, refframe, 2, &mut mc_buf);
587a6d78
KS
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,
b7c882c1 836 refframe, 2, &mut mc_buf, 8, pitch_smode);
587a6d78
KS
837 }
838 } else {
839 for y in 0..2 {
840 for x in 0..2 {
7589c13a
KS
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;
587a6d78
KS
856
857 if pitch_smode == 0 {
7589c13a 858 mc_block4x4(dst, uoff + x * 4, ustride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
587a6d78 859 chroma_mv.x, chroma_mv.y, refframe.clone(), 1, &mut mc_buf);
7589c13a 860 mc_block4x4(dst, voff + x * 4, vstride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
587a6d78
KS
861 chroma_mv.x, chroma_mv.y, refframe.clone(), 2, &mut mc_buf);
862 } else {
7589c13a 863 mc_block_special(dst, uoff + x * 4, ustride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
587a6d78
KS
864 chroma_mv.x, chroma_mv.y, refframe.clone(), 1, &mut mc_buf,
865 4, pitch_smode);
7589c13a 866 mc_block_special(dst, voff + x * 4, vstride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
587a6d78
KS
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
47933c6d
KS
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;
587a6d78 895 let inner_thr = if self.dstate.loop_sharpness == 0 {
47933c6d 896 i16::from(loop_str)
587a6d78 897 } else {
47933c6d 898 let bound1 = i16::from(9 - self.dstate.loop_sharpness);
587a6d78 899 let shift = (self.dstate.loop_sharpness + 3) >> 2;
47933c6d 900 (i16::from(loop_str) >> shift).min(bound1)
587a6d78 901 };
47933c6d 902 let hev_thr = i16::from(HIGH_EDGE_VAR_THR[if self.dstate.is_intra { 1 } else { 0 }][loop_str as usize]);
587a6d78
KS
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
942impl 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);
47933c6d 947 let myinfo = NACodecTypeInfo::Video(myvinfo);
587a6d78
KS
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 }
b7c882c1 958 #[allow(clippy::cognitive_complexity)]
587a6d78
KS
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();
9ceb80a2 982 self.scan.copy_from_slice(&DEFAULT_SCAN_ORDER);
6e24ec0b
KS
983 } else {
984 if !self.shuf.has_refs() {
985 return Err(DecoderError::MissingReference);
986 }
587a6d78
KS
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();
f7125215 1088 if self.dstate.is_intra || (self.dstate.version > 0) {
99cc55ef
KS
1089 self.dstate.pdc_pred_val = [0; 2];
1090 self.dstate.pdc_pred_count = [0; 2];
f7125215 1091 }
587a6d78
KS
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 }
99cc55ef 1181 self.decode_residue(&mut bc_main, mb_x, mb_idx, use_last);
587a6d78
KS
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 }
f9be4e75
KS
1240 fn flush(&mut self) {
1241 self.shuf.clear();
1242 }
587a6d78
KS
1243}
1244
7d57ae2f
KS
1245impl 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
ac818eac 1251pub fn get_decoder() -> Box<dyn NADecoder + Send> {
587a6d78
KS
1252 Box::new(VP7Decoder::new())
1253}
1254
1255#[cfg(test)]
1256mod test {
1257 use nihav_core::codecs::RegisteredDecoders;
1258 use nihav_core::demuxers::RegisteredDemuxers;
ce742854 1259 use nihav_codec_support::test::dec_video::*;
78fb6560 1260 use crate::duck_register_all_decoders;
e64739f8 1261 use nihav_commonfmt::generic_register_all_demuxers;
587a6d78
KS
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();
78fb6560 1268 duck_register_all_decoders(&mut dec_reg);
587a6d78 1269
d24468d9 1270 test_decoding("avi", "vp7", "assets/Duck/interlaced_blit_pitch.avi", Some(12), &dmx_reg,
d9dcff04
KS
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]]));
587a6d78
KS
1285 }
1286}
1287
0cc75664
KS
1288const 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 ]
587a6d78 1291];
0cc75664
KS
1292const 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 ]
587a6d78
KS
1295];
1296
0cc75664
KS
1297const SUB_MV_REF_PROBS: [u8; 3] = [ 180, 162, 25 ];
1298
1299const 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
587a6d78 1308];
0cc75664
KS
1309const 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
587a6d78 1318];
0cc75664
KS
1319const 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
587a6d78 1328];
0cc75664
KS
1329const 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
587a6d78 1338];
0cc75664
KS
1339const 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
587a6d78 1348];
0cc75664
KS
1349const 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
587a6d78 1358];