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