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