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