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