realmedia/rv3040: ignore slices with wrong headers
[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 if let Ok(nhdr) = bd.decode_slice_header(br, shdr.width, shdr.height) {
543 validate!(nhdr.start > shdr.start);
544 shdr.end = nhdr.start;
545 } else {
546 if slice_no + 2 < slice_offs.len() {
547 br.seek((slice_offs[slice_no + 2] * 8) as u32)?;
548 if let Ok(nhdr) = bd.decode_slice_header(br, shdr.width, shdr.height) {
549 validate!(nhdr.start > shdr.start);
550 shdr.end = nhdr.start;
551 } else {
552 shdr.end = ((shdr.width + 15) >> 4) * ((shdr.height + 15) >> 4);
553 }
554 } else {
555 shdr.end = ((shdr.width + 15) >> 4) * ((shdr.height + 15) >> 4);
556 }
557 }
558 br.seek(cur_pos)?;
559 } else {
560 shdr.end = ((shdr.width + 15) >> 4) * ((shdr.height + 15) >> 4);
561 }
562 Ok(shdr)
563 }
564
565 const RV34_MB_MAX_SIZES: [usize; 6] = [ 0x2F, 0x62, 0x18B, 0x62F, 0x18BF, 0x23FF ];
566 const RV34_SLICE_START_BITS: [u8; 6] = [ 6, 7, 9, 11, 13, 14 ];
567
568 pub fn get_slice_start_offset_bits(w: usize, h: usize) -> u8 {
569 let mb_size = ((w + 15) >> 4) * ((h + 15) >> 4) - 1;
570 let mut idx: usize = 0;
571 while (idx < 5) && (RV34_MB_MAX_SIZES[idx] < mb_size) { idx += 1; }
572 RV34_SLICE_START_BITS[idx]
573 }
574
575 const RV34_DQUANT_TAB: [[i8; 2]; 32] = [
576 [ 0, 0 ], [ 2, 1 ], [ -1, 1 ], [ -1, 1 ], [ -1, 1 ], [ -1, 1 ], [ -1, 1 ], [ -1, 1 ],
577 [ -1, 1 ], [ -1, 1 ], [ -1, 1 ], [ -2, 2 ], [ -2, 2 ], [ -2, 2 ], [ -2, 2 ], [ -2, 2 ],
578 [ -2, 2 ], [ -2, 2 ], [ -2, 2 ], [ -2, 2 ], [ -2, 2 ], [ -3, 3 ], [ -3, 3 ], [ -3, 3 ],
579 [ -3, 3 ], [ -3, 3 ], [ -3, 3 ], [ -3, 3 ], [ -3, 3 ], [ -3, 2 ], [ -3, 1 ], [ -3,-5 ]
580 ];
581
582 const RV34_QUANT_TAB: [u16; 32] = [
583 60, 67, 76, 85, 96, 108, 121, 136,
584 152, 171, 192, 216, 242, 272, 305, 341,
585 383, 432, 481, 544, 606, 683, 767, 854,
586 963, 1074, 1212, 1392, 1566, 1708, 1978, 2211
587 ];
588
589 const RV34_CHROMA_QUANT_DC: [u8; 32] = [
590 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
591 14, 15, 15, 16, 17, 18, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23
592 ];
593 const RV34_CHROMA_QUANT_AC: [u8; 32] = [
594 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
595 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25
596 ];
597
598 fn decode_dquant(br: &mut BitReader, q: u8) -> DecoderResult<u8> {
599 if br.read_bool()? {
600 let diff = RV34_DQUANT_TAB[q as usize][br.read(1)? as usize];
601 let qp = (q as i8) + diff;
602 validate!((qp > 0) && (qp < 32));
603 Ok(qp as u8)
604 } else {
605 let qp = br.read(5)? as u8;
606 Ok(qp)
607 }
608 }
609
610 pub struct SState {
611 pub mb_x: usize,
612 pub mb_y: usize,
613 pub mb_w: usize,
614 pub mb_h: usize,
615 pub cbp: u32,
616 pub q: u8,
617 pub q_dc: u8,
618 pub set_idx: usize,
619 pub has_left: bool,
620 pub has_top: bool,
621 pub has_tl: bool,
622 pub has_tr: bool,
623 pub trd: u16,
624 pub trb: u16,
625 }
626
627 impl SState {
628 fn new() -> Self {
629 Self {
630 mb_x: 0,
631 mb_y: 0,
632 mb_w: 0,
633 mb_h: 0,
634 cbp: 0,
635 q: 0,
636 q_dc: 0,
637 set_idx: 0,
638 has_left: false,
639 has_top: false,
640 has_tl: false,
641 has_tr: false,
642 trd: 0,
643 trb: 0,
644 }
645 }
646 }
647
648 struct MBHist {
649 is_p: bool,
650 hist: [MBType; 4],
651 count: usize,
652 }
653
654 impl MBHist {
655 fn new(ftype: FrameType) -> Self { Self { is_p: ftype == FrameType::P, hist: [MBType::Invalid; 4], count: 0 } }
656 fn add(&mut self, mbt: MBType) {
657 let mbt2 = match mbt {
658 MBType::MBSkip if self.is_p => MBType::MBP16x16,
659 MBType::MBSkip if !self.is_p => MBType::MBDirect,
660 _ => mbt,
661 };
662 self.hist[self.count] = mbt2;
663 self.count += 1;
664 }
665 fn get_mbtype(&self) -> MBType {
666 if self.count == 0 {
667 MBType::MBIntra
668 } else if self.count == 1 {
669 self.hist[0]
670 } else if self.count == 2 {
671 if self.hist[0].get_weight() <= self.hist[1].get_weight() {
672 self.hist[0]
673 } else {
674 self.hist[1]
675 }
676 } else {
677 let mut w: [usize; 12] = [0; 12];
678 for i in 0..self.count { w[self.hist[i].get_weight()] += 1; }
679 let mut nz_idx = 0;
680 for i in 0..12 {
681 if w[i] == self.count { return MBTYPE_FROM_WEIGHT[i]; }
682 if (w[i] > w[nz_idx]) || (w[nz_idx] == 0) { nz_idx = i; }
683 }
684
685 MBTYPE_FROM_WEIGHT[nz_idx]
686 }
687 }
688 }
689
690 fn decode_mv(br: &mut BitReader) -> DecoderResult<MV> {
691 let x = br.read_code_signed(IntCodeType::Gamma)? as i16;
692 let y = br.read_code_signed(IntCodeType::Gamma)? as i16;
693 Ok(MV{ x, y })
694 }
695
696 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) {
697 dsp.do_luma_mc (buf, prevbuf, mb_x * 16, mb_y * 16, mv, true, avg);
698 dsp.do_chroma_mc(buf, prevbuf, mb_x * 8, mb_y * 8, 1, mv, true, avg);
699 dsp.do_chroma_mc(buf, prevbuf, mb_x * 8, mb_y * 8, 2, mv, true, avg);
700 }
701
702 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) {
703 dsp.do_luma_mc (buf, prevbuf, mb_x * 16 + xoff * 8, mb_y * 16 + yoff * 8, mv, false, avg);
704 dsp.do_chroma_mc(buf, prevbuf, mb_x * 8 + xoff * 4, mb_y * 8 + yoff * 4, 1, mv, false, avg);
705 dsp.do_chroma_mc(buf, prevbuf, mb_x * 8 + xoff * 4, mb_y * 8 + yoff * 4, 2, mv, false, avg);
706 }
707
708 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) {
709 for comp in 0..3 {
710 let xoff = if comp == 0 { mb_x * 16 + xb * 8 } else { mb_x * 8 + xb * 4 };
711 let yoff = if comp == 0 { mb_y * 16 + yb * 8 } else { mb_y * 8 + yb * 4 };
712 let csize = if comp == 0 { size } else { size >> 1 };
713 let dstride = buf.get_stride(comp);
714 let doffset = buf.get_offset(comp) + xoff + yoff * dstride;
715 let data = buf.get_data_mut().unwrap();
716 let dst: &mut [u8] = data.as_mut_slice();
717
718 let sstride = avg_buf.get_stride(comp);
719 let soffset = avg_buf.get_offset(comp);
720 let data = avg_buf.get_data();
721 let src: &[u8] = data.as_slice();
722
723 if ratio1 == ratio2 {
724 cdsp.avg(dst, doffset, dstride, src, soffset, sstride, csize);
725 } else {
726 cdsp.weight(dst, doffset, dstride, src, soffset, sstride, ratio2, ratio1, csize);
727 }
728 }
729 }
730
731 pub struct RV34Decoder {
732 is_rv30: bool,
733 coderead: RV34Codes,
734 dsp: Box<dyn RV34DSP + Send>,
735 cdsp: RV34CommonDSP,
736 width: usize,
737 height: usize,
738 ipbs: IPBShuffler,
739 mvi: MVInfo,
740 ref_mvi: MVInfo,
741 last_ts: u16,
742 next_ts: u16,
743 ratio1: u32,
744 ratio2: u32,
745 is_b: bool,
746 mbinfo: Vec<RV34MBInfo>,
747 avg_buf: NAVideoBufferRef<u8>,
748 base_ts: u64,
749 }
750
751 impl RV34Decoder {
752 pub fn new(is_rv30: bool, dsp: Box<dyn RV34DSP + Send>) -> Self {
753 let tmp_vinfo = NAVideoInfo::new(16, 16, false, YUV420_FORMAT);
754 let vt = alloc_video_buffer(tmp_vinfo, 4).unwrap();
755 let vb = vt.get_vbuf();
756 let avg_buf = vb.unwrap();
757 RV34Decoder {
758 is_rv30,
759 coderead: RV34Codes::new(),
760 dsp,
761 cdsp: RV34CommonDSP::new(),
762 ipbs: IPBShuffler::new(),
763 mvi: MVInfo::new(),
764 ref_mvi: MVInfo::new(),
765 mbinfo: Vec::new(),
766 width: 0, height: 0,
767 last_ts: 0, next_ts: 0,
768 ratio1: 0, ratio2: 0,
769 is_b: false,
770 avg_buf,
771 base_ts: 0,
772 }
773 }
774 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> {
775 if is_i16 {
776 let imode = br.read(2)? as i8;
777 im.fill_block(imode);
778 Ok(MBInfo { mbtype: MBType::MBIntra16, skip_run: 0, dquant: false })
779 } else {
780 let dq = if !has_dq {
781 if !self.is_rv30 { !br.read_bool()? } else { false }
782 } else { false };
783 if dq {
784 decode_dquant(br, q)?;
785 }
786 bd.decode_intra_pred(br, im.cache.data.as_mut_slice(), im.cache.xpos, im.cache.stride, has_top)?;
787 Ok(MBInfo { mbtype: MBType::MBIntra, skip_run: 0, dquant: dq })
788 }
789 }
790 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> {
791 let hdr = bd.decode_inter_mb_hdr(br, ftype, mbtype)?;
792 validate!(hdr.mbtype != MBType::Invalid);
793 if hdr.dquant {
794 decode_dquant(br, q)?;
795 }
796 if hdr.mbtype.is_intra() {
797 return self.decode_mb_header_intra(bd, br, hdr.mbtype.is_16(), im, q, has_top, true);
798 }
799 Ok(hdr)
800 }
801
802 fn decode_mb_intra(&mut self, sstate: &SState, imode: &IntraModeState, buf: &mut NAVideoBuffer<u8>, br: &mut BitReader, is_16: bool) -> DecoderResult<()> {
803 let mut cur_cbp = sstate.cbp;
804 {
805 let q_dc = RV34_QUANT_TAB[sstate.q_dc as usize];
806 let q_ac = RV34_QUANT_TAB[sstate.q as usize];
807 let luma_set = if is_16 { 2 } else { 1 };
808 let mut coeffs16: [i16; 16] = [0; 16];
809 if is_16 {
810 let has_ac = self.coderead.decode_block(br, &mut coeffs16, 3, 0, q_dc, q_dc, q_ac)?;
811 if has_ac {
812 self.cdsp.transform16(&mut coeffs16);
813 } else {
814 self.cdsp.transform16_dc(&mut coeffs16);
815 }
816 }
817 let stride = buf.get_stride(0);
818 let mut offset = buf.get_offset(0) + sstate.mb_x * 16 + sstate.mb_y * 16 * stride;
819 let data = buf.get_data_mut().unwrap();
820 let framebuf: &mut [u8] = data.as_mut_slice();
821
822 if is_16 {
823 let im16 = imode.get_pred16_type(sstate.has_top, sstate.has_left);
824 self.cdsp.ipred16x16[im16 as usize](framebuf, offset, stride);
825 }
826
827 for y in 0..4 {
828 for x in 0..4 {
829 let mut coeffs: [i16; 16] = [0; 16];
830 let has_ac;
831 if (cur_cbp & 1) != 0 {
832 has_ac = self.coderead.decode_block(br, &mut coeffs, luma_set, 0, q_ac, q_ac, q_ac)?;
833 } else {
834 has_ac = false;
835 }
836 if is_16 {
837 coeffs[0] = coeffs16[x + y * 4];
838 } else {
839 let noright = (sstate.mb_x == sstate.mb_w - 1) && (x == 3);
840 let has_top = sstate.has_top || (y > 0);
841 let im = imode.get_pred4_type(x, y, sstate.has_top, sstate.has_left);
842 let topright: [u8; 4] = if (noright && sstate.has_top && y == 0) || (x == 3 && y > 0) {
843 let i = offset + x * 4 - stride;
844 [framebuf[i + 3], framebuf[i + 3], framebuf[i + 3], framebuf[i + 3]]
845 } else if has_top {
846 let i = offset + x * 4 - stride;
847 [framebuf[i + 4], framebuf[i + 5], framebuf[i + 6], framebuf[i + 7]]
848 } else {
849 [0; 4]
850 };
851 self.cdsp.ipred4x4[im as usize](framebuf, offset + x*4, stride, &topright);
852 }
853 if has_ac {
854 self.cdsp.transform(&mut coeffs);
855 } else {
856 self.cdsp.transform_dc(&mut coeffs);
857 }
858 self.cdsp.add_coeffs(framebuf, offset + x * 4, stride, &coeffs);
859 cur_cbp >>= 1;
860 }
861 offset += stride * 4;
862 }
863 }
864 let q_dc = RV34_QUANT_TAB[RV34_CHROMA_QUANT_DC[sstate.q as usize] as usize];
865 let q_ac = RV34_QUANT_TAB[RV34_CHROMA_QUANT_AC[sstate.q as usize] as usize];
866 let chroma_set = 0;
867 for comp in 1..3 {
868 let stride = buf.get_stride(comp);
869 let mut offset = buf.get_offset(comp) + sstate.mb_x * 8 + sstate.mb_y * 8 * stride;
870 let data = buf.get_data_mut().unwrap();
871 let framebuf: &mut [u8] = data.as_mut_slice();
872 if is_16 {
873 let im8 = imode.get_pred8_type(sstate.has_top, sstate.has_left);
874 self.cdsp.ipred8x8[im8 as usize](framebuf, offset, stride);
875 }
876 for y in 0..2 {
877 for x in 0..2 {
878 let mut coeffs: [i16; 16] = [0; 16];
879 let has_ac;
880 if (cur_cbp & 1) != 0 {
881 has_ac = self.coderead.decode_block(br, &mut coeffs, chroma_set, 1, q_dc, q_ac, q_ac)?;
882 } else {
883 has_ac = false;
884 }
885 if !is_16 {
886 let noright = (sstate.mb_x == sstate.mb_w - 1) && (x == 1);
887 let has_top = sstate.has_top || (y > 0);
888 let im = imode.get_pred4_type_chroma(x, y, sstate.has_top, sstate.has_left);
889 let topright: [u8; 4] = if (noright && sstate.has_top && y == 0) || (x == 1 && y > 0) {
890 let i = offset + x * 4 - stride;
891 [framebuf[i + 3], framebuf[i + 3], framebuf[i + 3], framebuf[i + 3]]
892 } else if has_top {
893 let i = offset + x * 4 - stride;
894 [framebuf[i + 4], framebuf[i + 5], framebuf[i + 6], framebuf[i + 7]]
895 } else {
896 [0; 4]
897 };
898 self.cdsp.ipred4x4[im as usize](framebuf, offset + x*4, stride, &topright);
899 }
900 if has_ac {
901 self.cdsp.transform(&mut coeffs);
902 } else {
903 self.cdsp.transform_dc(&mut coeffs);
904 }
905 self.cdsp.add_coeffs(framebuf, offset + x * 4, stride, &coeffs);
906 cur_cbp >>= 1;
907 }
908 offset += stride * 4;
909 }
910 }
911 Ok(())
912 }
913
914 fn do_mc(&mut self, buf: &mut NAVideoBuffer<u8>, mbh: &MBInfo, sstate: &SState) {
915 let mb_x = sstate.mb_x;
916 let mb_y = sstate.mb_y;
917 match mbh.mbtype {
918 MBType::MBP16x16 | MBType::MBP16x16Mix => {
919 if let Some(ref prevbuf) = self.ipbs.get_lastref() {
920 let mv = self.mvi.get_mv(mb_x, mb_y, 0, 0, true);
921 do_mc_16x16(&self.dsp, buf, prevbuf, mb_x, mb_y, mv, false);
922 }
923 },
924 MBType::MBForward => {
925 if let Some(ref fwdbuf) = self.ipbs.get_b_fwdref() {
926 let mv = self.mvi.get_mv(mb_x, mb_y, 0, 0, true);
927 do_mc_16x16(&self.dsp, buf, fwdbuf, mb_x, mb_y, mv, false);
928 }
929 },
930 MBType::MBBackward => {
931 if let Some(ref bwdbuf) = self.ipbs.get_b_bwdref() {
932 let mv = self.mvi.get_mv(mb_x, mb_y, 0, 0, false);
933 do_mc_16x16(&self.dsp, buf, bwdbuf, mb_x, mb_y, mv, false);
934 }
935 },
936 MBType::MBP8x8 | MBType::MBP8x16 | MBType::MBP16x8 => {
937 if let Some(ref prevbuf) = self.ipbs.get_lastref() {
938 for y in 0..2 {
939 for x in 0..2 {
940 let mv = self.mvi.get_mv(mb_x, mb_y, x, y, true);
941 do_mc_8x8(&self.dsp, buf, prevbuf, mb_x, x, mb_y, y, mv, false);
942 }
943 }
944 }
945 },
946 MBType::MBSkip if !self.is_b => {
947 if let Some(ref prevbuf) = self.ipbs.get_lastref() {
948 do_mc_16x16(&self.dsp, buf, prevbuf, mb_x, mb_y, ZERO_MV, false);
949 }
950 },
951 MBType::MBSkip | MBType::MBDirect => {
952 if let (Some(ref fwdbuf), Some(ref bwdbuf)) = (self.ipbs.get_b_fwdref(), self.ipbs.get_b_bwdref()) {
953 for y in 0..2 {
954 for x in 0..2 {
955 let (mv_f, mv_b) = self.ref_mvi.get_mv(mb_x, mb_y, x, y, true).scale(sstate.trd, sstate.trb);
956 do_mc_8x8(&self.dsp, buf, fwdbuf, mb_x, x, mb_y, y, mv_f, false);
957 do_mc_8x8(&self.dsp, &mut self.avg_buf, bwdbuf, mb_x, x, mb_y, y, mv_b, true);
958 do_avg(&self.cdsp, buf, &self.avg_buf, mb_x, x, mb_y, y, 8, self.ratio1, self.ratio2);
959 }
960 }
961 }
962 },
963 MBType::MBBidir => {
964 if let (Some(ref fwdbuf), Some(ref bwdbuf)) = (self.ipbs.get_b_fwdref(), self.ipbs.get_b_bwdref()) {
965 let mv_f = self.mvi.get_mv(mb_x, mb_y, 0, 0, true);
966 let mv_b = self.mvi.get_mv(mb_x, mb_y, 0, 0, false);
967 do_mc_16x16(&self.dsp, buf, fwdbuf, mb_x, mb_y, mv_f, false);
968 do_mc_16x16(&self.dsp, &mut self.avg_buf, bwdbuf, mb_x, mb_y, mv_b, true);
969 do_avg(&self.cdsp, buf, &self.avg_buf, mb_x, 0, mb_y, 0, 16, self.ratio1, self.ratio2);
970 }
971 },
972 _ => {},
973 };
974 }
975 fn decode_mb_inter(&mut self, sstate: &SState, mbh: &MBInfo, buf: &mut NAVideoBuffer<u8>, br: &mut BitReader, is_16: bool) -> DecoderResult<()> {
976 self.do_mc(buf, mbh, sstate);
977
978 let mut cur_cbp = sstate.cbp;
979
980 {
981 let q_dc = RV34_QUANT_TAB[sstate.q_dc as usize];
982 let q_ac = RV34_QUANT_TAB[sstate.q as usize];
983 let luma_set = if is_16 { 2 } else { 0 };
984 let mut coeffs16: [i16; 16] = [0; 16];
985 if is_16 {
986 let has_ac = self.coderead.decode_block(br, &mut coeffs16, 3, 0, q_dc, q_dc, q_ac)?;
987 if has_ac {
988 self.cdsp.transform16(&mut coeffs16);
989 } else {
990 self.cdsp.transform16_dc(&mut coeffs16);
991 }
992 }
993 let stride = buf.get_stride(0);
994 let mut offset = buf.get_offset(0) + sstate.mb_x * 16 + sstate.mb_y * 16 * stride;
995 let data = buf.get_data_mut().unwrap();
996 let framebuf: &mut [u8] = data.as_mut_slice();
997
998 for y in 0..4 {
999 for x in 0..4 {
1000 let mut coeffs: [i16; 16] = [0; 16];
1001 let has_ac;
1002 if (cur_cbp & 1) != 0 {
1003 has_ac = self.coderead.decode_block(br, &mut coeffs, luma_set, 0, q_ac, q_ac, q_ac)?;
1004 } else {
1005 has_ac = false;
1006 }
1007 if is_16 {
1008 coeffs[0] = coeffs16[x + y * 4];
1009 }
1010 if has_ac {
1011 self.cdsp.transform(&mut coeffs);
1012 } else {
1013 self.cdsp.transform_dc(&mut coeffs);
1014 }
1015 self.cdsp.add_coeffs(framebuf, offset + x * 4, stride, &coeffs);
1016 cur_cbp >>= 1;
1017 }
1018 offset += stride * 4;
1019 }
1020 }
1021 if is_16 {
1022 self.coderead.select_codes(false, sstate.q, sstate.set_idx, false);
1023 }
1024 let q_dc = RV34_QUANT_TAB[RV34_CHROMA_QUANT_DC[sstate.q as usize] as usize];
1025 let q_ac = RV34_QUANT_TAB[RV34_CHROMA_QUANT_AC[sstate.q as usize] as usize];
1026 let chroma_set = 1;
1027 for comp in 1..3 {
1028 let stride = buf.get_stride(comp);
1029 let mut offset = buf.get_offset(comp) + sstate.mb_x * 8 + sstate.mb_y * 8 * stride;
1030 let data = buf.get_data_mut().unwrap();
1031 let framebuf: &mut [u8] = data.as_mut_slice();
1032 for _ in 0..2 {
1033 for x in 0..2 {
1034 let mut coeffs: [i16; 16] = [0; 16];
1035 let has_ac;
1036 if (cur_cbp & 1) != 0 {
1037 has_ac = self.coderead.decode_block(br, &mut coeffs, chroma_set, 1, q_dc, q_ac, q_ac)?;
1038 } else {
1039 has_ac = false;
1040 }
1041 if has_ac {
1042 self.cdsp.transform(&mut coeffs);
1043 } else {
1044 self.cdsp.transform_dc(&mut coeffs);
1045 }
1046 self.cdsp.add_coeffs(framebuf, offset + x * 4, stride, &coeffs);
1047 cur_cbp >>= 1;
1048 }
1049 offset += stride * 4;
1050 }
1051 }
1052 Ok(())
1053 }
1054 fn fill_deblock_flags(&self, sstate: &SState, mb_pos: usize, mbinfo: &mut Vec<RV34MBInfo>) {
1055 let mbt = mbinfo[mb_pos].mbtype;
1056 let mut hmvmask = 0;
1057 let mut vmvmask = 0;
1058
1059 for y in 0..2 {
1060 for x in 0..2 {
1061 let shift = x * 2 + y * 8;
1062 if ((x > 0) || (sstate.mb_x > 0)) && self.mvi.mv_gt_3(sstate.mb_x, sstate.mb_y, x, y, false) {
1063 vmvmask |= 0x11 << shift;
1064 }
1065 if ((y > 0) || sstate.has_top) && self.mvi.mv_gt_3(sstate.mb_x, sstate.mb_y, x, y, true) {
1066 hmvmask |= 0x03 << shift;
1067 }
1068 }
1069 }
1070 if !sstate.has_top { hmvmask &= !0x000F; }
1071 if sstate.mb_x == 0 { vmvmask &= !0x1111; }
1072 if self.is_rv30 {
1073 vmvmask |= (vmvmask & 0x4444) >> 1;
1074 hmvmask |= (hmvmask & 0x0F00) >> 4;
1075 if sstate.mb_x > 0 {
1076 mbinfo[mb_pos - 1].deblock |= (vmvmask & 0x1111) << 3;
1077 }
1078 if sstate.has_top {
1079
1080 mbinfo[mb_pos - sstate.mb_w].deblock |= (hmvmask & 0xF) << 12;
1081 }
1082 }
1083 if mbt.is_intra_or_16() {
1084 mbinfo[mb_pos].deblock = 0xFFFF;
1085 mbinfo[mb_pos].cbp_c = 0xFF;
1086 } else {
1087 mbinfo[mb_pos].deblock = (mbinfo[mb_pos].cbp as u16) | hmvmask | vmvmask;
1088 mbinfo[mb_pos].cbp_c = (mbinfo[mb_pos].cbp >> 16) as u8;
1089 }
1090 }
1091
1092 pub fn parse_frame(&mut self, supp: &mut NADecoderSupport, src: &[u8], bd: &mut RV34BitstreamDecoder) -> DecoderResult<(NABufferType, FrameType, u64)> {
1093 let mut slice_offs: Vec<usize> = Vec::new();
1094 parse_slice_offsets(src, &mut slice_offs)?;
1095 let ini_off = slice_offs.len() * 8 + 1;
1096
1097 let mut br = BitReader::new(&src[ini_off..], BitReaderMode::BE);
1098 let hdr0 = decode_slice_header(&mut br, bd, 0, slice_offs.as_slice(), self.width, self.height)?;
1099 validate!((hdr0.width != 0) && (hdr0.height != 0));
1100 self.width = hdr0.width;
1101 self.height = hdr0.height;
1102 let mb_w = (hdr0.width + 15) >> 4;
1103 let mb_h = (hdr0.height + 15) >> 4;
1104 let mut mb_pos: usize = 0;
1105 let mut slice = hdr0;
1106 let mut slice_no: usize = 1;
1107 let is_intra = hdr0.ftype == FrameType::I;
1108 let mut skip_run: usize = 0;
1109 let mut imode = IntraModeState::new(mb_w);
1110 let mut q = hdr0.quant;
1111
1112 let mut sstate = SState::new();
1113 let mut mbinfo: Vec<RV34MBInfo> = Vec::with_capacity(mb_w * mb_h);
1114
1115 self.is_b = hdr0.ftype == FrameType::B;
1116 if hdr0.ftype != FrameType::B {
1117 self.last_ts = self.next_ts;
1118 self.next_ts = hdr0.pts;
1119 if self.last_ts > self.next_ts {
1120 self.base_ts += 1 << 13;
1121 }
1122 }
1123 match hdr0.ftype {
1124 FrameType::P => {
1125 if self.ipbs.get_lastref().is_none() {
1126 return Err(DecoderError::MissingReference);
1127 }
1128 },
1129 FrameType::B => {
1130 if self.ipbs.get_lastref().is_none() {
1131 return Err(DecoderError::MissingReference);
1132 }
1133 if self.ipbs.get_nextref().is_none() {
1134 return Err(DecoderError::MissingReference);
1135 }
1136 },
1137 _ => {},
1138 };
1139 let ts_diff = (self.next_ts << 3).wrapping_sub(hdr0.pts << 3) >> 3;
1140 let ts = self.base_ts + (self.next_ts as u64) - (ts_diff as u64);
1141 sstate.trd = (self.next_ts << 3).wrapping_sub(self.last_ts << 3) >> 3;
1142 sstate.trb = (hdr0.pts << 3).wrapping_sub(self.last_ts << 3) >> 3;
1143 if sstate.trb != 0 {
1144 self.ratio1 = ((sstate.trb as u32) << 14) / (sstate.trd as u32);
1145 self.ratio2 = (((sstate.trd as u32) - (sstate.trb as u32)) << 14) / (sstate.trd as u32);
1146 } else {
1147 self.ratio1 = 1 << 14 >> 1;
1148 self.ratio2 = 1 << 14 >> 1;
1149 }
1150 //todo validate against ref frame
1151
1152 let vinfo = NAVideoInfo::new(hdr0.width, hdr0.height, false, YUV420_FORMAT);
1153 let ret = supp.pool_u8.get_free();
1154 if ret.is_none() {
1155 return Err(DecoderError::AllocError);
1156 }
1157 let mut buf = ret.unwrap();
1158 if buf.get_info() != vinfo {
1159 self.ipbs.clear();
1160 supp.pool_u8.reset();
1161 supp.pool_u8.prealloc_video(vinfo, 4)?;
1162 let ret = supp.pool_u8.get_free();
1163 if ret.is_none() {
1164 return Err(DecoderError::AllocError);
1165 }
1166 buf = ret.unwrap();
1167 }
1168
1169 sstate.q = q;
1170 sstate.has_top = false;
1171 sstate.mb_w = mb_w;
1172 sstate.mb_h = mb_h;
1173 sstate.set_idx = hdr0.set_idx;
1174
1175 self.mvi.resize(mb_w, mb_h);
1176 for mb_y in 0..mb_h {
1177 sstate.mb_y = mb_y;
1178 sstate.has_left = false;
1179 for mb_x in 0..mb_w {
1180 sstate.mb_x = mb_x;
1181 if mb_pos == slice.end {
1182 slice = decode_slice_header(&mut br, bd, slice_no, &slice_offs, self.width, self.height)?;
1183 validate!(slice.fits(&hdr0));
1184 q = slice.quant;
1185 slice_no += 1;
1186 imode.reset();
1187 sstate.q = q;
1188 sstate.has_top = false;
1189 sstate.has_left = false;
1190 sstate.set_idx = slice.set_idx;
1191 }
1192 sstate.has_top = (mb_pos - slice.start) >= mb_w;
1193 sstate.has_tl = sstate.has_top && (mb_x > 0) && (mb_pos > slice.start + mb_w);
1194 sstate.has_tr = (mb_x < mb_w - 1) && (mb_pos - slice.start >= mb_w - 1);
1195 imode.set_mb_x(mb_x);
1196 let mbh = if is_intra {
1197 let is_i16 = br.read_bool()?;
1198 self.decode_mb_header_intra(bd, &mut br, is_i16, &mut imode, q, sstate.has_top, false)?
1199 } else {
1200 if skip_run == 0 {
1201 let mbtype;
1202 if self.is_rv30 {
1203 mbtype = MBType::Invalid;
1204 } else {
1205 let mut hist = MBHist::new(hdr0.ftype);
1206 if sstate.has_top {
1207 hist.add(mbinfo[mb_pos - mb_w].mbtype);
1208 if sstate.has_tr { hist.add(mbinfo[mb_pos - mb_w + 1].mbtype); }
1209 }
1210 if sstate.has_left { hist.add(mbinfo[mb_pos - 1].mbtype); }
1211 if sstate.has_tl { hist.add(mbinfo[mb_pos - mb_w - 1].mbtype); }
1212 mbtype = hist.get_mbtype();
1213 }
1214 self.decode_mb_header_inter(bd, &mut br, hdr0.ftype, mbtype, &mut imode, q, sstate.has_top)?
1215 } else {
1216 skip_run -= 1;
1217 MBInfo { mbtype: MBType::MBSkip, skip_run: 0, dquant: false }
1218 }
1219 };
1220 if !mbh.mbtype.is_intra() {
1221 let mut mvs: [MV; 4] = [ZERO_MV; 4];
1222 for i in 0..mbh.mbtype.get_num_mvs() {
1223 mvs[i] = decode_mv(&mut br)?;
1224 }
1225 if !self.is_b {
1226 self.mvi.set_mb(mb_x, mb_y, mbh.mbtype, &self.ref_mvi, &mvs, &sstate);
1227 } else {
1228 let (mv_f, mv_b) = bd.predict_b_mv(&sstate, &self.mvi, mbh.mbtype, &mvs, mbinfo.as_slice());
1229 self.mvi.fill(mb_x, mb_y, true, mv_f);
1230 self.mvi.fill(mb_x, mb_y, false, mv_b);
1231 }
1232 }
1233 let cbp;
1234 let is_16 = (mbh.mbtype == MBType::MBIntra16) || (mbh.mbtype == MBType::MBP16x16Mix);
1235 if mbh.mbtype == MBType::MBSkip {
1236 cbp = 0;
1237 if mbh.skip_run > 0 {
1238 skip_run = mbh.skip_run;
1239 }
1240 } else {
1241 self.coderead.select_codes(mbh.mbtype.is_intra(), q, slice.set_idx, is_16);
1242 if mbh.mbtype == MBType::MBP16x16Mix {
1243 self.coderead.select_codes(true, q, slice.set_idx, true);
1244 }
1245 cbp = self.coderead.decode_cbp(&mut br)?;
1246 }
1247 sstate.cbp = cbp;
1248 if is_intra || mbh.mbtype.is_intra() {
1249 sstate.q_dc = bd.quant_dc(true, q);
1250 self.decode_mb_intra(&sstate, &imode, &mut buf, &mut br, is_16)?;
1251 } else {
1252 imode.fill_block(0);
1253 self.decode_mb_inter(&sstate, &mbh, &mut buf, &mut br, is_16)?;
1254 }
1255
1256 let mi = RV34MBInfo { cbp, q, mbtype: mbh.mbtype, deblock: 0, cbp_c: 0 };
1257 mbinfo.push(mi);
1258 if is_intra {
1259 mbinfo[mb_pos].deblock = 0xFFFF;
1260 mbinfo[mb_pos].cbp_c = 0xFF;
1261 } else {
1262 self.fill_deblock_flags(&sstate, mb_pos, &mut mbinfo);
1263 }
1264 sstate.has_left = true;
1265 mb_pos += 1;
1266 }
1267 if hdr0.deblock && (mb_y >= 1) {
1268 self.dsp.loop_filter(&mut buf, hdr0.ftype, &mbinfo, mb_w, mb_y - 1);
1269 }
1270 imode.update();
1271 }
1272 if hdr0.deblock {
1273 self.dsp.loop_filter(&mut buf, hdr0.ftype, &mbinfo, mb_w, mb_h - 1);
1274 }
1275 if !self.is_b {
1276 self.ipbs.add_frame(buf.clone());
1277 mem::swap(&mut self.mvi, &mut self.ref_mvi);
1278 mem::swap(&mut self.mbinfo, &mut mbinfo);
1279 }
1280
1281 Ok((NABufferType::Video(buf), hdr0.ftype, ts))
1282 }
1283 pub fn flush(&mut self) {
1284 self.ipbs.clear();
1285 }
1286 }