]> git.nihav.org Git - nihav.git/blame - nihav-realmedia/src/codecs/rv3040.rs
realmedia: fix or silence clippy warnings
[nihav.git] / nihav-realmedia / src / codecs / rv3040.rs
CommitLineData
5641dccf 1use nihav_core::formats::YUV420_FORMAT;
3fc28ece 2use nihav_core::frame::{NABufferType, NAVideoInfo, NAVideoBuffer, NAVideoBufferRef, FrameType, alloc_video_buffer};
b4d5b851
KS
3use nihav_core::codecs::{NADecoderSupport, DecoderError, DecoderResult};
4use nihav_codec_support::codecs::{MV, ZERO_MV, IPBShuffler};
5641dccf
KS
5use nihav_core::io::bitreader::{BitReader,BitReaderMode};
6use nihav_core::io::intcode::*;
b4d5b851 7use nihav_codec_support::data::GenericCache;
47527732
KS
8use std::mem;
9
10use super::rv34codes::*;
11use super::rv34dsp::*;
12
47527732
KS
13trait RV34MVScale {
14 fn scale(&self, trd: u16, trb: u16) -> (MV, MV);
15}
16
17const TR_SHIFT: u8 = 14;
18const TR_BIAS: i32 = 1 << (TR_SHIFT - 1);
19
20impl 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)]
33pub 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
45impl 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)]
56pub 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
72impl MBType {
e07387c7
KS
73 pub fn is_intra(self) -> bool {
74 (self == MBType::MBIntra) || (self == MBType::MBIntra16)
47527732 75 }
e07387c7
KS
76 pub fn is_16(self) -> bool {
77 (self == MBType::MBIntra16) || (self == MBType::MBP16x16Mix)
47527732 78 }
e07387c7 79 pub fn is_intra_or_16(self) -> bool {
47527732
KS
80 self.is_intra() || self.is_16()
81 }
e07387c7
KS
82 pub fn get_num_mvs(self) -> usize {
83 match self {
47527732
KS
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 }
e07387c7
KS
93 pub fn is_fwd(self) -> bool {
94 match self {
47527732
KS
95 MBType::MBP16x16 | MBType::MBP16x16Mix |
96 MBType::MBP16x8 | MBType::MBP8x16 | MBType::MBP8x8 |
97 MBType::MBForward => true,
98 _ => false,
99 }
100 }
e07387c7
KS
101 pub fn is_bwd(self) -> bool {
102 match self {
47527732
KS
103 MBType::MBBidir | MBType::MBBackward => true,
104 _ => false,
105 }
106 }
e07387c7
KS
107 pub fn has_mv_dir(self, fwd: bool) -> bool {
108 match self {
47527732
KS
109 MBType::MBBidir => true,
110 MBType::MBForward if fwd => true,
111 MBType::MBBackward if !fwd => true,
112 _ => false,
113 }
114 }
e07387c7
KS
115 pub fn is_nomv(self) -> bool {
116 match self {
47527732
KS
117 MBType::MBIntra | MBType::MBIntra16 | MBType::MBSkip | MBType::MBDirect => true,
118 _ => false,
119 }
120 }
e07387c7
KS
121 /*pub fn is_16x16(self) -> bool {
122 match self {
47527732
KS
123 MBType::MBP16x8 | MBType::MBP8x16 | MBType::MBP8x8 => false,
124 _ => true,
125 }
126 }*/
e07387c7
KS
127 fn get_weight(self) -> usize {
128 match self {
47527732
KS
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
146const 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)]
153pub struct MBInfo {
154 pub mbtype: MBType,
155 pub skip_run: usize,
156 pub dquant: bool,
157}
158
159#[derive(Clone,Copy)]
160pub 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
168struct IntraModeState {
169 cache: GenericCache<i8>,
170}
171
172const 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
179const RV34_INTRA_PRED16: [PredType8x8; 4] = [
180 PredType8x8::DC, PredType8x8::Ver, PredType8x8::Hor, PredType8x8::Plane
181];
182
183impl 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
47527732
KS
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
47527732
KS
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
309pub 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
318impl 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 }
47527732
KS
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 }
47527732
KS
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;
47527732
KS
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 => {
821c9dea 395 let pred_mv = self.pred_mv(idx, mbtype.is_fwd(), sstate.has_top, sstate.has_left, sstate.has_tr, sstate.has_tl, true);
47527732
KS
396 let new_mv = mvs[0] + pred_mv;
397 self.fill(mb_x, mb_y, true, new_mv);
398 },
399 MBType::MBP16x8 => {
821c9dea 400 let pred_mv = self.pred_mv(idx, mbtype.is_fwd(), sstate.has_top, sstate.has_left, sstate.has_tr, sstate.has_tl, true);
47527732
KS
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);
47527732
KS
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);
47527732
KS
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);
47527732
KS
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);
47527732
KS
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 => {
821c9dea 471 let pred_mv = self.pred_mv(idx, mbtype.is_fwd(), sstate.has_top, sstate.has_left, sstate.has_tr, sstate.has_tl, true);
47527732
KS
472 let new_mv = mvs[0] + pred_mv;
473 self.fill(mb_x, mb_y, true, new_mv);
474 },
475 MBType::MBBackward => {
821c9dea 476 let pred_mv = self.pred_mv(idx, mbtype.is_fwd(), sstate.has_top, sstate.has_left, sstate.has_tr, sstate.has_tl, true);
47527732
KS
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
497pub 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>;
e07387c7 502 fn predict_b_mv(&self, sstate: &SState, mvi: &MVInfo, mbtype: MBType, mvs: &[MV], mbinfo: &[RV34MBInfo]) -> (MV, MV);
47527732
KS
503}
504
505pub trait RV34DSP {
16cbd8c0 506 fn loop_filter(&self, frame: &mut NAVideoBuffer<u8>, ftype: FrameType, mbinfo: &[RV34MBInfo], mb_w: usize, mb_h: usize, row: usize);
47527732
KS
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
511fn 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
fa90ccfb 518 let mut br = BitReader::new(&src[1..ini_off], BitReaderMode::BE);
47527732
KS
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
e07387c7 535fn decode_slice_header(br: &mut BitReader, bd: &mut RV34BitstreamDecoder, slice_no: usize, slice_offs: &[usize], old_width: usize, old_height: usize) -> DecoderResult<RV34SliceHeader> {
47527732
KS
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)?;
6bdc6300
KS
539 if ((shdr.width == 0) || (shdr.height == 0)) && (shdr.ftype != FrameType::I) {
540 return Err(DecoderError::MissingReference);
541 }
47527732
KS
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)?;
404d527a
KS
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 }
47527732 561 br.seek(cur_pos)?;
47527732
KS
562 } else {
563 shdr.end = ((shdr.width + 15) >> 4) * ((shdr.height + 15) >> 4);
564 }
47527732
KS
565 Ok(shdr)
566}
567
568const RV34_MB_MAX_SIZES: [usize; 6] = [ 0x2F, 0x62, 0x18B, 0x62F, 0x18BF, 0x23FF ];
569const RV34_SLICE_START_BITS: [u8; 6] = [ 6, 7, 9, 11, 13, 14 ];
570
571pub fn get_slice_start_offset_bits(w: usize, h: usize) -> u8 {
6bdc6300
KS
572 if (w == 0) || (h == 0) {
573 return 0;
574 }
47527732
KS
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
581const 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
588const 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
595const 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];
599const 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
604fn 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
616pub 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
633impl 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
654struct MBHist {
655 is_p: bool,
656 hist: [MBType; 4],
657 count: usize,
658}
659
660impl 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
696fn 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;
e07387c7 699 Ok(MV{ x, y })
47527732
KS
700}
701
fa57381e 702fn do_mc_16x16(dsp: &mut dyn RV34DSP, buf: &mut NAVideoBuffer<u8>, prevbuf: &NAVideoBuffer<u8>, mb_x: usize, mb_y: usize, mv: MV, avg: bool) {
47527732
KS
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
fa57381e 708fn 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) {
47527732
KS
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
714fn 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;
1a967e6b 721 let data = buf.get_data_mut().unwrap();
47527732
KS
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
737pub struct RV34Decoder {
738 is_rv30: bool,
739 coderead: RV34Codes,
08a1fab7 740 dsp: Box<dyn RV34DSP + Send>,
47527732
KS
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>,
3fc28ece 753 avg_buf: NAVideoBufferRef<u8>,
47527732
KS
754 base_ts: u64,
755}
756
757impl RV34Decoder {
08a1fab7 758 pub fn new(is_rv30: bool, dsp: Box<dyn RV34DSP + Send>) -> Self {
47527732 759 let tmp_vinfo = NAVideoInfo::new(16, 16, false, YUV420_FORMAT);
b70cc006 760 let vt = alloc_video_buffer(tmp_vinfo, 4).unwrap();
47527732
KS
761 let vb = vt.get_vbuf();
762 let avg_buf = vb.unwrap();
763 RV34Decoder {
e07387c7 764 is_rv30,
47527732 765 coderead: RV34Codes::new(),
e07387c7 766 dsp,
47527732
KS
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,
e07387c7 776 avg_buf,
47527732
KS
777 base_ts: 0,
778 }
779 }
780 fn decode_mb_header_intra(&mut self, bd: &mut 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);
e07387c7 784 Ok(MBInfo { mbtype: MBType::MBIntra16, skip_run: 0, dquant: false })
47527732
KS
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)?;
e07387c7 793 Ok(MBInfo { mbtype: MBType::MBIntra, skip_run: 0, dquant: dq })
47527732
KS
794 }
795 }
796 fn decode_mb_header_inter(&mut self, bd: &mut 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 }
e07387c7 805 Ok(hdr)
47527732
KS
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;
1a967e6b 825 let data = buf.get_data_mut().unwrap();
47527732
KS
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);
47527732
KS
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 };
47527732
KS
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;
1a967e6b 876 let data = buf.get_data_mut().unwrap();
47527732
KS
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);
47527732
KS
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 };
47527732
KS
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);
fa57381e 927 do_mc_16x16(self.dsp.as_mut(), buf, prevbuf, mb_x, mb_y, mv, false);
47527732
KS
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);
fa57381e 933 do_mc_16x16(self.dsp.as_mut(), buf, fwdbuf, mb_x, mb_y, mv, false);
47527732
KS
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);
fa57381e 939 do_mc_16x16(self.dsp.as_mut(), buf, bwdbuf, mb_x, mb_y, mv, false);
47527732
KS
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);
fa57381e 947 do_mc_8x8(self.dsp.as_mut(), buf, prevbuf, mb_x, x, mb_y, y, mv, false);
47527732
KS
948 }
949 }
950 }
951 },
952 MBType::MBSkip if !self.is_b => {
953 if let Some(ref prevbuf) = self.ipbs.get_lastref() {
fa57381e 954 do_mc_16x16(self.dsp.as_mut(), buf, prevbuf, mb_x, mb_y, ZERO_MV, false);
47527732
KS
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 {
1a151e53 960 for x in 0..2 {
47527732 961 let (mv_f, mv_b) = self.ref_mvi.get_mv(mb_x, mb_y, x, y, true).scale(sstate.trd, sstate.trb);
fa57381e
KS
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);
47527732
KS
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);
fa57381e
KS
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);
47527732
KS
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;
1a967e6b 1001 let data = buf.get_data_mut().unwrap();
47527732
KS
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;
1a967e6b 1036 let data = buf.get_data_mut().unwrap();
47527732
KS
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
fa57381e 1098 #[allow(clippy::cyclomatic_complexity)]
3c69ce1b 1099 pub fn parse_frame(&mut self, supp: &mut NADecoderSupport, src: &[u8], bd: &mut RV34BitstreamDecoder) -> DecoderResult<(NABufferType, FrameType, u64)> {
47527732
KS
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
fa90ccfb 1104 let mut br = BitReader::new(&src[ini_off..], BitReaderMode::BE);
e07387c7 1105 let hdr0 = decode_slice_header(&mut br, bd, 0, slice_offs.as_slice(), self.width, self.height)?;
47527732
KS
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 }
6e24ec0b
KS
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 };
47527732
KS
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
47527732 1159 let vinfo = NAVideoInfo::new(hdr0.width, hdr0.height, false, YUV420_FORMAT);
3c69ce1b
KS
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 }
47527732
KS
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)?;
47527732
KS
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 {
e07387c7 1235 let (mv_f, mv_b) = bd.predict_b_mv(&sstate, &self.mvi, mbh.mbtype, &mvs, mbinfo.as_slice());
47527732
KS
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;
47527732
KS
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)?;
47527732
KS
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 {
d6402b85 1259 sstate.q_dc = bd.quant_dc(false, q);
47527732
KS
1260 imode.fill_block(0);
1261 self.decode_mb_inter(&sstate, &mbh, &mut buf, &mut br, is_16)?;
1262 }
1263
e07387c7 1264 let mi = RV34MBInfo { cbp, q, mbtype: mbh.mbtype, deblock: 0, cbp_c: 0 };
47527732
KS
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) {
16cbd8c0 1276 self.dsp.loop_filter(&mut buf, hdr0.ftype, &mbinfo, mb_w, mb_h, mb_y - 1);
47527732
KS
1277 }
1278 imode.update();
1279 }
1280 if hdr0.deblock {
16cbd8c0 1281 self.dsp.loop_filter(&mut buf, hdr0.ftype, &mbinfo, mb_w, mb_h, mb_h - 1);
47527732 1282 }
47527732 1283 if !self.is_b {
3c69ce1b 1284 self.ipbs.add_frame(buf.clone());
47527732
KS
1285 mem::swap(&mut self.mvi, &mut self.ref_mvi);
1286 mem::swap(&mut self.mbinfo, &mut mbinfo);
1287 }
1288
3c69ce1b 1289 Ok((NABufferType::Video(buf), hdr0.ftype, ts))
47527732 1290 }
f9be4e75
KS
1291 pub fn flush(&mut self) {
1292 self.ipbs.clear();
1293 }
47527732 1294}