fix clippy warnings for update to rustc 1.46
[nihav.git] / nihav-realmedia / src / codecs / rv3040.rs
1 use nihav_core::formats::YUV420_FORMAT;
2 use nihav_core::frame::{NABufferType, NAVideoInfo, NAVideoBuffer, NAVideoBufferRef, FrameType, alloc_video_buffer};
3 use nihav_core::codecs::{NADecoderSupport, DecoderError, DecoderResult};
4 use nihav_codec_support::codecs::{MV, ZERO_MV, IPBShuffler};
5 use nihav_core::io::bitreader::{BitReader,BitReaderMode};
6 use nihav_core::io::intcode::*;
7 use nihav_codec_support::data::GenericCache;
8 use std::mem;
9
10 use super::rv34codes::*;
11 use super::rv34dsp::*;
12
13 trait RV34MVScale {
14 fn scale(&self, trd: u16, trb: u16) -> (MV, MV);
15 }
16
17 const TR_SHIFT: u8 = 14;
18 const TR_BIAS: i32 = 1 << (TR_SHIFT - 1);
19
20 impl RV34MVScale for MV {
21 fn scale(&self, trd: u16, trb: u16) -> (MV, MV) {
22 let ratio = ((trb as i32) << TR_SHIFT) / (trd as i32);
23 let mv_f = MV {
24 x: (((self.x as i32) * ratio + TR_BIAS) >> TR_SHIFT) as i16,
25 y: (((self.y as i32) * ratio + TR_BIAS) >> TR_SHIFT) as i16
26 };
27 let mv_b = mv_f - *self;
28 (mv_f, mv_b)
29 }
30 }
31
32 #[derive(Clone,Copy)]
33 pub struct RV34SliceHeader {
34 pub ftype: FrameType,
35 pub quant: u8,
36 pub pts: u16,
37 pub width: usize,
38 pub height: usize,
39 pub start: usize,
40 pub end: usize,
41 pub set_idx: usize,
42 pub deblock: bool,
43 }
44
45 impl RV34SliceHeader {
46 pub fn fits(&self, cmp: &RV34SliceHeader) -> bool {
47 (self.ftype == cmp.ftype) &&
48 (self.pts == cmp.pts) &&
49 (self.width == cmp.width) &&
50 (self.height == cmp.height)
51 }
52 }
53
54 #[allow(dead_code)]
55 #[derive(Debug,Clone,Copy,PartialEq)]
56 pub enum MBType {
57 MBIntra,
58 MBIntra16,
59 MBSkip,
60 MBP16x16,
61 MBP16x16Mix,
62 MBP16x8,
63 MBP8x16,
64 MBP8x8,
65 MBDirect,
66 MBBidir,
67 MBForward,
68 MBBackward,
69 Invalid,
70 }
71
72 impl MBType {
73 pub fn is_intra(self) -> bool {
74 (self == MBType::MBIntra) || (self == MBType::MBIntra16)
75 }
76 pub fn is_16(self) -> bool {
77 (self == MBType::MBIntra16) || (self == MBType::MBP16x16Mix)
78 }
79 pub fn is_intra_or_16(self) -> bool {
80 self.is_intra() || self.is_16()
81 }
82 pub fn get_num_mvs(self) -> usize {
83 match self {
84 MBType::MBIntra | MBType::MBIntra16 |
85 MBType::MBSkip | MBType::MBDirect => 0,
86 MBType::MBP16x16 | MBType::MBP16x16Mix |
87 MBType::MBForward | MBType::MBBackward => 1,
88 MBType::MBP16x8 | MBType::MBP8x16 | MBType::MBBidir => 2,
89 MBType::MBP8x8 => 4,
90 MBType::Invalid => unreachable!(),
91 }
92 }
93 pub fn is_fwd(self) -> bool {
94 match self {
95 MBType::MBP16x16 | MBType::MBP16x16Mix |
96 MBType::MBP16x8 | MBType::MBP8x16 | MBType::MBP8x8 |
97 MBType::MBForward => true,
98 _ => false,
99 }
100 }
101 pub fn is_bwd(self) -> bool {
102 match self {
103 MBType::MBBidir | MBType::MBBackward => true,
104 _ => false,
105 }
106 }
107 pub fn has_mv_dir(self, fwd: bool) -> bool {
108 match self {
109 MBType::MBBidir => true,
110 MBType::MBForward if fwd => true,
111 MBType::MBBackward if !fwd => true,
112 _ => false,
113 }
114 }
115 pub fn is_nomv(self) -> bool {
116 match self {
117 MBType::MBIntra | MBType::MBIntra16 | MBType::MBSkip | MBType::MBDirect => true,
118 _ => false,
119 }
120 }
121 /*pub fn is_16x16(self) -> bool {
122 match self {
123 MBType::MBP16x8 | MBType::MBP8x16 | MBType::MBP8x8 => false,
124 _ => true,
125 }
126 }*/
127 fn get_weight(self) -> usize {
128 match self {
129 MBType::MBIntra => 0,
130 MBType::MBIntra16 => 1,
131 MBType::MBSkip => unreachable!(),
132 MBType::MBP16x16 => 2,
133 MBType::MBP16x16Mix => 10,
134 MBType::MBP16x8 => 7,
135 MBType::MBP8x16 => 8,
136 MBType::MBP8x8 => 3,
137 MBType::MBDirect => 6,
138 MBType::MBBidir => 9,
139 MBType::MBForward => 4,
140 MBType::MBBackward => 5,
141 MBType::Invalid => unreachable!(),
142 }
143 }
144 }
145
146 const MBTYPE_FROM_WEIGHT: [MBType; 11] = [
147 MBType::MBIntra, MBType::MBIntra16, MBType::MBP16x16, MBType::MBP8x8,
148 MBType::MBForward, MBType::MBBackward, MBType::MBDirect, MBType::MBP16x8,
149 MBType::MBP8x16, MBType::MBBidir, MBType::MBP16x16Mix,
150 ];
151
152 #[derive(Clone,Copy)]
153 pub struct MBInfo {
154 pub mbtype: MBType,
155 pub skip_run: usize,
156 pub dquant: bool,
157 }
158
159 #[derive(Clone,Copy)]
160 pub struct RV34MBInfo {
161 pub mbtype: MBType,
162 pub cbp: u32,
163 pub deblock:u16,
164 pub cbp_c: u8, // for deblocking purposes
165 pub q: u8,
166 }
167
168 struct IntraModeState {
169 cache: GenericCache<i8>,
170 }
171
172 const RV34_INTRA_PRED4: [PredType4x4; 9] = [
173 PredType4x4::DC, PredType4x4::Ver, PredType4x4::Hor,
174 PredType4x4::DiagDownRight, PredType4x4::DiagDownLeft,
175 PredType4x4::VerRight, PredType4x4::VerLeft,
176 PredType4x4::HorUp, PredType4x4::HorDown
177 ];
178
179 const RV34_INTRA_PRED16: [PredType8x8; 4] = [
180 PredType8x8::DC, PredType8x8::Ver, PredType8x8::Hor, PredType8x8::Plane
181 ];
182
183 impl IntraModeState {
184 fn new(mb_w: usize) -> Self {
185 let stride = 1 + mb_w * 4 + 1;
186 IntraModeState { cache: GenericCache::new(4, stride, -1) }
187 }
188 fn reset(&mut self) { self.cache.reset(); }
189 fn update(&mut self) { self.cache.update_row(); }
190 fn get_pos(&self, xpos: usize) -> usize {
191 self.cache.stride + 1 + xpos * 4
192 }
193 fn set_mb_x(&mut self, mb_x: usize) {
194 self.cache.xpos = self.get_pos(mb_x);
195 }
196 fn fill_block(&mut self, val: i8) {
197 let mut pos = self.cache.xpos;
198 for _ in 0..4 {
199 for j in 0..4 {
200 self.cache.data[pos + j] = val;
201 }
202 pos += self.cache.stride;
203 }
204 }
205 fn get_pred16_type(&self, has_top: bool, has_left: bool) -> PredType8x8 {
206 if !has_top && !has_left { return PredType8x8::DC128; }
207 let mut im = RV34_INTRA_PRED16[self.cache.data[self.cache.xpos] as usize];
208 if !has_top {
209 im = match im {
210 PredType8x8::Plane | PredType8x8::Ver => PredType8x8::Hor,
211 PredType8x8::DC => PredType8x8::LeftDC,
212 _ => im,
213 };
214 } else if !has_left {
215 im = match im {
216 PredType8x8::Plane | PredType8x8::Hor => PredType8x8::Ver,
217 PredType8x8::DC => PredType8x8::TopDC,
218 _ => im,
219 };
220 }
221 im
222 }
223 fn get_pred8_type(&self, has_top: bool, has_left: bool) -> PredType8x8 {
224 if !has_top && !has_left { return PredType8x8::DC128; }
225 let mut im = RV34_INTRA_PRED16[self.cache.data[self.cache.xpos] as usize];
226 im = match im { PredType8x8::Plane => PredType8x8::DC, _ => im };
227 if !has_top {
228 im = match im {
229 PredType8x8::Plane | PredType8x8::Ver => PredType8x8::Hor,
230 PredType8x8::DC => PredType8x8::LeftDC,
231 _ => im,
232 };
233 } else if !has_left {
234 im = match im {
235 PredType8x8::Plane | PredType8x8::Hor => PredType8x8::Ver,
236 PredType8x8::DC => PredType8x8::TopDC,
237 _ => im,
238 };
239 }
240 im
241 }
242 fn get_pred4_type(&self, x: usize, y: usize, has_top: bool, has_left: bool) -> PredType4x4 {
243 let no_up = !has_top && (y == 0);
244 let no_left = !has_left && (x == 0);
245 if no_up && no_left { return PredType4x4::DC128; }
246 let no_down = !has_left || (x != 0) || (y == 3);
247
248 let mut im = RV34_INTRA_PRED4[self.cache.data[self.cache.xpos + x + y * self.cache.stride] as usize];
249
250 if no_up {
251 im = match im {
252 PredType4x4::Ver => PredType4x4::Hor,
253 PredType4x4::DC => PredType4x4::LeftDC,
254 _ => im,
255 };
256 } else if no_left {
257 im = match im {
258 PredType4x4::Hor => PredType4x4::Ver,
259 PredType4x4::DC => PredType4x4::TopDC,
260 PredType4x4::DiagDownLeft => PredType4x4::DiagDownLeftNoDown,
261 _ => im,
262 };
263 }
264 if no_down {
265 im = match im {
266 PredType4x4::DiagDownLeft => PredType4x4::DiagDownLeftNoDown,
267 PredType4x4::HorUp => PredType4x4::HorUpNoDown,
268 PredType4x4::VerLeft => PredType4x4::VerLeftNoDown,
269 _ => im,
270 };
271 }
272 im
273 }
274 //todo merge
275 fn get_pred4_type_chroma(&self, x: usize, y: usize, has_top: bool, has_left: bool) -> PredType4x4 {
276 let no_up = !has_top && (y == 0);
277 let no_left = !has_left && (x == 0);
278 if no_up && no_left { return PredType4x4::DC128; }
279 let no_down = !has_left || (x != 0) || (y == 1);
280
281 let mut im = RV34_INTRA_PRED4[self.cache.data[self.cache.xpos + x * 2 + y * 2 * self.cache.stride] as usize];
282
283 if no_up {
284 im = match im {
285 PredType4x4::Ver => PredType4x4::Hor,
286 PredType4x4::DC => PredType4x4::LeftDC,
287 _ => im,
288 };
289 } else if no_left {
290 im = match im {
291 PredType4x4::Hor => PredType4x4::Ver,
292 PredType4x4::DC => PredType4x4::TopDC,
293 PredType4x4::DiagDownLeft => PredType4x4::DiagDownLeftNoDown,
294 _ => im,
295 };
296 }
297 if no_down {
298 im = match im {
299 PredType4x4::DiagDownLeft => PredType4x4::DiagDownLeftNoDown,
300 PredType4x4::HorUp => PredType4x4::HorUpNoDown,
301 PredType4x4::VerLeft => PredType4x4::VerLeftNoDown,
302 _ => im,
303 };
304 }
305 im
306 }
307 }
308
309 pub struct MVInfo {
310 pub mv_b: Vec<MV>,
311 pub mv_f: Vec<MV>,
312 pub w: usize,
313 pub h: usize,
314 pub has_b: Vec<bool>,
315 pub has_f: Vec<bool>,
316 }
317
318 impl MVInfo {
319 fn new() -> Self {
320 Self { mv_b: Vec::new(), mv_f: Vec::new(), w: 0, h: 0, has_b: Vec::new(), has_f: Vec::new() }
321 }
322 fn resize(&mut self, mb_w: usize, mb_h: usize) {
323 self.w = mb_w * 2;
324 self.h = mb_h * 2;
325 self.reset();
326 }
327 fn reset(&mut self) {
328 let size = self.w * self.h;
329 self.mv_f.truncate(0);
330 self.mv_f.resize(size, ZERO_MV);
331 self.mv_b.truncate(0);
332 self.mv_b.resize(size, ZERO_MV);
333 self.has_f.truncate(0);
334 self.has_f.resize(size >> 2, false);
335 self.has_b.truncate(0);
336 self.has_b.resize(size >> 2, false);
337 }
338 fn fill(&mut self, mb_x: usize, mb_y: usize, fwd: bool, mv: MV) {
339 let idx = mb_x * 2 + mb_y * 2 * self.w;
340 if fwd {
341 self.mv_f[idx + 0] = mv;
342 self.mv_f[idx + 1] = mv;
343 self.mv_f[idx + self.w + 0] = mv;
344 self.mv_f[idx + self.w + 1] = mv;
345 } else {
346 self.mv_b[idx + 0] = mv;
347 self.mv_b[idx + 1] = mv;
348 self.mv_b[idx + self.w + 0] = mv;
349 self.mv_b[idx + self.w + 1] = mv;
350 }
351 }
352 fn get_mv_by_idx(&self, idx: usize, fwd: bool) -> MV {
353 if fwd { self.mv_f[idx] } else { self.mv_b[idx] }
354 }
355 fn pred_mv(&self, idx: usize, fwd: bool, has_top: bool, has_left: bool, has_tr: bool, has_tl: bool, is16: bool) -> MV {
356 if !has_top && !has_left { return ZERO_MV; }
357 let left_mv = if has_left { self.get_mv_by_idx(idx - 1, fwd) } else { ZERO_MV };
358 let top_mv = if has_top { self.get_mv_by_idx(idx - self.w, fwd) } else { left_mv };
359 let tr_add = if is16 { 2 } else { 1 };
360 let tr_mv;
361 if has_tr {
362 tr_mv = self.get_mv_by_idx(idx - self.w + tr_add, fwd);
363 } else if has_tl {
364 tr_mv = self.get_mv_by_idx(idx - self.w - 1, fwd);
365 } else {
366 tr_mv = left_mv;
367 }
368 MV::pred(left_mv, top_mv, tr_mv)
369 }
370 pub fn pred_mb_mv(&self, mb_x: usize, mb_y: usize, fwd: bool, has_top: bool, has_left: bool, has_tr: bool, has_tl: bool) -> MV {
371 self.pred_mv(mb_x * 2 + mb_y * 2 * self.w, fwd, has_top, has_left, has_tr, has_tl, true)
372 }
373 fn set_mb(&mut self, mb_x: usize, mb_y: usize, mbtype: MBType, ref_mvi: &Self, mvs: &[MV], sstate: &SState) {
374 let mb_idx = mb_x + mb_y * (self.w >> 1);
375 self.has_f[mb_idx] = mbtype.is_fwd();
376 self.has_b[mb_idx] = mbtype.is_bwd();
377 if mbtype.is_nomv() {
378 self.fill(mb_x, mb_y, true, ZERO_MV);
379 self.fill(mb_x, mb_y, false, ZERO_MV);
380 return;
381 }
382 if mbtype.is_fwd() {
383 self.fill(mb_x, mb_y, false, ZERO_MV);
384 } else if mbtype.is_bwd() {
385 self.fill(mb_x, mb_y, true, ZERO_MV);
386 }
387 let idx = mb_x * 2 + mb_y * 2 * self.w;
388
389 match mbtype {
390 MBType::MBSkip => {
391 self.fill(mb_x, mb_y, true, ZERO_MV/*pred_mv*/);
392 },
393 MBType::MBP16x16 |
394 MBType::MBP16x16Mix => {
395 let pred_mv = self.pred_mv(idx, mbtype.is_fwd(), sstate.has_top, sstate.has_left, sstate.has_tr, sstate.has_tl, true);
396 let new_mv = mvs[0] + pred_mv;
397 self.fill(mb_x, mb_y, true, new_mv);
398 },
399 MBType::MBP16x8 => {
400 let pred_mv = self.pred_mv(idx, mbtype.is_fwd(), sstate.has_top, sstate.has_left, sstate.has_tr, sstate.has_tl, true);
401 let new_mv = mvs[0] + pred_mv;
402 self.mv_f[idx + 0] = new_mv;
403 self.mv_f[idx + 1] = new_mv;
404
405 let idx2 = idx + self.w;
406 let pred_mv = self.pred_mv(idx2, true, true, sstate.has_left, false, sstate.has_left, true);
407 let new_mv = mvs[1] + pred_mv;
408 self.mv_f[idx2 + 0] = new_mv;
409 self.mv_f[idx2 + 1] = new_mv;
410 },
411 MBType::MBP8x16 => {
412 let pred_mv = self.pred_mv(idx, true, sstate.has_top, sstate.has_left, sstate.has_top, sstate.has_tl, false);
413 let new_mv = mvs[0] + pred_mv;
414 self.mv_f[idx] = new_mv;
415 self.mv_f[idx + self.w] = new_mv;
416
417 let pred_mv = self.pred_mv(idx + 1, true, sstate.has_top, true, sstate.has_tr, sstate.has_top, false);
418 let new_mv = mvs[1] + pred_mv;
419 self.mv_f[idx + 1] = new_mv;
420 self.mv_f[idx + self.w + 1] = new_mv;
421 },
422 MBType::MBP8x8 => {
423 let mut idx8 = idx;
424 let mut has_top = sstate.has_top;
425 for y in 0..2 {
426 for x in 0..2 {
427 let has_left = (x > 0) || sstate.has_left;
428 let has_tr = if y > 0 { x == 0 } else if x == 0 { sstate.has_top } else { sstate.has_tr };
429 let has_tl;
430 if y == 0 {
431 has_tl = if x == 0 { sstate.has_tl } else { sstate.has_top };
432 } else {
433 has_tl = if x == 0 { sstate.has_left } else { true };
434 }
435 let pred_mv = self.pred_mv(idx8 + x, true, has_top, has_left, has_tr, has_tl, false);
436 let new_mv = mvs[x + y * 2] + pred_mv;
437 self.mv_f[idx8 + x] = new_mv;
438 }
439 has_top = true;
440 idx8 += self.w;
441 }
442 },
443 MBType::MBDirect => {
444 let mut cum_mv_f = ZERO_MV;
445 let mut cum_mv_b = ZERO_MV;
446 let mut idx8 = idx;
447 for _ in 0..2 {
448 for x in 0..2 {
449 let (mv_f, mv_b) = ref_mvi.mv_f[idx8 + x].scale(sstate.trd, sstate.trb);
450 cum_mv_f += mv_f;
451 cum_mv_b += mv_b;
452 }
453 idx8 += self.w;
454 }
455 cum_mv_f.x >>= 2;
456 cum_mv_f.y >>= 2;
457 cum_mv_b.x >>= 2;
458 cum_mv_b.y >>= 2;
459 self.fill(mb_x, mb_y, true, cum_mv_f);
460 self.fill(mb_x, mb_y, false, cum_mv_b);
461 },
462 MBType::MBBidir => {
463 let pred_mv_f = ZERO_MV;
464 let new_mv = pred_mv_f + mvs[0];
465 self.fill(mb_x, mb_y, true, new_mv);
466 let pred_mv_b = ZERO_MV;
467 let new_mv = pred_mv_b + mvs[1];
468 self.fill(mb_x, mb_y, false, new_mv);
469 },
470 MBType::MBForward => {
471 let pred_mv = self.pred_mv(idx, mbtype.is_fwd(), sstate.has_top, sstate.has_left, sstate.has_tr, sstate.has_tl, true);
472 let new_mv = mvs[0] + pred_mv;
473 self.fill(mb_x, mb_y, true, new_mv);
474 },
475 MBType::MBBackward => {
476 let pred_mv = self.pred_mv(idx, mbtype.is_fwd(), sstate.has_top, sstate.has_left, sstate.has_tr, sstate.has_tl, true);
477 let new_mv = mvs[0] + pred_mv;
478 self.fill(mb_x, mb_y, false, new_mv);
479 },
480 _ => {},
481 }
482 }
483 pub fn get_mv(&self, mb_x: usize, mb_y: usize, x: usize, y: usize, fwd: bool) -> MV {
484 let idx = mb_x * 2 + x + (mb_y * 2 + y) * self.w;
485 if fwd { self.mv_f[idx] }
486 else { self.mv_b[idx] }
487 }
488 fn mv_gt_3(&self, mb_x: usize, mb_y: usize, x: usize, y: usize, vert: bool) -> bool {
489 let idx = mb_x * 2 + x + (mb_y * 2 + y) * self.w;
490 let off = if vert { self.w } else { 1 };
491 let diffx = self.mv_f[idx].x - self.mv_f[idx - off].x;
492 let diffy = self.mv_f[idx].y - self.mv_f[idx - off].y;
493 (diffx < -3) || (diffx > 3) || (diffy < -3) || (diffy > 3)
494 }
495 }
496
497 pub trait RV34BitstreamDecoder {
498 fn decode_slice_header(&mut self, br: &mut BitReader, old_w: usize, old_h: usize) -> DecoderResult<RV34SliceHeader>;
499 fn decode_intra_pred(&mut self, br: &mut BitReader, types: &mut [i8], pos: usize, tstride: usize, has_top: bool) -> DecoderResult<()>;
500 fn quant_dc(&self, is_intra: bool, q: u8) -> u8;
501 fn decode_inter_mb_hdr(&mut self, br: &mut BitReader, ftype: FrameType, mbtype: MBType) -> DecoderResult<MBInfo>;
502 fn predict_b_mv(&self, sstate: &SState, mvi: &MVInfo, mbtype: MBType, mvs: &[MV], mbinfo: &[RV34MBInfo]) -> (MV, MV);
503 }
504
505 pub trait RV34DSP {
506 fn loop_filter(&self, frame: &mut NAVideoBuffer<u8>, ftype: FrameType, mbinfo: &[RV34MBInfo], mb_w: usize, mb_h: usize, row: usize);
507 fn do_luma_mc(&self, frame: &mut NAVideoBuffer<u8>, prev_frame: &NAVideoBuffer<u8>, x: usize, y: usize, mv: MV, use16: bool, avg: bool);
508 fn do_chroma_mc(&self, frame: &mut NAVideoBuffer<u8>, prev_frame: &NAVideoBuffer<u8>, x: usize, y: usize, comp: usize, mv: MV, use8: bool, avg: bool);
509 }
510
511 fn parse_slice_offsets(src: &[u8], offsets: &mut Vec<usize>) -> DecoderResult<()> {
512 let num_slices = (src[0] as usize) + 1;
513 let ini_off = num_slices * 8 + 1;
514 offsets.truncate(0);
515
516 if ini_off >= src.len() { return Err(DecoderError::ShortData); }
517
518 let mut br = BitReader::new(&src[1..ini_off], BitReaderMode::BE);
519
520 for i in 0..num_slices {
521 br.skip(32)?;
522 let off = br.read(32)? as usize;
523 if (i == 0) && (off != 0) {
524 return Err(DecoderError::InvalidData);
525 }
526 if (i > 0) && (off <= offsets[i - 1]) {
527 return Err(DecoderError::InvalidData);
528 }
529 offsets.push(off);
530 }
531
532 Ok(())
533 }
534
535 fn decode_slice_header(br: &mut BitReader, bd: &mut dyn RV34BitstreamDecoder, slice_no: usize, slice_offs: &[usize], old_width: usize, old_height: usize) -> DecoderResult<RV34SliceHeader> {
536 validate!(slice_no < slice_offs.len());
537 br.seek((slice_offs[slice_no] * 8) as u32)?;
538 let mut shdr = bd.decode_slice_header(br, old_width, old_height)?;
539 if ((shdr.width == 0) || (shdr.height == 0)) && (shdr.ftype != FrameType::I) {
540 return Err(DecoderError::MissingReference);
541 }
542 if slice_no < slice_offs.len() - 1 {
543 let cur_pos = br.tell() as u32;
544 br.seek((slice_offs[slice_no + 1] * 8) as u32)?;
545 if let Ok(nhdr) = bd.decode_slice_header(br, shdr.width, shdr.height) {
546 validate!(nhdr.start > shdr.start);
547 shdr.end = nhdr.start;
548 } else {
549 if slice_no + 2 < slice_offs.len() {
550 br.seek((slice_offs[slice_no + 2] * 8) as u32)?;
551 if let Ok(nhdr) = bd.decode_slice_header(br, shdr.width, shdr.height) {
552 validate!(nhdr.start > shdr.start);
553 shdr.end = nhdr.start;
554 } else {
555 shdr.end = ((shdr.width + 15) >> 4) * ((shdr.height + 15) >> 4);
556 }
557 } else {
558 shdr.end = ((shdr.width + 15) >> 4) * ((shdr.height + 15) >> 4);
559 }
560 }
561 br.seek(cur_pos)?;
562 } else {
563 shdr.end = ((shdr.width + 15) >> 4) * ((shdr.height + 15) >> 4);
564 }
565 Ok(shdr)
566 }
567
568 const RV34_MB_MAX_SIZES: [usize; 6] = [ 0x2F, 0x62, 0x18B, 0x62F, 0x18BF, 0x23FF ];
569 const RV34_SLICE_START_BITS: [u8; 6] = [ 6, 7, 9, 11, 13, 14 ];
570
571 pub fn get_slice_start_offset_bits(w: usize, h: usize) -> u8 {
572 if (w == 0) || (h == 0) {
573 return 0;
574 }
575 let mb_size = ((w + 15) >> 4) * ((h + 15) >> 4) - 1;
576 let mut idx: usize = 0;
577 while (idx < 5) && (RV34_MB_MAX_SIZES[idx] < mb_size) { idx += 1; }
578 RV34_SLICE_START_BITS[idx]
579 }
580
581 const RV34_DQUANT_TAB: [[i8; 2]; 32] = [
582 [ 0, 0 ], [ 2, 1 ], [ -1, 1 ], [ -1, 1 ], [ -1, 1 ], [ -1, 1 ], [ -1, 1 ], [ -1, 1 ],
583 [ -1, 1 ], [ -1, 1 ], [ -1, 1 ], [ -2, 2 ], [ -2, 2 ], [ -2, 2 ], [ -2, 2 ], [ -2, 2 ],
584 [ -2, 2 ], [ -2, 2 ], [ -2, 2 ], [ -2, 2 ], [ -2, 2 ], [ -3, 3 ], [ -3, 3 ], [ -3, 3 ],
585 [ -3, 3 ], [ -3, 3 ], [ -3, 3 ], [ -3, 3 ], [ -3, 3 ], [ -3, 2 ], [ -3, 1 ], [ -3,-5 ]
586 ];
587
588 const RV34_QUANT_TAB: [u16; 32] = [
589 60, 67, 76, 85, 96, 108, 121, 136,
590 152, 171, 192, 216, 242, 272, 305, 341,
591 383, 432, 481, 544, 606, 683, 767, 854,
592 963, 1074, 1212, 1392, 1566, 1708, 1978, 2211
593 ];
594
595 const RV34_CHROMA_QUANT_DC: [u8; 32] = [
596 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
597 14, 15, 15, 16, 17, 18, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23
598 ];
599 const RV34_CHROMA_QUANT_AC: [u8; 32] = [
600 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
601 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25
602 ];
603
604 fn decode_dquant(br: &mut BitReader, q: u8) -> DecoderResult<u8> {
605 if br.read_bool()? {
606 let diff = RV34_DQUANT_TAB[q as usize][br.read(1)? as usize];
607 let qp = (q as i8) + diff;
608 validate!((qp > 0) && (qp < 32));
609 Ok(qp as u8)
610 } else {
611 let qp = br.read(5)? as u8;
612 Ok(qp)
613 }
614 }
615
616 pub struct SState {
617 pub mb_x: usize,
618 pub mb_y: usize,
619 pub mb_w: usize,
620 pub mb_h: usize,
621 pub cbp: u32,
622 pub q: u8,
623 pub q_dc: u8,
624 pub set_idx: usize,
625 pub has_left: bool,
626 pub has_top: bool,
627 pub has_tl: bool,
628 pub has_tr: bool,
629 pub trd: u16,
630 pub trb: u16,
631 }
632
633 impl SState {
634 fn new() -> Self {
635 Self {
636 mb_x: 0,
637 mb_y: 0,
638 mb_w: 0,
639 mb_h: 0,
640 cbp: 0,
641 q: 0,
642 q_dc: 0,
643 set_idx: 0,
644 has_left: false,
645 has_top: false,
646 has_tl: false,
647 has_tr: false,
648 trd: 0,
649 trb: 0,
650 }
651 }
652 }
653
654 struct MBHist {
655 is_p: bool,
656 hist: [MBType; 4],
657 count: usize,
658 }
659
660 impl MBHist {
661 fn new(ftype: FrameType) -> Self { Self { is_p: ftype == FrameType::P, hist: [MBType::Invalid; 4], count: 0 } }
662 fn add(&mut self, mbt: MBType) {
663 let mbt2 = match mbt {
664 MBType::MBSkip if self.is_p => MBType::MBP16x16,
665 MBType::MBSkip if !self.is_p => MBType::MBDirect,
666 _ => mbt,
667 };
668 self.hist[self.count] = mbt2;
669 self.count += 1;
670 }
671 fn get_mbtype(&self) -> MBType {
672 if self.count == 0 {
673 MBType::MBIntra
674 } else if self.count == 1 {
675 self.hist[0]
676 } else if self.count == 2 {
677 if self.hist[0].get_weight() <= self.hist[1].get_weight() {
678 self.hist[0]
679 } else {
680 self.hist[1]
681 }
682 } else {
683 let mut w: [usize; 12] = [0; 12];
684 for i in 0..self.count { w[self.hist[i].get_weight()] += 1; }
685 let mut nz_idx = 0;
686 for i in 0..12 {
687 if w[i] == self.count { return MBTYPE_FROM_WEIGHT[i]; }
688 if (w[i] > w[nz_idx]) || (w[nz_idx] == 0) { nz_idx = i; }
689 }
690
691 MBTYPE_FROM_WEIGHT[nz_idx]
692 }
693 }
694 }
695
696 fn decode_mv(br: &mut BitReader) -> DecoderResult<MV> {
697 let x = br.read_code_signed(IntCodeType::Gamma)? as i16;
698 let y = br.read_code_signed(IntCodeType::Gamma)? as i16;
699 Ok(MV{ x, y })
700 }
701
702 fn do_mc_16x16(dsp: &mut dyn RV34DSP, buf: &mut NAVideoBuffer<u8>, prevbuf: &NAVideoBuffer<u8>, mb_x: usize, mb_y: usize, mv: MV, avg: bool) {
703 dsp.do_luma_mc (buf, prevbuf, mb_x * 16, mb_y * 16, mv, true, avg);
704 dsp.do_chroma_mc(buf, prevbuf, mb_x * 8, mb_y * 8, 1, mv, true, avg);
705 dsp.do_chroma_mc(buf, prevbuf, mb_x * 8, mb_y * 8, 2, mv, true, avg);
706 }
707
708 fn do_mc_8x8(dsp: &mut dyn RV34DSP, buf: &mut NAVideoBuffer<u8>, prevbuf: &NAVideoBuffer<u8>, mb_x: usize, xoff: usize, mb_y: usize, yoff: usize, mv: MV, avg: bool) {
709 dsp.do_luma_mc (buf, prevbuf, mb_x * 16 + xoff * 8, mb_y * 16 + yoff * 8, mv, false, avg);
710 dsp.do_chroma_mc(buf, prevbuf, mb_x * 8 + xoff * 4, mb_y * 8 + yoff * 4, 1, mv, false, avg);
711 dsp.do_chroma_mc(buf, prevbuf, mb_x * 8 + xoff * 4, mb_y * 8 + yoff * 4, 2, mv, false, avg);
712 }
713
714 fn do_avg(cdsp: &RV34CommonDSP, buf: &mut NAVideoBuffer<u8>, avg_buf: &NAVideoBuffer<u8>, mb_x: usize, xb: usize, mb_y: usize, yb: usize, size: usize, ratio1: u32, ratio2: u32) {
715 for comp in 0..3 {
716 let xoff = if comp == 0 { mb_x * 16 + xb * 8 } else { mb_x * 8 + xb * 4 };
717 let yoff = if comp == 0 { mb_y * 16 + yb * 8 } else { mb_y * 8 + yb * 4 };
718 let csize = if comp == 0 { size } else { size >> 1 };
719 let dstride = buf.get_stride(comp);
720 let doffset = buf.get_offset(comp) + xoff + yoff * dstride;
721 let data = buf.get_data_mut().unwrap();
722 let dst: &mut [u8] = data.as_mut_slice();
723
724 let sstride = avg_buf.get_stride(comp);
725 let soffset = avg_buf.get_offset(comp);
726 let data = avg_buf.get_data();
727 let src: &[u8] = data.as_slice();
728
729 if ratio1 == ratio2 {
730 cdsp.avg(dst, doffset, dstride, src, soffset, sstride, csize);
731 } else {
732 cdsp.weight(dst, doffset, dstride, src, soffset, sstride, ratio2, ratio1, csize);
733 }
734 }
735 }
736
737 pub struct RV34Decoder {
738 is_rv30: bool,
739 coderead: RV34Codes,
740 dsp: Box<dyn RV34DSP + Send>,
741 cdsp: RV34CommonDSP,
742 width: usize,
743 height: usize,
744 ipbs: IPBShuffler,
745 mvi: MVInfo,
746 ref_mvi: MVInfo,
747 last_ts: u16,
748 next_ts: u16,
749 ratio1: u32,
750 ratio2: u32,
751 is_b: bool,
752 mbinfo: Vec<RV34MBInfo>,
753 avg_buf: NAVideoBufferRef<u8>,
754 base_ts: u64,
755 }
756
757 impl RV34Decoder {
758 pub fn new(is_rv30: bool, dsp: Box<dyn RV34DSP + Send>) -> Self {
759 let tmp_vinfo = NAVideoInfo::new(16, 16, false, YUV420_FORMAT);
760 let vt = alloc_video_buffer(tmp_vinfo, 4).unwrap();
761 let vb = vt.get_vbuf();
762 let avg_buf = vb.unwrap();
763 RV34Decoder {
764 is_rv30,
765 coderead: RV34Codes::new(),
766 dsp,
767 cdsp: RV34CommonDSP::new(),
768 ipbs: IPBShuffler::new(),
769 mvi: MVInfo::new(),
770 ref_mvi: MVInfo::new(),
771 mbinfo: Vec::new(),
772 width: 0, height: 0,
773 last_ts: 0, next_ts: 0,
774 ratio1: 0, ratio2: 0,
775 is_b: false,
776 avg_buf,
777 base_ts: 0,
778 }
779 }
780 fn decode_mb_header_intra(&mut self, bd: &mut dyn RV34BitstreamDecoder, br: &mut BitReader, is_i16: bool, im: &mut IntraModeState, q: u8, has_top: bool, has_dq: bool) -> DecoderResult<MBInfo> {
781 if is_i16 {
782 let imode = br.read(2)? as i8;
783 im.fill_block(imode);
784 Ok(MBInfo { mbtype: MBType::MBIntra16, skip_run: 0, dquant: false })
785 } else {
786 let dq = if !has_dq {
787 if !self.is_rv30 { !br.read_bool()? } else { false }
788 } else { false };
789 if dq {
790 decode_dquant(br, q)?;
791 }
792 bd.decode_intra_pred(br, im.cache.data.as_mut_slice(), im.cache.xpos, im.cache.stride, has_top)?;
793 Ok(MBInfo { mbtype: MBType::MBIntra, skip_run: 0, dquant: dq })
794 }
795 }
796 fn decode_mb_header_inter(&mut self, bd: &mut dyn RV34BitstreamDecoder, br: &mut BitReader, ftype: FrameType, mbtype: MBType, im: &mut IntraModeState, q: u8, has_top: bool) -> DecoderResult<MBInfo> {
797 let hdr = bd.decode_inter_mb_hdr(br, ftype, mbtype)?;
798 validate!(hdr.mbtype != MBType::Invalid);
799 if hdr.dquant {
800 decode_dquant(br, q)?;
801 }
802 if hdr.mbtype.is_intra() {
803 return self.decode_mb_header_intra(bd, br, hdr.mbtype.is_16(), im, q, has_top, true);
804 }
805 Ok(hdr)
806 }
807
808 fn decode_mb_intra(&mut self, sstate: &SState, imode: &IntraModeState, buf: &mut NAVideoBuffer<u8>, br: &mut BitReader, is_16: bool) -> DecoderResult<()> {
809 let mut cur_cbp = sstate.cbp;
810 {
811 let q_dc = RV34_QUANT_TAB[sstate.q_dc as usize];
812 let q_ac = RV34_QUANT_TAB[sstate.q as usize];
813 let luma_set = if is_16 { 2 } else { 1 };
814 let mut coeffs16: [i16; 16] = [0; 16];
815 if is_16 {
816 let has_ac = self.coderead.decode_block(br, &mut coeffs16, 3, 0, q_dc, q_dc, q_ac)?;
817 if has_ac {
818 self.cdsp.transform16(&mut coeffs16);
819 } else {
820 self.cdsp.transform16_dc(&mut coeffs16);
821 }
822 }
823 let stride = buf.get_stride(0);
824 let mut offset = buf.get_offset(0) + sstate.mb_x * 16 + sstate.mb_y * 16 * stride;
825 let data = buf.get_data_mut().unwrap();
826 let framebuf: &mut [u8] = data.as_mut_slice();
827
828 if is_16 {
829 let im16 = imode.get_pred16_type(sstate.has_top, sstate.has_left);
830 self.cdsp.ipred16x16[im16 as usize](framebuf, offset, stride);
831 }
832
833 for y in 0..4 {
834 for x in 0..4 {
835 let mut coeffs: [i16; 16] = [0; 16];
836 let has_ac;
837 if (cur_cbp & 1) != 0 {
838 has_ac = self.coderead.decode_block(br, &mut coeffs, luma_set, 0, q_ac, q_ac, q_ac)?;
839 } else {
840 has_ac = false;
841 }
842 if is_16 {
843 coeffs[0] = coeffs16[x + y * 4];
844 } else {
845 let noright = (sstate.mb_x == sstate.mb_w - 1) && (x == 3);
846 let has_top = sstate.has_top || (y > 0);
847 let im = imode.get_pred4_type(x, y, sstate.has_top, sstate.has_left);
848 let topright: [u8; 4] = if (noright && sstate.has_top && y == 0) || (x == 3 && y > 0) {
849 let i = offset + x * 4 - stride;
850 [framebuf[i + 3], framebuf[i + 3], framebuf[i + 3], framebuf[i + 3]]
851 } else if has_top {
852 let i = offset + x * 4 - stride;
853 [framebuf[i + 4], framebuf[i + 5], framebuf[i + 6], framebuf[i + 7]]
854 } else {
855 [0; 4]
856 };
857 self.cdsp.ipred4x4[im as usize](framebuf, offset + x*4, stride, &topright);
858 }
859 if has_ac {
860 self.cdsp.transform(&mut coeffs);
861 } else {
862 self.cdsp.transform_dc(&mut coeffs);
863 }
864 self.cdsp.add_coeffs(framebuf, offset + x * 4, stride, &coeffs);
865 cur_cbp >>= 1;
866 }
867 offset += stride * 4;
868 }
869 }
870 let q_dc = RV34_QUANT_TAB[RV34_CHROMA_QUANT_DC[sstate.q as usize] as usize];
871 let q_ac = RV34_QUANT_TAB[RV34_CHROMA_QUANT_AC[sstate.q as usize] as usize];
872 let chroma_set = 0;
873 for comp in 1..3 {
874 let stride = buf.get_stride(comp);
875 let mut offset = buf.get_offset(comp) + sstate.mb_x * 8 + sstate.mb_y * 8 * stride;
876 let data = buf.get_data_mut().unwrap();
877 let framebuf: &mut [u8] = data.as_mut_slice();
878 if is_16 {
879 let im8 = imode.get_pred8_type(sstate.has_top, sstate.has_left);
880 self.cdsp.ipred8x8[im8 as usize](framebuf, offset, stride);
881 }
882 for y in 0..2 {
883 for x in 0..2 {
884 let mut coeffs: [i16; 16] = [0; 16];
885 let has_ac;
886 if (cur_cbp & 1) != 0 {
887 has_ac = self.coderead.decode_block(br, &mut coeffs, chroma_set, 1, q_dc, q_ac, q_ac)?;
888 } else {
889 has_ac = false;
890 }
891 if !is_16 {
892 let noright = (sstate.mb_x == sstate.mb_w - 1) && (x == 1);
893 let has_top = sstate.has_top || (y > 0);
894 let im = imode.get_pred4_type_chroma(x, y, sstate.has_top, sstate.has_left);
895 let topright: [u8; 4] = if (noright && sstate.has_top && y == 0) || (x == 1 && y > 0) {
896 let i = offset + x * 4 - stride;
897 [framebuf[i + 3], framebuf[i + 3], framebuf[i + 3], framebuf[i + 3]]
898 } else if has_top {
899 let i = offset + x * 4 - stride;
900 [framebuf[i + 4], framebuf[i + 5], framebuf[i + 6], framebuf[i + 7]]
901 } else {
902 [0; 4]
903 };
904 self.cdsp.ipred4x4[im as usize](framebuf, offset + x*4, stride, &topright);
905 }
906 if has_ac {
907 self.cdsp.transform(&mut coeffs);
908 } else {
909 self.cdsp.transform_dc(&mut coeffs);
910 }
911 self.cdsp.add_coeffs(framebuf, offset + x * 4, stride, &coeffs);
912 cur_cbp >>= 1;
913 }
914 offset += stride * 4;
915 }
916 }
917 Ok(())
918 }
919
920 fn do_mc(&mut self, buf: &mut NAVideoBuffer<u8>, mbh: &MBInfo, sstate: &SState) {
921 let mb_x = sstate.mb_x;
922 let mb_y = sstate.mb_y;
923 match mbh.mbtype {
924 MBType::MBP16x16 | MBType::MBP16x16Mix => {
925 if let Some(ref prevbuf) = self.ipbs.get_lastref() {
926 let mv = self.mvi.get_mv(mb_x, mb_y, 0, 0, true);
927 do_mc_16x16(self.dsp.as_mut(), buf, prevbuf, mb_x, mb_y, mv, false);
928 }
929 },
930 MBType::MBForward => {
931 if let Some(ref fwdbuf) = self.ipbs.get_b_fwdref() {
932 let mv = self.mvi.get_mv(mb_x, mb_y, 0, 0, true);
933 do_mc_16x16(self.dsp.as_mut(), buf, fwdbuf, mb_x, mb_y, mv, false);
934 }
935 },
936 MBType::MBBackward => {
937 if let Some(ref bwdbuf) = self.ipbs.get_b_bwdref() {
938 let mv = self.mvi.get_mv(mb_x, mb_y, 0, 0, false);
939 do_mc_16x16(self.dsp.as_mut(), buf, bwdbuf, mb_x, mb_y, mv, false);
940 }
941 },
942 MBType::MBP8x8 | MBType::MBP8x16 | MBType::MBP16x8 => {
943 if let Some(ref prevbuf) = self.ipbs.get_lastref() {
944 for y in 0..2 {
945 for x in 0..2 {
946 let mv = self.mvi.get_mv(mb_x, mb_y, x, y, true);
947 do_mc_8x8(self.dsp.as_mut(), buf, prevbuf, mb_x, x, mb_y, y, mv, false);
948 }
949 }
950 }
951 },
952 MBType::MBSkip if !self.is_b => {
953 if let Some(ref prevbuf) = self.ipbs.get_lastref() {
954 do_mc_16x16(self.dsp.as_mut(), buf, prevbuf, mb_x, mb_y, ZERO_MV, false);
955 }
956 },
957 MBType::MBSkip | MBType::MBDirect => {
958 if let (Some(ref fwdbuf), Some(ref bwdbuf)) = (self.ipbs.get_b_fwdref(), self.ipbs.get_b_bwdref()) {
959 for y in 0..2 {
960 for x in 0..2 {
961 let (mv_f, mv_b) = self.ref_mvi.get_mv(mb_x, mb_y, x, y, true).scale(sstate.trd, sstate.trb);
962 do_mc_8x8(self.dsp.as_mut(), buf, fwdbuf, mb_x, x, mb_y, y, mv_f, false);
963 do_mc_8x8(self.dsp.as_mut(), &mut self.avg_buf, bwdbuf, mb_x, x, mb_y, y, mv_b, true);
964 do_avg(&self.cdsp, buf, &self.avg_buf, mb_x, x, mb_y, y, 8, self.ratio1, self.ratio2);
965 }
966 }
967 }
968 },
969 MBType::MBBidir => {
970 if let (Some(ref fwdbuf), Some(ref bwdbuf)) = (self.ipbs.get_b_fwdref(), self.ipbs.get_b_bwdref()) {
971 let mv_f = self.mvi.get_mv(mb_x, mb_y, 0, 0, true);
972 let mv_b = self.mvi.get_mv(mb_x, mb_y, 0, 0, false);
973 do_mc_16x16(self.dsp.as_mut(), buf, fwdbuf, mb_x, mb_y, mv_f, false);
974 do_mc_16x16(self.dsp.as_mut(), &mut self.avg_buf, bwdbuf, mb_x, mb_y, mv_b, true);
975 do_avg(&self.cdsp, buf, &self.avg_buf, mb_x, 0, mb_y, 0, 16, self.ratio1, self.ratio2);
976 }
977 },
978 _ => {},
979 };
980 }
981 fn decode_mb_inter(&mut self, sstate: &SState, mbh: &MBInfo, buf: &mut NAVideoBuffer<u8>, br: &mut BitReader, is_16: bool) -> DecoderResult<()> {
982 self.do_mc(buf, mbh, sstate);
983
984 let mut cur_cbp = sstate.cbp;
985
986 {
987 let q_dc = RV34_QUANT_TAB[sstate.q_dc as usize];
988 let q_ac = RV34_QUANT_TAB[sstate.q as usize];
989 let luma_set = if is_16 { 2 } else { 0 };
990 let mut coeffs16: [i16; 16] = [0; 16];
991 if is_16 {
992 let has_ac = self.coderead.decode_block(br, &mut coeffs16, 3, 0, q_dc, q_dc, q_ac)?;
993 if has_ac {
994 self.cdsp.transform16(&mut coeffs16);
995 } else {
996 self.cdsp.transform16_dc(&mut coeffs16);
997 }
998 }
999 let stride = buf.get_stride(0);
1000 let mut offset = buf.get_offset(0) + sstate.mb_x * 16 + sstate.mb_y * 16 * stride;
1001 let data = buf.get_data_mut().unwrap();
1002 let framebuf: &mut [u8] = data.as_mut_slice();
1003
1004 for y in 0..4 {
1005 for x in 0..4 {
1006 let mut coeffs: [i16; 16] = [0; 16];
1007 let has_ac;
1008 if (cur_cbp & 1) != 0 {
1009 has_ac = self.coderead.decode_block(br, &mut coeffs, luma_set, 0, q_ac, q_ac, q_ac)?;
1010 } else {
1011 has_ac = false;
1012 }
1013 if is_16 {
1014 coeffs[0] = coeffs16[x + y * 4];
1015 }
1016 if has_ac {
1017 self.cdsp.transform(&mut coeffs);
1018 } else {
1019 self.cdsp.transform_dc(&mut coeffs);
1020 }
1021 self.cdsp.add_coeffs(framebuf, offset + x * 4, stride, &coeffs);
1022 cur_cbp >>= 1;
1023 }
1024 offset += stride * 4;
1025 }
1026 }
1027 if is_16 {
1028 self.coderead.select_codes(false, sstate.q, sstate.set_idx, false);
1029 }
1030 let q_dc = RV34_QUANT_TAB[RV34_CHROMA_QUANT_DC[sstate.q as usize] as usize];
1031 let q_ac = RV34_QUANT_TAB[RV34_CHROMA_QUANT_AC[sstate.q as usize] as usize];
1032 let chroma_set = 1;
1033 for comp in 1..3 {
1034 let stride = buf.get_stride(comp);
1035 let mut offset = buf.get_offset(comp) + sstate.mb_x * 8 + sstate.mb_y * 8 * stride;
1036 let data = buf.get_data_mut().unwrap();
1037 let framebuf: &mut [u8] = data.as_mut_slice();
1038 for _ in 0..2 {
1039 for x in 0..2 {
1040 let mut coeffs: [i16; 16] = [0; 16];
1041 let has_ac;
1042 if (cur_cbp & 1) != 0 {
1043 has_ac = self.coderead.decode_block(br, &mut coeffs, chroma_set, 1, q_dc, q_ac, q_ac)?;
1044 } else {
1045 has_ac = false;
1046 }
1047 if has_ac {
1048 self.cdsp.transform(&mut coeffs);
1049 } else {
1050 self.cdsp.transform_dc(&mut coeffs);
1051 }
1052 self.cdsp.add_coeffs(framebuf, offset + x * 4, stride, &coeffs);
1053 cur_cbp >>= 1;
1054 }
1055 offset += stride * 4;
1056 }
1057 }
1058 Ok(())
1059 }
1060 fn fill_deblock_flags(&self, sstate: &SState, mb_pos: usize, mbinfo: &mut Vec<RV34MBInfo>) {
1061 let mbt = mbinfo[mb_pos].mbtype;
1062 let mut hmvmask = 0;
1063 let mut vmvmask = 0;
1064
1065 for y in 0..2 {
1066 for x in 0..2 {
1067 let shift = x * 2 + y * 8;
1068 if ((x > 0) || (sstate.mb_x > 0)) && self.mvi.mv_gt_3(sstate.mb_x, sstate.mb_y, x, y, false) {
1069 vmvmask |= 0x11 << shift;
1070 }
1071 if ((y > 0) || sstate.has_top) && self.mvi.mv_gt_3(sstate.mb_x, sstate.mb_y, x, y, true) {
1072 hmvmask |= 0x03 << shift;
1073 }
1074 }
1075 }
1076 if !sstate.has_top { hmvmask &= !0x000F; }
1077 if sstate.mb_x == 0 { vmvmask &= !0x1111; }
1078 if self.is_rv30 {
1079 vmvmask |= (vmvmask & 0x4444) >> 1;
1080 hmvmask |= (hmvmask & 0x0F00) >> 4;
1081 if sstate.mb_x > 0 {
1082 mbinfo[mb_pos - 1].deblock |= (vmvmask & 0x1111) << 3;
1083 }
1084 if sstate.has_top {
1085
1086 mbinfo[mb_pos - sstate.mb_w].deblock |= (hmvmask & 0xF) << 12;
1087 }
1088 }
1089 if mbt.is_intra_or_16() {
1090 mbinfo[mb_pos].deblock = 0xFFFF;
1091 mbinfo[mb_pos].cbp_c = 0xFF;
1092 } else {
1093 mbinfo[mb_pos].deblock = (mbinfo[mb_pos].cbp as u16) | hmvmask | vmvmask;
1094 mbinfo[mb_pos].cbp_c = (mbinfo[mb_pos].cbp >> 16) as u8;
1095 }
1096 }
1097
1098 #[allow(clippy::cognitive_complexity)]
1099 pub fn parse_frame(&mut self, supp: &mut NADecoderSupport, src: &[u8], bd: &mut dyn RV34BitstreamDecoder) -> DecoderResult<(NABufferType, FrameType, u64)> {
1100 let mut slice_offs: Vec<usize> = Vec::new();
1101 parse_slice_offsets(src, &mut slice_offs)?;
1102 let ini_off = slice_offs.len() * 8 + 1;
1103
1104 let mut br = BitReader::new(&src[ini_off..], BitReaderMode::BE);
1105 let hdr0 = decode_slice_header(&mut br, bd, 0, slice_offs.as_slice(), self.width, self.height)?;
1106 validate!((hdr0.width != 0) && (hdr0.height != 0));
1107 self.width = hdr0.width;
1108 self.height = hdr0.height;
1109 let mb_w = (hdr0.width + 15) >> 4;
1110 let mb_h = (hdr0.height + 15) >> 4;
1111 let mut mb_pos: usize = 0;
1112 let mut slice = hdr0;
1113 let mut slice_no: usize = 1;
1114 let is_intra = hdr0.ftype == FrameType::I;
1115 let mut skip_run: usize = 0;
1116 let mut imode = IntraModeState::new(mb_w);
1117 let mut q = hdr0.quant;
1118
1119 let mut sstate = SState::new();
1120 let mut mbinfo: Vec<RV34MBInfo> = Vec::with_capacity(mb_w * mb_h);
1121
1122 self.is_b = hdr0.ftype == FrameType::B;
1123 if hdr0.ftype != FrameType::B {
1124 self.last_ts = self.next_ts;
1125 self.next_ts = hdr0.pts;
1126 if self.last_ts > self.next_ts {
1127 self.base_ts += 1 << 13;
1128 }
1129 }
1130 match hdr0.ftype {
1131 FrameType::P => {
1132 if self.ipbs.get_lastref().is_none() {
1133 return Err(DecoderError::MissingReference);
1134 }
1135 },
1136 FrameType::B => {
1137 if self.ipbs.get_lastref().is_none() {
1138 return Err(DecoderError::MissingReference);
1139 }
1140 if self.ipbs.get_nextref().is_none() {
1141 return Err(DecoderError::MissingReference);
1142 }
1143 },
1144 _ => {},
1145 };
1146 let ts_diff = (self.next_ts << 3).wrapping_sub(hdr0.pts << 3) >> 3;
1147 let ts = self.base_ts + (self.next_ts as u64) - (ts_diff as u64);
1148 sstate.trd = (self.next_ts << 3).wrapping_sub(self.last_ts << 3) >> 3;
1149 sstate.trb = (hdr0.pts << 3).wrapping_sub(self.last_ts << 3) >> 3;
1150 if sstate.trb != 0 {
1151 self.ratio1 = ((sstate.trb as u32) << 14) / (sstate.trd as u32);
1152 self.ratio2 = (((sstate.trd as u32) - (sstate.trb as u32)) << 14) / (sstate.trd as u32);
1153 } else {
1154 self.ratio1 = 1 << 14 >> 1;
1155 self.ratio2 = 1 << 14 >> 1;
1156 }
1157 //todo validate against ref frame
1158
1159 let vinfo = NAVideoInfo::new(hdr0.width, hdr0.height, false, YUV420_FORMAT);
1160 let ret = supp.pool_u8.get_free();
1161 if ret.is_none() {
1162 return Err(DecoderError::AllocError);
1163 }
1164 let mut buf = ret.unwrap();
1165 if buf.get_info() != vinfo {
1166 self.ipbs.clear();
1167 supp.pool_u8.reset();
1168 supp.pool_u8.prealloc_video(vinfo, 4)?;
1169 let ret = supp.pool_u8.get_free();
1170 if ret.is_none() {
1171 return Err(DecoderError::AllocError);
1172 }
1173 buf = ret.unwrap();
1174 }
1175
1176 sstate.q = q;
1177 sstate.has_top = false;
1178 sstate.mb_w = mb_w;
1179 sstate.mb_h = mb_h;
1180 sstate.set_idx = hdr0.set_idx;
1181
1182 self.mvi.resize(mb_w, mb_h);
1183 for mb_y in 0..mb_h {
1184 sstate.mb_y = mb_y;
1185 sstate.has_left = false;
1186 for mb_x in 0..mb_w {
1187 sstate.mb_x = mb_x;
1188 if mb_pos == slice.end {
1189 slice = decode_slice_header(&mut br, bd, slice_no, &slice_offs, self.width, self.height)?;
1190 validate!(slice.fits(&hdr0));
1191 q = slice.quant;
1192 slice_no += 1;
1193 imode.reset();
1194 sstate.q = q;
1195 sstate.has_top = false;
1196 sstate.has_left = false;
1197 sstate.set_idx = slice.set_idx;
1198 }
1199 sstate.has_top = (mb_pos - slice.start) >= mb_w;
1200 sstate.has_tl = sstate.has_top && (mb_x > 0) && (mb_pos > slice.start + mb_w);
1201 sstate.has_tr = (mb_x < mb_w - 1) && (mb_pos - slice.start >= mb_w - 1);
1202 imode.set_mb_x(mb_x);
1203 let mbh = if is_intra {
1204 let is_i16 = br.read_bool()?;
1205 self.decode_mb_header_intra(bd, &mut br, is_i16, &mut imode, q, sstate.has_top, false)?
1206 } else {
1207 if skip_run == 0 {
1208 let mbtype;
1209 if self.is_rv30 {
1210 mbtype = MBType::Invalid;
1211 } else {
1212 let mut hist = MBHist::new(hdr0.ftype);
1213 if sstate.has_top {
1214 hist.add(mbinfo[mb_pos - mb_w].mbtype);
1215 if sstate.has_tr { hist.add(mbinfo[mb_pos - mb_w + 1].mbtype); }
1216 }
1217 if sstate.has_left { hist.add(mbinfo[mb_pos - 1].mbtype); }
1218 if sstate.has_tl { hist.add(mbinfo[mb_pos - mb_w - 1].mbtype); }
1219 mbtype = hist.get_mbtype();
1220 }
1221 self.decode_mb_header_inter(bd, &mut br, hdr0.ftype, mbtype, &mut imode, q, sstate.has_top)?
1222 } else {
1223 skip_run -= 1;
1224 MBInfo { mbtype: MBType::MBSkip, skip_run: 0, dquant: false }
1225 }
1226 };
1227 if !mbh.mbtype.is_intra() {
1228 let mut mvs: [MV; 4] = [ZERO_MV; 4];
1229 for i in 0..mbh.mbtype.get_num_mvs() {
1230 mvs[i] = decode_mv(&mut br)?;
1231 }
1232 if !self.is_b {
1233 self.mvi.set_mb(mb_x, mb_y, mbh.mbtype, &self.ref_mvi, &mvs, &sstate);
1234 } else {
1235 let (mv_f, mv_b) = bd.predict_b_mv(&sstate, &self.mvi, mbh.mbtype, &mvs, mbinfo.as_slice());
1236 self.mvi.fill(mb_x, mb_y, true, mv_f);
1237 self.mvi.fill(mb_x, mb_y, false, mv_b);
1238 }
1239 }
1240 let cbp;
1241 let is_16 = (mbh.mbtype == MBType::MBIntra16) || (mbh.mbtype == MBType::MBP16x16Mix);
1242 if mbh.mbtype == MBType::MBSkip {
1243 cbp = 0;
1244 if mbh.skip_run > 0 {
1245 skip_run = mbh.skip_run;
1246 }
1247 } else {
1248 self.coderead.select_codes(mbh.mbtype.is_intra(), q, slice.set_idx, is_16);
1249 if mbh.mbtype == MBType::MBP16x16Mix {
1250 self.coderead.select_codes(true, q, slice.set_idx, true);
1251 }
1252 cbp = self.coderead.decode_cbp(&mut br)?;
1253 }
1254 sstate.cbp = cbp;
1255 if is_intra || mbh.mbtype.is_intra() {
1256 sstate.q_dc = bd.quant_dc(true, q);
1257 self.decode_mb_intra(&sstate, &imode, &mut buf, &mut br, is_16)?;
1258 } else {
1259 sstate.q_dc = bd.quant_dc(false, q);
1260 imode.fill_block(0);
1261 self.decode_mb_inter(&sstate, &mbh, &mut buf, &mut br, is_16)?;
1262 }
1263
1264 let mi = RV34MBInfo { cbp, q, mbtype: mbh.mbtype, deblock: 0, cbp_c: 0 };
1265 mbinfo.push(mi);
1266 if is_intra {
1267 mbinfo[mb_pos].deblock = 0xFFFF;
1268 mbinfo[mb_pos].cbp_c = 0xFF;
1269 } else {
1270 self.fill_deblock_flags(&sstate, mb_pos, &mut mbinfo);
1271 }
1272 sstate.has_left = true;
1273 mb_pos += 1;
1274 }
1275 if hdr0.deblock && (mb_y >= 1) {
1276 self.dsp.loop_filter(&mut buf, hdr0.ftype, &mbinfo, mb_w, mb_h, mb_y - 1);
1277 }
1278 imode.update();
1279 }
1280 if hdr0.deblock {
1281 self.dsp.loop_filter(&mut buf, hdr0.ftype, &mbinfo, mb_w, mb_h, mb_h - 1);
1282 }
1283 if !self.is_b {
1284 self.ipbs.add_frame(buf.clone());
1285 mem::swap(&mut self.mvi, &mut self.ref_mvi);
1286 mem::swap(&mut self.mbinfo, &mut mbinfo);
1287 }
1288
1289 Ok((NABufferType::Video(buf), hdr0.ftype, ts))
1290 }
1291 pub fn flush(&mut self) {
1292 self.ipbs.clear();
1293 }
1294 }