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