1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3 use nihav_core::io::bitreader::*;
4 use nihav_core::io::codebook::*;
5 use nihav_core::io::intcode::*;
10 #[derive(Clone,Copy,Default,Debug,PartialEq)]
18 fn add(self, other: MV) -> MV { MV { x: self.x + other.x, y: self.y + other.y } }
21 impl AddAssign for MV {
22 fn add_assign(&mut self, other: MV) { self.x += other.x; self.y += other.y; }
27 fn sub(self, other: MV) -> MV { MV { x: self.x - other.x, y: self.y - other.y } }
30 impl SubAssign for MV {
31 fn sub_assign(&mut self, other: MV) { self.x -= other.x; self.y -= other.y; }
35 fn pred(t: MV, tl: MV, l: MV) -> MV {
36 let x0 = i16::from(t.x);
37 let x1 = i16::from(tl.x);
38 let x2 = i16::from(l.x);
39 let y0 = i16::from(t.y);
40 let y1 = i16::from(tl.y);
41 let y2 = i16::from(l.y);
42 let x = x0 + x1 + x2 - x0.min(x1).min(x2) - x0.max(x1).max(x2);
43 let y = y0 + y1 + y2 - y0.min(y1).min(y2) - y0.max(y1).max(y2);
44 MV{ x: x as i8, y: y as i8 }
49 fn read_gammap(&mut self) -> BitReaderResult<u32>;
50 fn read_gammap_s(&mut self) -> BitReaderResult<i32>;
51 fn read_unary(&mut self) -> BitReaderResult<u32>;
54 impl<'a> ReadCodes for BitReader<'a> {
55 fn read_gammap(&mut self) -> BitReaderResult<u32> {
56 Ok(self.read_code(UintCodeType::GammaP)? - 1)
58 fn read_gammap_s(&mut self) -> BitReaderResult<i32> {
59 let val = self.read_code(UintCodeType::GammaP)?;
63 Ok((1 - (val as i32)) >> 1)
66 fn read_unary(&mut self) -> BitReaderResult<u32> {
67 self.read_code(UintCodeType::UnaryZeroes)
71 const CUR_BUF: usize = 3;
72 const CHROMA_OFF: usize = 256 * 256;
75 ($bufs: expr, $src_id: expr, $dst_id: expr, $mx: expr, $my: expr, $xpos: expr, $ypos: expr, $w: expr, $h: expr, $ydelta: expr, $udelta: expr, $vdelta: expr, $width: expr, $height: expr) => {
76 if ($mx + ($xpos as isize) < 0) || ($mx + (($xpos + $w) as isize) > ($width as isize)) {
77 return Err(DecoderError::InvalidData);
79 if ($my + ($ypos as isize) < 0) || ($my + (($ypos + $h) as isize) > ($height as isize)) {
80 return Err(DecoderError::InvalidData);
83 let sx = (($xpos as isize) + $mx) as usize;
84 let sy = (($ypos as isize) + $my) as usize;
86 let mut soff = sx + sy * 256;
87 let mut doff = $xpos + $ypos * 256;
90 $bufs[$dst_id][doff + x] = (i32::from($bufs[$src_id][soff + x]) + $ydelta).max(0).min(255) as u8;
95 let mut soff = CHROMA_OFF + sx / 2 + (sy / 2) * 256;
96 let mut doff = CHROMA_OFF + $xpos / 2 + $ypos / 2 * 256;
99 $bufs[$dst_id][doff + x] = (i32::from($bufs[$src_id][soff + x]) + $udelta).max(0).min(255) as u8;
100 $bufs[$dst_id][doff + x + 128] = (i32::from($bufs[$src_id][soff + x + 128]) + $vdelta).max(0).min(255) as u8;
108 fn pred_dc(buf: &mut [u8], mut pos: usize, x: usize, y: usize, w: usize, h: usize) {
109 let dc = if x == 0 && y == 0 {
115 sum += u16::from(buf[pos - 1 + i * 256]);
117 ((sum + hh / 2) / hh) as u8
122 sum += u16::from(buf[pos - 256 + i]);
124 ((sum + ww / 2) / ww) as u8
129 sum += u16::from(buf[pos - 256 + i]);
131 let wdc = (sum + ww / 2) / ww;
136 sum += u16::from(buf[pos - 1 + i * 256]);
138 let hdc = (sum + hh / 2) / hh;
140 ((wdc + hdc + 1) >> 1) as u8
149 fn pred_dc4x4(buf: &mut [u8], mut pos: usize, x: usize, y: usize) {
150 if x == 0 && y == 0 {
163 sum += u16::from(buf[pos - 256 + i]);
170 sum += u16::from(buf[pos + i * 256 - 1]);
175 let dc = (sum >> shift) as u8;
184 fn pred_hor(buf: &mut [u8], mut pos: usize, w: usize, h: usize) {
187 buf[pos + x] = buf[pos - 1];
193 fn pred_ver(buf: &mut [u8], mut pos: usize, w: usize, h: usize) {
196 buf[pos + x] = buf[pos + x - 256];
202 fn avg(a: u8, b: u8) -> u8 {
203 ((u16::from(a) + u16::from(b) + 1) >> 1) as u8
205 fn avg_nr(a: u8, b: u8) -> u8 {
206 ((u16::from(a) + u16::from(b)) >> 1) as u8
208 fn interp2(a: u8, b: u8, c: u8) -> u8 {
209 ((u16::from(a) + 2 * u16::from(b) + u16::from(c) + 2) >> 2) as u8
212 fn pred_ddown_left(blk: &mut [u8], pos: usize) {
213 let (t0, t1, t2, t3) = (blk[pos - 256], blk[pos - 256 + 1], blk[pos - 256 + 2], blk[pos - 256 + 3]);
214 let (t4, t5, t6, t7) = (blk[pos - 256 + 4], blk[pos - 256 + 5], blk[pos - 256 + 6], blk[pos - 256 + 7]);
216 blk[pos + 0 + 0 * 256] = interp2(t0, t1, t2);
217 let pix = interp2(t1, t2, t3);
218 blk[pos + 1 + 0 * 256] = pix;
219 blk[pos + 0 + 1 * 256] = pix;
220 let pix = interp2(t2, t3, t4);
221 blk[pos + 2 + 0 * 256] = pix;
222 blk[pos + 1 + 1 * 256] = pix;
223 blk[pos + 0 + 2 * 256] = pix;
224 let pix = interp2(t3, t4, t5);
225 blk[pos + 3 + 0 * 256] = pix;
226 blk[pos + 2 + 1 * 256] = pix;
227 blk[pos + 1 + 2 * 256] = pix;
228 blk[pos + 0 + 3 * 256] = pix;
229 let pix = interp2(t4, t5, t6);
230 blk[pos + 3 + 1 * 256] = pix;
231 blk[pos + 2 + 2 * 256] = pix;
232 blk[pos + 1 + 3 * 256] = pix;
233 let pix = interp2(t5, t6, t7);
234 blk[pos + 3 + 2 * 256] = pix;
235 blk[pos + 2 + 3 * 256] = pix;
236 blk[pos + 3 + 3 * 256] = interp2(t6, t7, t7);
238 fn pred_ddown_right(blk: &mut [u8], pos: usize) {
239 let (l0, l1, l2, l3) = (blk[pos - 1], blk[pos + 256 - 1], blk[pos + 256 * 2 - 1], blk[pos + 256 * 3 - 1]);
240 let (tl, t0, t1, t2) = (blk[pos - 256 - 1], blk[pos - 256], blk[pos - 256 + 1], blk[pos - 256 + 2]);
241 let t3 = blk[pos - 256 + 3];
243 blk[pos + 0 + 3 * 256] = interp2(l1, l2, l3);
244 let pix = interp2(l0, l1, l2);
245 blk[pos + 0 + 2 * 256] = pix;
246 blk[pos + 1 + 3 * 256] = pix;
247 let pix = interp2(tl, l0, l1);
248 blk[pos + 0 + 1 * 256] = pix;
249 blk[pos + 1 + 2 * 256] = pix;
250 blk[pos + 2 + 3 * 256] = pix;
251 let pix = interp2(l0, tl, t0);
252 blk[pos + 0 + 0 * 256] = pix;
253 blk[pos + 1 + 1 * 256] = pix;
254 blk[pos + 2 + 2 * 256] = pix;
255 blk[pos + 3 + 3 * 256] = pix;
256 let pix = interp2(tl, t0, t1);
257 blk[pos + 1 + 0 * 256] = pix;
258 blk[pos + 2 + 1 * 256] = pix;
259 blk[pos + 3 + 2 * 256] = pix;
260 let pix = interp2(t0, t1, t2);
261 blk[pos + 2 + 0 * 256] = pix;
262 blk[pos + 3 + 1 * 256] = pix;
263 blk[pos + 3 + 0 * 256] = interp2(t1, t2, t3);
265 fn pred_ver_right(blk: &mut [u8], pos: usize) {
266 let (l0, l1, l2) = (blk[pos - 1], blk[pos + 256 - 1], blk[pos + 256 * 2 - 1]);
267 let (tl, t0, t1, t2, t3) = (blk[pos - 256 - 1], blk[pos - 256], blk[pos - 256 + 1], blk[pos - 256 + 2], blk[pos - 256 + 3]);
269 blk[pos + 0 + 3 * 256] = interp2(l0, l1, l2);
270 blk[pos + 0 + 2 * 256] = interp2(tl, l0, l1);
271 let pix = interp2(l0, tl, t0);
272 blk[pos + 0 + 1 * 256] = pix;
273 blk[pos + 1 + 3 * 256] = pix;
274 let pix = avg(tl, t0);
275 blk[pos + 0 + 0 * 256] = pix;
276 blk[pos + 1 + 2 * 256] = pix;
277 let pix = interp2(tl, t0, t1);
278 blk[pos + 1 + 1 * 256] = pix;
279 blk[pos + 2 + 3 * 256] = pix;
280 let pix = avg(t0, t1);
281 blk[pos + 1 + 0 * 256] = pix;
282 blk[pos + 2 + 2 * 256] = pix;
283 let pix = interp2(t0, t1, t2);
284 blk[pos + 2 + 1 * 256] = pix;
285 blk[pos + 3 + 3 * 256] = pix;
286 let pix = avg(t1, t2);
287 blk[pos + 2 + 0 * 256] = pix;
288 blk[pos + 3 + 2 * 256] = pix;
289 blk[pos + 3 + 1 * 256] = interp2(t1, t2, t3);
290 blk[pos + 3 + 0 * 256] = avg(t2, t3);
292 fn pred_hor_down(blk: &mut [u8], pos: usize) {
293 let (l0, l1, l2, l3) = (blk[pos - 1], blk[pos + 256 - 1], blk[pos + 256 * 2 - 1], blk[pos + 256 * 3 - 1]);
294 let (tl, t0, t1, t2) = (blk[pos - 256 - 1], blk[pos - 256], blk[pos - 256 + 1], blk[pos - 256 + 2]);
296 blk[pos + 0 + 3 * 256] = avg(l2, l3);
297 blk[pos + 1 + 3 * 256] = interp2(l1, l2, l3);
298 let pix = avg(l1, l2);
299 blk[pos + 0 + 2 * 256] = pix;
300 blk[pos + 2 + 3 * 256] = pix;
301 let pix = interp2(l0, l1, l2);
302 blk[pos + 1 + 2 * 256] = pix;
303 blk[pos + 3 + 3 * 256] = pix;
304 let pix = avg(l0, l1);
305 blk[pos + 0 + 1 * 256] = pix;
306 blk[pos + 2 + 2 * 256] = pix;
307 let pix = interp2(tl, t0, l1);
308 blk[pos + 1 + 1 * 256] = pix;
309 blk[pos + 3 + 2 * 256] = pix;
310 let pix = avg(tl, l0);
311 blk[pos + 0 + 0 * 256] = pix;
312 blk[pos + 2 + 1 * 256] = pix;
313 let pix = interp2(l0, tl, t0);
314 blk[pos + 1 + 0 * 256] = pix;
315 blk[pos + 3 + 1 * 256] = pix;
316 blk[pos + 2 + 0 * 256] = interp2(tl, t0, t1);
317 blk[pos + 3 + 0 * 256] = interp2(t0, t1, t2);
319 fn pred_ver_left(blk: &mut [u8], pos: usize) {
320 let (t0, t1, t2, t3) = (blk[pos - 256], blk[pos - 256 + 1], blk[pos - 256 + 2], blk[pos - 256 + 3]);
321 let (t4, t5, t6) = (blk[pos - 256 + 4], blk[pos - 256 + 5], blk[pos - 256 + 6]);
323 blk[pos + 3 + 3 * 256] = interp2(t4, t5, t6);
324 blk[pos + 3 + 2 * 256] = avg(t4, t5);
325 let pix = interp2(t3, t4, t5);
326 blk[pos + 3 + 1 * 256] = pix;
327 blk[pos + 2 + 3 * 256] = pix;
328 let pix = avg(t3, t4);
329 blk[pos + 3 + 0 * 256] = pix;
330 blk[pos + 2 + 2 * 256] = pix;
331 let pix = interp2(t2, t3, t4);
332 blk[pos + 2 + 1 * 256] = pix;
333 blk[pos + 1 + 3 * 256] = pix;
334 let pix = avg(t2, t3);
335 blk[pos + 2 + 0 * 256] = pix;
336 blk[pos + 1 + 2 * 256] = pix;
337 let pix = interp2(t1, t2, t3);
338 blk[pos + 1 + 1 * 256] = pix;
339 blk[pos + 0 + 3 * 256] = pix;
340 let pix = avg(t1, t2);
341 blk[pos + 1 + 0 * 256] = pix;
342 blk[pos + 0 + 2 * 256] = pix;
343 blk[pos + 0 + 1 * 256] = interp2(t0, t1, t2);
344 blk[pos + 0 + 0 * 256] = avg(t0, t1);
346 fn pred_hor_up(blk: &mut [u8], pos: usize) {
347 let (l0, l1, l2, l3) = (blk[pos - 1], blk[pos + 256 - 1], blk[pos + 256 * 2 - 1], blk[pos + 256 * 3 - 1]);
349 blk[pos + 0 + 0 * 256] = avg(l0, l1);
350 blk[pos + 1 + 0 * 256] = interp2(l0, l1, l2);
351 let pix = avg(l1, l2);
352 blk[pos + 2 + 0 * 256] = pix;
353 blk[pos + 0 + 1 * 256] = pix;
354 let pix = interp2(l1, l2, l3);
355 blk[pos + 3 + 0 * 256] = pix;
356 blk[pos + 1 + 1 * 256] = pix;
357 let pix = avg(l2, l3);
358 blk[pos + 2 + 1 * 256] = pix;
359 blk[pos + 0 + 2 * 256] = pix;
360 let pix = interp2(l2, l3, l3);
361 blk[pos + 3 + 1 * 256] = pix;
362 blk[pos + 1 + 2 * 256] = pix;
363 blk[pos + 0 + 3 * 256] = l3;
364 blk[pos + 2 + 2 * 256] = l3;
365 blk[pos + 3 + 2 * 256] = l3;
366 blk[pos + 1 + 3 * 256] = l3;
367 blk[pos + 2 + 3 * 256] = l3;
368 blk[pos + 3 + 3 * 256] = l3;
371 fn pred_plane(blk: &mut [u8], pos: usize, w: usize, h: usize) {
372 if w == 1 && h == 1 {
376 blk[pos + w / 2 - 1] = avg_nr(blk[pos - 1], blk[pos + w - 1]);
378 pred_plane(blk, pos, w / 2, 1);
379 pred_plane(blk, pos + w / 2, w / 2, 1);
384 blk[pos + (h / 2 - 1) * 256] = avg_nr(blk[pos - 256], blk[pos + (h - 1) * 256]);
386 pred_plane(blk, pos, 1, h / 2);
387 pred_plane(blk, pos + (h / 2) * 256, 1, h / 2);
392 let is_even_block = ((w.trailing_zeros() + h.trailing_zeros()) & 1) == 0; // i.e. w*h = 256/64/16/4
394 let hoff = (h - 1) * 256;
395 let h2off = (h / 2 - 1) * 256;
397 let w2off = w / 2 - 1;
398 let dr = blk[pos + woff + hoff];
399 let tr = blk[pos + woff - 256];
400 let dl = blk[pos - 1 + hoff];
402 let dm = avg_nr(dl, dr);
403 blk[pos + w2off + hoff] = dm;
404 blk[pos + woff + h2off] = avg_nr(tr, dr);
405 let val2 = if is_even_block { blk[pos + w2off - 256] } else { blk[pos - 1 + h2off] };
406 blk[pos + w2off + h2off] = avg_nr(dm, val2);
410 pred_plane(blk, pos, hw, hh);
411 pred_plane(blk, pos + hw, hw, hh);
412 pred_plane(blk, pos + hh * 256, hw, hh);
413 pred_plane(blk, pos + hw + hh * 256, hw, hh);
415 fn pred_plane_delta(blk: &mut [u8], pos: usize, w: usize, h: usize, delta: i32) {
416 let tr = blk[pos + w - 1 - 256];
417 let dl = blk[pos + 256 * (h - 1) - 1];
418 //XXX: this is a hack since it should not wrap around normally but this conceals some artefacts so let it be until the reconstruction is properly fixed
419 let pred = (((i32::from(tr) + i32::from(dl) + 1) >> 1) + delta).max(0).min(255) as u8;
420 //let pred = avg(tr, dl).wrapping_add(delta as u8);
421 blk[pos + 256 * (h - 1) + w - 1] = pred;
422 pred_plane(blk, pos, w, h);
426 nc_cb: [Codebook<u8>; 3],
427 num_zero_cb: [Codebook<u8>; 15],
428 zero_run_cb: [Codebook<u8>; 6],
431 fn map_idx(idx: usize) -> u8 { idx as u8 }
432 macro_rules! create_cb {
433 ($bits_tab: expr, $lens_tab: expr) => {{
434 let mut cbr = TableCodebookDescReader::new($bits_tab, $lens_tab, map_idx);
435 Codebook::new(&mut cbr, CodebookMode::MSB).unwrap()
441 let nc_cb0 = create_cb!(&NC_BITS[0], &NC_LENS[0]);
442 let nc_cb1 = create_cb!(&NC_BITS[1], &NC_LENS[1]);
443 let nc_cb2 = create_cb!(&NC_BITS[2], &NC_LENS[2]);
445 let nz0 = create_cb!(&NUM_ZERO_BITS[ 0], &NUM_ZERO_LENS[ 0]);
446 let nz1 = create_cb!(&NUM_ZERO_BITS[ 1], &NUM_ZERO_LENS[ 1]);
447 let nz2 = create_cb!(&NUM_ZERO_BITS[ 2], &NUM_ZERO_LENS[ 2]);
448 let nz3 = create_cb!(&NUM_ZERO_BITS[ 3], &NUM_ZERO_LENS[ 3]);
449 let nz4 = create_cb!(&NUM_ZERO_BITS[ 4], &NUM_ZERO_LENS[ 4]);
450 let nz5 = create_cb!(&NUM_ZERO_BITS[ 5], &NUM_ZERO_LENS[ 5]);
451 let nz6 = create_cb!(&NUM_ZERO_BITS[ 6], &NUM_ZERO_LENS[ 6]);
452 let nz7 = create_cb!(&NUM_ZERO_BITS[ 7], &NUM_ZERO_LENS[ 7]);
453 let nz8 = create_cb!(&NUM_ZERO_BITS[ 8], &NUM_ZERO_LENS[ 8]);
454 let nz9 = create_cb!(&NUM_ZERO_BITS[ 9], &NUM_ZERO_LENS[ 9]);
455 let nz10 = create_cb!(&NUM_ZERO_BITS[10], &NUM_ZERO_LENS[10]);
456 let nz11 = create_cb!(&NUM_ZERO_BITS[11], &NUM_ZERO_LENS[11]);
457 let nz12 = create_cb!(&NUM_ZERO_BITS[12], &NUM_ZERO_LENS[12]);
458 let nz13 = create_cb!(&NUM_ZERO_BITS[13], &NUM_ZERO_LENS[13]);
459 let nz14 = create_cb!(&NUM_ZERO_BITS[14], &NUM_ZERO_LENS[14]);
461 let zcb0 = create_cb!(&ZERO_RUN_BITS[0], &ZERO_RUN_LENS[0]);
462 let zcb1 = create_cb!(&ZERO_RUN_BITS[1], &ZERO_RUN_LENS[1]);
463 let zcb2 = create_cb!(&ZERO_RUN_BITS[2], &ZERO_RUN_LENS[2]);
464 let zcb3 = create_cb!(&ZERO_RUN_BITS[3], &ZERO_RUN_LENS[3]);
465 let zcb4 = create_cb!(&ZERO_RUN_BITS[4], &ZERO_RUN_LENS[4]);
466 let zcb5 = create_cb!(&ZERO_RUN_BITS[5], &ZERO_RUN_LENS[5]);
468 nc_cb: [nc_cb0, nc_cb1, nc_cb2],
469 num_zero_cb: [nz0, nz1, nz2, nz3, nz4, nz5, nz6, nz7, nz8, nz9, nz10, nz11, nz12, nz13, nz14],
470 zero_run_cb: [zcb0, zcb1, zcb2, zcb3, zcb4, zcb5],
475 macro_rules! transform {
476 ($a: expr, $b: expr, $c: expr, $d: expr, $q0: expr, $q1: expr) => {
477 let t0 = ($a + $c).wrapping_mul($q0);
478 let t1 = ($a - $c).wrapping_mul($q0);
479 let tb = $b.wrapping_mul($q1);
480 let td = $d.wrapping_mul($q1);
481 let t2 = tb + (td >> 1);
482 let t3 = (tb >> 1) - td;
490 fn idct_add(qmat: &[i32; 8], blk: &mut [i32; 16], dst: &mut [u8]) {
492 transform!(blk[i + 0 * 4], blk[i + 1 * 4], blk[i + 2 * 4], blk[i + 3 * 4], qmat[i], qmat[i + 4]);
494 for (dline, row) in dst.chunks_mut(256).zip(blk.chunks_mut(4)) {
495 transform!(row[0], row[1], row[2], row[3], 1, 1);
496 for (out, coef) in dline.iter_mut().zip(row.iter_mut()) {
497 *out = (i32::from(*out) + ((*coef + 0x20) >> 6)).max(0).min(255) as u8;
502 fn decode_coeffs(br: &mut BitReader, codebooks: &Codebooks, qmat: &[i32; 8], ctx: u8, dst: &mut [u8]) -> DecoderResult<u8> {
503 const ZIGZAG: [usize; 16] = [
509 const MAX_LEVEL: [i32; 6] = [ 2, 5, 11, 23, 47, 0x8000 ];
511 let (ncoeffs, nones) = if ctx < 8 {
512 let sym = br.read_cb(&codebooks.nc_cb[NC_MAP[ctx as usize]])?;
518 let ncoeffs = (br.read(4)? + 1) as u8;
519 let nones = br.read(2)? as u8;
525 let mut num_zero = if ncoeffs == 16 { 0 } else {
526 br.read_cb(&codebooks.num_zero_cb[ncoeffs as usize - 1])?
528 validate!(ncoeffs + num_zero <= 16);
529 let mut blk = [0i32; 16];
530 let mut level = 0usize;
531 let mut coef_left = ncoeffs;
532 let mut ones_left = nones;
533 let mut idx = ncoeffs + num_zero;
534 while coef_left > 0 {
535 let val = if ones_left > 0 {
537 if !br.read_bool()? { 1 } else { -1 }
539 let prefix = br.read_unary()?;
540 let val = if prefix < 15 {
541 (br.read(level as u8)? | (prefix << level)) as i32
543 (br.read(11)? + (15 << level)) as i32
545 if val > MAX_LEVEL[level] {
548 if !br.read_bool()? {
555 blk[ZIGZAG[idx as usize]] = val;
557 if num_zero > 0 && coef_left > 0 {
558 let run = if num_zero < 7 {
559 br.read_cb(&codebooks.zero_run_cb[num_zero as usize - 1])?
562 7 - (br.read(3)? as u8)
564 (br.read_unary()? as u8) + 4
567 validate!(run <= num_zero);
572 idct_add(qmat, &mut blk, dst);
576 const NCSTRIDE: usize = 64 + 1;
578 struct VXVideoDecoder {
579 info: NACodecInfoRef,
582 buf: [[u8; 256 * 392]; 4], // layout is luma with stride 256 and at 256*256 chroma lines with two components starting at positions 0 and 128 and stride 256
585 y_ncoeffs: [u8; NCSTRIDE * (256 / 4 + 1)],
586 c_ncoeffs: [u8; NCSTRIDE * (256 / 8 + 1)],
591 codebooks: Codebooks,
594 impl VXVideoDecoder {
597 info: NACodecInfoRef::default(),
598 buf: [[0x80; 256 * 392]; 4],
603 y_ncoeffs: [0; NCSTRIDE * (256 / 4 + 1)],
604 c_ncoeffs: [0; NCSTRIDE * (256 / 8 + 1)],
605 mvs: [MV::default(); 16 * 16],
606 cur_mv: MV::default(),
607 pred_mv: MV::default(),
609 codebooks: Codebooks::new(),
612 fn update_refs(&mut self) {
613 for el in self.refs.iter_mut() {
617 fn decode_frame(&mut self, br: &mut BitReader) -> DecoderResult<()> {
619 for ypos in (0..self.height).step_by(16) {
620 for xpos in (0..self.width).step_by(16) {
621 let left_mv = self.mvs[mv_pos - 1];
622 let top_mv = self.mvs[mv_pos - 17];
623 let tl_mv = self.mvs[mv_pos - 18];
624 self.pred_mv = MV::pred(top_mv, tl_mv, left_mv);
625 self.cur_mv = MV::default();
626 self.decode_block(br, xpos, ypos, 16, 16)?;
627 self.mvs[mv_pos] = self.cur_mv;
630 mv_pos -= self.width / 16;
635 fn copy_block(&mut self, xpos: usize, ypos: usize, w: usize, h: usize, ref_buf: usize) -> DecoderResult<()> {
636 let src = self.refs[ref_buf];
637 let dst = self.refs[CUR_BUF];
638 self.cur_mv = self.pred_mv;
639 let mx = self.pred_mv.x as isize;
640 let my = self.pred_mv.y as isize;
641 mc!(self.buf, src, dst, mx, my, xpos, ypos, w, h, 0, 0, 0, self.width, self.height);
644 fn do_mc(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize, ref_buf: usize) -> DecoderResult<()> {
645 let src = self.refs[ref_buf];
646 let dst = self.refs[CUR_BUF];
647 let dx = br.read_gammap_s()? as i8;
648 let dy = br.read_gammap_s()? as i8;
649 self.cur_mv = self.pred_mv + MV { x: dx, y: dy };
650 let mx = self.cur_mv.x as isize;
651 let my = self.cur_mv.y as isize;
652 mc!(self.buf, src, dst, mx, my, xpos, ypos, w, h, 0, 0, 0, self.width, self.height);
656 fn do_mc_bias(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> {
657 let src = self.refs[0];
658 let dst = self.refs[CUR_BUF];
659 let mx = br.read_gammap_s()? as isize;
660 let my = br.read_gammap_s()? as isize;
661 let ydelta = br.read_gammap_s()? * 2;
662 let udelta = br.read_gammap_s()? * 2;
663 let vdelta = br.read_gammap_s()? * 2;
664 mc!(self.buf, src, dst, mx, my, xpos, ypos, w, h, ydelta, udelta, vdelta, self.width, self.height);
668 fn pred_plane(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> {
669 let ydelta = br.read_gammap_s()? * 2;
670 let udelta = br.read_gammap_s()? * 2;
671 let vdelta = br.read_gammap_s()? * 2;
672 let yoff = xpos + ypos * 256;
673 let coff = CHROMA_OFF + xpos / 2 + ypos / 2 * 256;
674 pred_plane_delta(&mut self.buf[self.refs[CUR_BUF]], yoff, w, h, ydelta);
675 pred_plane_delta(&mut self.buf[self.refs[CUR_BUF]], coff, w / 2, h / 2, udelta);
676 pred_plane_delta(&mut self.buf[self.refs[CUR_BUF]], coff + 128, w / 2, h / 2, vdelta);
679 fn intra_pred(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> {
680 let ymode = br.read_gammap()? as usize;
681 let cmode = br.read_gammap()? as usize;
682 let yoff = xpos + ypos * 256;
683 let coff = CHROMA_OFF + xpos / 2 + ypos / 2 * 256;
684 let blk = &mut self.buf[self.refs[CUR_BUF]];
686 0 => pred_ver(blk, yoff, w, h),
687 1 => pred_hor(blk, yoff, w, h),
688 2 => pred_dc (blk, yoff, xpos, ypos, w, h),
689 3 => pred_plane_delta(blk, yoff, w, h, 0),
690 _ => return Err(DecoderError::InvalidData),
694 pred_dc(blk, coff, xpos / 2, ypos / 2, w / 2, h / 2);
695 pred_dc(blk, coff + 128, xpos / 2, ypos / 2, w / 2, h / 2);
698 pred_hor(blk, coff, w / 2, h / 2);
699 pred_hor(blk, coff + 128, w / 2, h / 2);
702 pred_ver(blk, coff, w / 2, h / 2);
703 pred_ver(blk, coff + 128, w / 2, h / 2);
706 pred_plane_delta(blk, coff, w / 2, h / 2, 0);
707 pred_plane_delta(blk, coff + 128, w / 2, h / 2, 0);
709 _ => return Err(DecoderError::InvalidData),
713 fn intra_pred4x4(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> {
714 let mut yoff = xpos + ypos * 256;
716 let blk = &mut self.buf[self.refs[CUR_BUF]];
717 for y in (0..h).step_by(4) {
718 for x in (0..w).step_by(4) {
719 let mut mode = self.ipred4x4[idx - 5].min(self.ipred4x4[idx - 1]);
723 if !br.read_bool()? {
724 let mode1 = br.read(3)? as u8;
725 mode = if mode1 >= mode { mode1 + 1 } else { mode1 };
728 0 => pred_ver(blk, yoff + x, 4, 4),
729 1 => pred_hor(blk, yoff + x, 4, 4),
730 2 => pred_dc4x4(blk, yoff + x, xpos + x, ypos + y),
731 3 => pred_ddown_left (blk, yoff + x),
732 4 => pred_ddown_right(blk, yoff + x),
733 5 => pred_ver_right (blk, yoff + x),
734 6 => pred_hor_down (blk, yoff + x),
735 7 => pred_ver_left (blk, yoff + x),
736 8 => pred_hor_up (blk, yoff + x),
739 self.ipred4x4[idx] = mode;
746 let cmode = br.read_gammap()? as usize;
747 let coff = CHROMA_OFF + xpos / 2 + ypos / 2 * 256;
750 pred_dc(blk, coff, xpos / 2, ypos / 2, w / 2, h / 2);
751 pred_dc(blk, coff + 128, xpos / 2, ypos / 2, w / 2, h / 2);
754 pred_hor(blk, coff, w / 2, h / 2);
755 pred_hor(blk, coff + 128, w / 2, h / 2);
758 pred_ver(blk, coff, w / 2, h / 2);
759 pred_ver(blk, coff + 128, w / 2, h / 2);
762 pred_plane_delta(blk, coff, w / 2, h / 2, 0);
763 pred_plane_delta(blk, coff + 128, w / 2, h / 2, 0);
765 _ => return Err(DecoderError::InvalidData),
769 fn decode_residue(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> {
770 const CBP: [u8; 32] = [
771 0x00, 0x08, 0x04, 0x02, 0x01, 0x1F, 0x0F, 0x0A,
772 0x05, 0x0C, 0x03, 0x10, 0x0E, 0x0D, 0x0B, 0x07,
773 0x09, 0x06, 0x1E, 0x1B, 0x1A, 0x1D, 0x17, 0x15,
774 0x18, 0x12, 0x11, 0x1C, 0x14, 0x13, 0x16, 0x19
777 let mut yoff = xpos + ypos * 256;
778 let mut coff = CHROMA_OFF + xpos / 2 + ypos / 2 * 256;
779 let blk = &mut self.buf[self.refs[CUR_BUF]];
780 let mut yidx = (xpos / 4 + 1) + NCSTRIDE * (ypos / 4 + 1);
781 let mut cidx = (xpos / 8 + 1) + NCSTRIDE * (ypos / 8 + 1);
782 for _y in (0..h).step_by(8) {
783 for x in (0..w).step_by(8) {
784 let idx = br.read_gammap()? as usize;
785 validate!(idx < CBP.len());
788 let cur_yidx = yidx + x / 4 + (bno & 1) + (bno / 2) * NCSTRIDE;
789 if (cbp & (1 << bno)) != 0 {
790 let ctx = avg(self.y_ncoeffs[cur_yidx - 1], self.y_ncoeffs[cur_yidx - NCSTRIDE]);
791 self.y_ncoeffs[cur_yidx] = decode_coeffs(br, &self.codebooks, &self.qmat, ctx, &mut blk[yoff + x + (bno & 1) * 4 + (bno / 2) * 4 * 256..])?;
793 self.y_ncoeffs[cur_yidx] = 0;
796 if (cbp & 0x10) != 0 {
797 let ctx = avg(self.c_ncoeffs[cidx + x / 8 - 1], self.c_ncoeffs[cidx + x / 8 - NCSTRIDE]);
798 let unc = decode_coeffs(br, &self.codebooks, &self.qmat, ctx, &mut blk[coff + x / 2..])?;
799 let vnc = decode_coeffs(br, &self.codebooks, &self.qmat, ctx, &mut blk[coff + 128 + x / 2..])?;
800 self.c_ncoeffs[cidx + x / 8] = avg(unc, vnc);
802 self.c_ncoeffs[cidx + x / 8] = 0;
805 yidx += NCSTRIDE * 2;
812 fn decode_block(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> {
813 let mode = br.read_gammap()?;
814 let min_dim = w.min(h);
815 let large_block = min_dim >= 8;
816 if mode >= 16 && !large_block {
817 return Err(DecoderError::InvalidData);
822 self.decode_block(br, xpos, ypos, hw, h)?;
823 self.decode_block(br, xpos + hw, ypos, hw, h)?;
825 1 => { self.copy_block(xpos, ypos, w, h, 0)?; },
828 self.decode_block(br, xpos, ypos, w, hh)?;
829 self.decode_block(br, xpos, ypos + hh, w, hh)?;
831 3 => { self.do_mc_bias(br, xpos, ypos, w, h)?; },
833 let ref_id = (mode - 4) as usize;
834 self.do_mc(br, xpos, ypos, w, h, ref_id)?;
836 7 => { self.pred_plane(br, xpos, ypos, w, h)?; },
837 8 if large_block => {
839 self.decode_block(br, xpos, ypos, hw, h)?;
840 self.decode_block(br, xpos + hw, ypos, hw, h)?;
841 self.decode_residue(br, xpos, ypos, w, h)?;
843 9 => { self.copy_block(xpos, ypos, w, h, 1)?; },
844 10 if large_block => {
845 self.do_mc_bias(br, xpos, ypos, w, h)?;
846 self.decode_residue(br, xpos, ypos, w, h)?;
850 self.intra_pred(br, xpos, ypos, w, h)?;
853 12 if large_block => {
854 self.copy_block(xpos, ypos, w, h, 0)?;
855 self.decode_residue(br, xpos, ypos, w, h)?;
857 13 if large_block => {
859 self.decode_block(br, xpos, ypos, w, hh)?;
860 self.decode_block(br, xpos, ypos + hh, w, hh)?;
861 self.decode_residue(br, xpos, ypos, w, h)?;
863 14 => { self.copy_block(xpos, ypos, w, h, 2)?; },
866 self.intra_pred4x4(br, xpos, ypos, w, h)?;
870 let ref_id = (mode - 16) as usize;
871 self.do_mc(br, xpos, ypos, w, h, ref_id)?;
872 self.decode_residue(br, xpos, ypos, w, h)?;
875 self.intra_pred4x4(br, xpos, ypos, w, h)?;
876 self.decode_residue(br, xpos, ypos, w, h)?;
879 self.copy_block(xpos, ypos, w, h, 1)?;
880 self.decode_residue(br, xpos, ypos, w, h)?;
883 self.copy_block(xpos, ypos, w, h, 2)?;
884 self.decode_residue(br, xpos, ypos, w, h)?;
887 self.intra_pred(br, xpos, ypos, w, h)?;
888 self.decode_residue(br, xpos, ypos, w, h)?;
891 self.pred_plane(br, xpos, ypos, w, h)?;
892 self.decode_residue(br, xpos, ypos, w, h)?;
894 _ => return Err(DecoderError::InvalidData),
900 const QUANTISERS: [u8; 52] = [
901 10, 13, 10, 13, 13, 16, 13, 16, 11, 14, 11, 14, 14, 18, 14, 18,
902 13, 16, 13, 16, 16, 20, 16, 20, 14, 18, 14, 18, 18, 23, 18, 23,
903 16, 20, 16, 20, 20, 25, 20, 25, 18, 23, 18, 23, 23, 29, 23, 29,
907 impl NADecoder for VXVideoDecoder {
908 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
909 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
910 self.width = vinfo.get_width();
911 self.height = vinfo.get_height();
912 validate!(self.width <= 256 && self.height <= 256);
914 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT));
915 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
917 if let Some(edata) = info.get_extradata() {
918 validate!(edata.len() > 0);
919 let fps = edata[0] as usize;
920 validate!(fps <= 60);
921 let base = &QUANTISERS[(fps % 6) * 8..][..8];
923 for (dq, iq) in self.qmat.iter_mut().zip(base.iter()) {
924 *dq = i32::from(*iq) << scale;
927 return Err(DecoderError::InvalidData);
930 for frm in self.buf.iter_mut() {
931 let (ybuf, cbuf) = frm.split_at_mut(CHROMA_OFF);
932 for el in ybuf.iter_mut() {
935 for el in cbuf.iter_mut() {
942 Err(DecoderError::InvalidData)
945 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
946 let src = pkt.get_buffer();
947 validate!(src.len() > 0);
949 let mut br = BitReader::new(&src[0..], BitReaderMode::LE16MSB);
951 self.y_ncoeffs = [0; NCSTRIDE * (256 / 4 + 1)];
952 self.c_ncoeffs = [0; NCSTRIDE * (256 / 8 + 1)];
953 self.mvs = [MV::default(); 16 * 16];
954 self.decode_frame(&mut br)?;
956 let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 4)?;
957 let mut buf = bufinfo.get_vbuf().unwrap();
958 let ystride = buf.get_stride(0);
959 let ustride = buf.get_stride(1);
960 let vstride = buf.get_stride(2);
961 let yoff = buf.get_offset(0);
962 let uoff = buf.get_offset(1);
963 let voff = buf.get_offset(2);
964 let data = buf.get_data_mut().unwrap();
965 let cur = self.refs[CUR_BUF];
966 for (sline, dline) in self.buf[cur][0..].chunks(256).take(self.height).zip(data[yoff..].chunks_mut(ystride)) {
967 dline[..self.width].copy_from_slice(&sline[..self.width]);
969 for (sline, dline) in self.buf[cur][CHROMA_OFF..].chunks(256).take(self.height / 2).zip(data[uoff..].chunks_mut(ustride)) {
970 dline[..self.width / 2].copy_from_slice(&sline[..self.width / 2]);
972 for (sline, dline) in self.buf[cur][CHROMA_OFF + 128..].chunks(256).take(self.height / 2).zip(data[voff..].chunks_mut(vstride)) {
973 dline[..self.width / 2].copy_from_slice(&sline[..self.width / 2]);
975 let videobuf = NABufferType::Video(buf);
978 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), videobuf);
979 let is_intra = pkt.get_pts() == Some(0);
980 frm.set_keyframe(is_intra);
981 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
984 fn flush(&mut self) {
988 impl NAOptionHandler for VXVideoDecoder {
989 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
990 fn set_options(&mut self, _options: &[NAOption]) { }
991 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
995 pub fn get_decoder_video() -> Box<dyn NADecoder + Send> {
996 Box::new(VXVideoDecoder::new())
1008 lpc0_cb: [[i16; 8]; 64],
1009 lpc1_cb: [[i16; 8]; 64],
1010 lpc2_cb: [[i16; 8]; 64],
1012 base_filt: [i32; 8],
1026 lpc0_cb: [[0; 8]; 64],
1027 lpc1_cb: [[0; 8]; 64],
1028 lpc2_cb: [[0; 8]; 64],
1034 fn read_initial_params(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
1035 for entry in self.lpc0_cb.iter_mut() {
1036 for el in entry.iter_mut() {
1037 *el = br.read_u16le()? as i16;
1040 for entry in self.lpc1_cb.iter_mut() {
1041 for el in entry.iter_mut() {
1042 *el = br.read_u16le()? as i16;
1045 for entry in self.lpc2_cb.iter_mut() {
1046 for el in entry.iter_mut() {
1047 *el = br.read_u16le()? as i16;
1050 for el in self.decays.iter_mut() {
1051 *el = i32::from(br.read_u16le()? as i16);
1053 for el in self.base_filt.iter_mut() {
1054 *el = br.read_u32le()? as i32;
1056 self.base_scale = br.read_u32le()? as i32;
1059 fn unpack_data(&mut self, br: &mut ByteReader, val: u16, dst: &mut [i32]) -> DecoderResult<()> {
1060 self.lpc0_idx = (val & 0x3F) as usize;
1061 self.scale = (self.decays[((val >> 6) & 7) as usize] * self.scale) >> 13;
1062 let val1 = br.read_u16le()?;
1063 self.lpc1_idx = ((val1 >> 6) & 0x3F) as usize;
1064 self.lpc2_idx = (val1 & 0x3F) as usize;
1065 self.frame_mode = ((val1 >> 12) & 3) as usize;
1066 let mut idx = (val1 >> 14) as usize;
1067 if self.frame_mode == 0 {
1070 let val = br.read_u16le()?;
1072 let add = i32::from((val >> (13 - i * 3)) & 7);
1073 dst[idx] += self.scale * (add * 2 - 7);
1076 tail = tail * 2 + (val & 1);
1078 let add = i32::from((tail >> 5) & 7);
1079 dst[idx] += self.scale * (add * 2 - 7);
1081 let add = i32::from((tail >> 2) & 7);
1082 dst[idx] += self.scale * (add * 2 - 7);
1084 let (len, step) = match self.frame_mode {
1088 _ => unreachable!(),
1092 let val = br.read_u16le()?;
1094 let add = i32::from((val >> (14 - i * 2)) & 3);
1095 dst[idx] += self.scale * (add * 2 - 3);
1102 fn update_intra(&mut self) {
1103 self.cur_filt = self.base_filt;
1105 self.cur_filt[i] += i32::from(self.lpc0_cb[self.lpc0_idx][i]);
1106 self.cur_filt[i] += i32::from(self.lpc1_cb[self.lpc1_idx][i]);
1107 self.cur_filt[i] += i32::from(self.lpc2_cb[self.lpc2_idx][i]);
1110 fn update_inter(&mut self) {
1112 self.cur_filt[i] += i32::from(self.lpc0_cb[self.lpc0_idx][i]);
1113 self.cur_filt[i] += i32::from(self.lpc1_cb[self.lpc1_idx][i]);
1114 self.cur_filt[i] += i32::from(self.lpc2_cb[self.lpc2_idx][i]);
1119 fn apply_lpc(dst: &mut [i32], src: &[i32], hist: &mut [i32], filt: &[i32; 8]) {
1121 for (out, src) in dst.iter_mut().zip(src.iter()) {
1122 let mut sum = *src << 14;
1124 sum += hist[(hidx + i) & 7] * filt[i];
1126 let samp = sum >> 14;
1128 hist[hidx & 7] = samp;
1133 struct VXAudioDecoder {
1135 info: Arc<NACodecInfo>,
1136 chmap: NAChannelMap,
1137 buf: [i32; 256 * 2],
1142 lpc_filt1: [i32; 8],
1145 impl VXAudioDecoder {
1148 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
1149 info: NACodecInfo::new_dummy(),
1150 chmap: NAChannelMap::new(),
1153 state: AudioState::new(),
1159 fn decode_inter(&mut self, br: &mut ByteReader, mode: u16, val: u16) -> DecoderResult<()> {
1160 let (mut cur_buf, mut prev_buf) = self.buf.split_at_mut(256);
1162 std::mem::swap(&mut cur_buf, &mut prev_buf);
1164 cur_buf[0..128].copy_from_slice(&prev_buf[128..]);
1166 for el in cur_buf[128..].iter_mut() {
1170 let src = &prev_buf[127 - (mode as usize)..];
1171 let dst = &mut cur_buf[128..];
1173 dst[i] = (src[i] * ((i + 1) as i32)) >> 4;
1176 dst[i] = src[i] >> 1;
1179 dst[i] = (src[i] * ((128 - i) as i32)) >> 4;
1183 self.state.unpack_data(br, val, prev_buf )?;
1184 self.state.update_inter();
1186 let (cfilt, pfilt) = if !self.flip_buf {
1187 (&mut self.lpc_filt, &mut self.lpc_filt1)
1189 (&mut self.lpc_filt1, &mut self.lpc_filt)
1191 *cfilt = self.state.cur_filt;
1192 let mut f0 = [0; 8];
1193 let mut f1 = [0; 8];
1194 let mut f2 = [0; 8];
1196 f1[i] = (pfilt[i] + cfilt[i]) >> 1;
1197 f0[i] = (pfilt[i] + f1 [i]) >> 1;
1198 f2[i] = (f1 [i] + cfilt[i]) >> 1;
1200 apply_lpc(&mut cur_buf[ 0..][..32], &prev_buf[128..], &mut self.lpc_hist, &f0);
1201 apply_lpc(&mut cur_buf[32..][..32], &prev_buf[128 + 32..], &mut self.lpc_hist, &f1);
1202 apply_lpc(&mut cur_buf[64..][..32], &prev_buf[128 + 64..], &mut self.lpc_hist, &f2);
1203 apply_lpc(&mut cur_buf[96..][..32], &prev_buf[128 + 96..], &mut self.lpc_hist, &cfilt);
1206 fn decode_intra(&mut self, br: &mut ByteReader, val: u16) -> DecoderResult<()> {
1207 self.state.scale = self.state.base_scale;
1208 self.lpc_hist = [0; 8];
1209 self.flip_buf = true;
1211 let (mut cur_buf, mut prev_buf) = self.buf.split_at_mut(256);
1213 std::mem::swap(&mut cur_buf, &mut prev_buf);
1215 for el in cur_buf[128..].iter_mut() {
1218 self.state.unpack_data(br, val, prev_buf)?;
1219 self.state.update_intra();
1221 self.lpc_filt = self.state.cur_filt;
1222 apply_lpc(&mut cur_buf[..128], &prev_buf[128..], &mut self.lpc_hist, &self.lpc_filt);
1225 fn output(&mut self, dst: &mut [i16]) {
1226 let src = if self.flip_buf { &self.buf[256..][..128] } else { &self.buf[..128] };
1227 for (src, dst) in src.iter().zip(dst.iter_mut()) {
1228 *dst = (*src).max(-0x8000).min(0x7FFF) as i16;
1230 self.flip_buf = !self.flip_buf;
1234 impl NADecoder for VXAudioDecoder {
1235 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
1236 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
1237 if let Some(edata) = info.get_extradata() {
1238 validate!(edata.len() >= 3124);
1239 let mut mr = MemoryReader::new_read(edata.as_slice());
1240 let mut br = ByteReader::new(&mut mr);
1241 self.state.read_initial_params(&mut br)?;
1243 return Err(DecoderError::InvalidData);
1245 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), 1, SND_S16_FORMAT, 1);
1246 self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo));
1247 self.chmap = NAChannelMap::from_str("C").unwrap();
1250 Err(DecoderError::InvalidData)
1253 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
1254 const SUBFRAME_LEN: [usize; 4] = [20, 14, 12, 10];
1256 let info = pkt.get_stream().get_info();
1257 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
1258 let pktbuf = pkt.get_buffer();
1259 validate!(pktbuf.len() >= 10);
1261 let mut mr = MemoryReader::new_read(&pktbuf);
1262 let mut br = ByteReader::new(&mut mr);
1263 let mut nblocks = 0;
1264 while br.left() > 4 {
1266 let val = br.read_u16le()?;
1268 let sf_len = SUBFRAME_LEN[((val >> 12) & 3) as usize];
1269 if br.left() <= sf_len as i64 {
1272 br.read_skip(sf_len - 4)?;
1275 let samples = 128 * nblocks;
1276 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
1277 let mut adata = abuf.get_abuf_i16().unwrap();
1278 let dst = adata.get_data_mut().unwrap();
1280 let mut mr = MemoryReader::new_read(&pktbuf);
1281 let mut br = ByteReader::new(&mut mr);
1283 let mut blk_no = 0usize;
1284 while br.left() > 0 {
1285 let val = br.read_u16le()?;
1286 let mode = val >> 9;
1288 self.decode_intra(&mut br, val)?;
1290 self.decode_inter(&mut br, val & 0x1FF, mode)?;
1292 self.output(&mut dst[blk_no * 128..]);
1296 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf);
1297 frm.set_duration(Some(samples as u64));
1298 frm.set_keyframe(true);
1301 Err(DecoderError::InvalidData)
1304 fn flush(&mut self) {
1309 impl NAOptionHandler for VXAudioDecoder {
1310 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
1311 fn set_options(&mut self, _options: &[NAOption]) { }
1312 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
1316 pub fn get_decoder_audio() -> Box<dyn NADecoder + Send> {
1317 Box::new(VXAudioDecoder::new())
1322 use nihav_core::codecs::RegisteredDecoders;
1323 use nihav_core::demuxers::RegisteredDemuxers;
1324 use nihav_codec_support::test::dec_video::*;
1325 use crate::game_register_all_decoders;
1326 use crate::game_register_all_demuxers;
1328 fn test_vx_video() {
1329 let mut dmx_reg = RegisteredDemuxers::new();
1330 game_register_all_demuxers(&mut dmx_reg);
1331 let mut dec_reg = RegisteredDecoders::new();
1332 game_register_all_decoders(&mut dec_reg);
1334 //XXX: the current version does not reconstruct videos perfectly yet
1335 test_decoding("vx", "vxvideo", "assets/Game/bioware.vx", Some(31), &dmx_reg, &dec_reg,
1336 ExpectedTestResult::MD5Frames(vec![
1337 [0x33de14fa, 0x00948eb7, 0x028141d7, 0x1d07abd6],
1338 [0x07442eef, 0x36ec00c1, 0x3d9556c6, 0x6ddbcd46],
1339 [0xb5b48d03, 0x0063faaf, 0xfa64de6f, 0xbe5d916b],
1340 [0xb760b777, 0xe7159f5e, 0x352b7326, 0xd21e3d14],
1341 [0xee1ccadc, 0xd2b54891, 0xb5f6f31a, 0x73d7e869],
1342 [0xcd234bd9, 0xad3d8f3e, 0xdb405b8c, 0x4faa738b],
1343 [0x615957be, 0x8a20b367, 0xadc031af, 0x886311cc],
1344 [0xade60b19, 0x2560fffa, 0x8bafff67, 0x698485ad],
1345 [0x131b874c, 0x4bb41da5, 0xc0f52bf2, 0x626d6e66],
1346 [0x1dc1bb4b, 0xc3552467, 0xa5598162, 0xe6220dde],
1347 [0xa1e27935, 0xd01c18c4, 0x6e6e1be7, 0xc42b021c],
1348 [0x28876ccb, 0xfaca435f, 0xe8cf81d7, 0x8f103d89],
1349 [0xab610d4d, 0x0bf5b213, 0x28749eda, 0xcbf5c34c],
1350 [0x48a452f8, 0x544b8a4d, 0x0a031be4, 0xe60b6f59],
1351 [0xe6f88898, 0x46171e3b, 0xf39e2605, 0x3d16e75a],
1352 [0xe1461669, 0x3dd4daa6, 0x1e82b9e7, 0x49214174],
1353 [0x39d89d57, 0x5c0bf9ba, 0xf254cdc4, 0x8c1b9bb9],
1354 [0x81f1a684, 0xd2a0bc8a, 0xe1355afa, 0xbe33e476],
1355 [0x571b0722, 0x25643452, 0x509ed72d, 0x1d55214e],
1356 [0xc799fa72, 0xed2bc13d, 0xa9be1b55, 0xece4d7f0],
1357 [0x0eae7358, 0x87d80481, 0xcac84bf9, 0x76bee392],
1358 [0xf0e6fb26, 0x95a9a362, 0x474edaa2, 0xd8d0b5fc],
1359 [0xee57bff2, 0x490b9ffc, 0x6189e2d4, 0xb1b97277],
1360 [0xa5f83723, 0xaa807527, 0x5c722b29, 0x3ea10cfc],
1361 [0x83562752, 0x27021714, 0x5b81f808, 0x192fa17c],
1362 [0x50f5ab82, 0x01a482b2, 0xa44b7525, 0xac4d1916],
1363 [0x8cf1fffd, 0xf09364c5, 0x57847078, 0x1a811a61],
1364 [0x3d8e4221, 0xe69532b1, 0x7bd4fa20, 0x78dc0676],
1365 [0x7b6432a5, 0x01ee9819, 0xfd0fd634, 0x96fd612b],
1366 [0xb0e0d469, 0xc651dd3a, 0xf2fa8e9b, 0xc58d55be],
1367 [0xa9d7fa17, 0xaf2d05f8, 0xd307d0c1, 0xd83dc57a],
1368 [0x14e644a7, 0xd8d9e459, 0x0d81e68c, 0xe57b9b81]]));
1372 const NC_MAP: [usize; 8] = [ 0, 0, 1, 1, 2, 2, 2, 2 ];
1373 const NC_BITS: [[u16; 68]; 3] = [
1375 0x0001, 0x0000, 0x0000, 0x0000, 0x0005, 0x0001, 0x0000, 0x0000,
1376 0x0007, 0x0004, 0x0001, 0x0000, 0x0007, 0x0006, 0x0005, 0x0003,
1377 0x0007, 0x0006, 0x0005, 0x0003, 0x0007, 0x0006, 0x0005, 0x0004,
1378 0x000F, 0x0006, 0x0005, 0x0004, 0x000B, 0x000E, 0x0005, 0x0004,
1379 0x0008, 0x000A, 0x000D, 0x0004, 0x000F, 0x000E, 0x0009, 0x0004,
1380 0x000B, 0x000A, 0x000D, 0x000C, 0x000F, 0x000E, 0x0009, 0x000C,
1381 0x000B, 0x000A, 0x000D, 0x0008, 0x000F, 0x0001, 0x0009, 0x000C,
1382 0x000B, 0x000E, 0x000D, 0x0008, 0x0007, 0x000A, 0x0009, 0x000C,
1383 0x0004, 0x0006, 0x0005, 0x0008
1385 0x0003, 0x0000, 0x0000, 0x0000, 0x000B, 0x0002, 0x0000, 0x0000,
1386 0x0007, 0x0007, 0x0003, 0x0000, 0x0007, 0x000A, 0x0009, 0x0005,
1387 0x0007, 0x0006, 0x0005, 0x0004, 0x0004, 0x0006, 0x0005, 0x0006,
1388 0x0007, 0x0006, 0x0005, 0x0008, 0x000F, 0x0006, 0x0005, 0x0004,
1389 0x000B, 0x000E, 0x000D, 0x0004, 0x000F, 0x000A, 0x0009, 0x0004,
1390 0x000B, 0x000E, 0x000D, 0x000C, 0x0008, 0x000A, 0x0009, 0x0008,
1391 0x000F, 0x000E, 0x000D, 0x000C, 0x000B, 0x000A, 0x0009, 0x000C,
1392 0x0007, 0x000B, 0x0006, 0x0008, 0x0009, 0x0008, 0x000A, 0x0001,
1393 0x0007, 0x0006, 0x0005, 0x0004
1395 0x000F, 0x0000, 0x0000, 0x0000, 0x000F, 0x000E, 0x0000, 0x0000,
1396 0x000B, 0x000F, 0x000D, 0x0000, 0x0008, 0x000C, 0x000E, 0x000C,
1397 0x000F, 0x000A, 0x000B, 0x000B, 0x000B, 0x0008, 0x0009, 0x000A,
1398 0x0009, 0x000E, 0x000D, 0x0009, 0x0008, 0x000A, 0x0009, 0x0008,
1399 0x000F, 0x000E, 0x000D, 0x000D, 0x000B, 0x000E, 0x000A, 0x000C,
1400 0x000F, 0x000A, 0x000D, 0x000C, 0x000B, 0x000E, 0x0009, 0x000C,
1401 0x0008, 0x000A, 0x000D, 0x0008, 0x000D, 0x0007, 0x0009, 0x000C,
1402 0x0009, 0x000C, 0x000B, 0x000A, 0x0005, 0x0008, 0x0007, 0x0006,
1403 0x0001, 0x0004, 0x0003, 0x0002
1406 const NC_LENS: [[u8; 68]; 3] = [
1408 1, 0, 0, 0, 6, 2, 0, 0,
1409 8, 6, 3, 0, 9, 8, 7, 5,
1410 10, 9, 8, 6, 11, 10, 9, 7,
1411 13, 11, 10, 8, 13, 13, 11, 9,
1412 13, 13, 13, 10, 14, 14, 13, 11,
1413 14, 14, 14, 13, 15, 15, 14, 14,
1414 15, 15, 15, 14, 16, 15, 15, 15,
1415 16, 16, 16, 15, 16, 16, 16, 16,
1418 2, 0, 0, 0, 6, 2, 0, 0,
1419 6, 5, 3, 0, 7, 6, 6, 4,
1420 8, 6, 6, 4, 8, 7, 7, 5,
1421 9, 8, 8, 6, 11, 9, 9, 6,
1422 11, 11, 11, 7, 12, 11, 11, 9,
1423 12, 12, 12, 11, 12, 12, 12, 11,
1424 13, 13, 13, 12, 13, 13, 13, 13,
1425 13, 14, 13, 13, 14, 14, 14, 13,
1428 4, 0, 0, 0, 6, 4, 0, 0,
1429 6, 5, 4, 0, 6, 5, 5, 4,
1430 7, 5, 5, 4, 7, 5, 5, 4,
1431 7, 6, 6, 4, 7, 6, 6, 4,
1432 8, 7, 7, 5, 8, 8, 7, 6,
1433 9, 8, 8, 7, 9, 9, 8, 8,
1434 9, 9, 9, 8, 10, 9, 9, 9,
1435 10, 10, 10, 10, 10, 10, 10, 10,
1440 const NUM_ZERO_BITS: [[u8; 16]; 15] = [
1442 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01
1444 0x07, 0x06, 0x05, 0x04, 0x03, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01, 0x00, 0x00
1446 0x05, 0x07, 0x06, 0x05, 0x04, 0x03, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00
1448 0x03, 0x07, 0x05, 0x04, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00
1450 0x05, 0x04, 0x03, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
1452 0x01, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1454 0x01, 0x01, 0x05, 0x04, 0x03, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1456 0x01, 0x01, 0x01, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1458 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1460 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1462 0x00, 0x01, 0x01, 0x02, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1464 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1466 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1468 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1470 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1473 const NUM_ZERO_LENS: [[u8; 16]; 15] = [
1474 [ 1, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 ],
1475 [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 0 ],
1476 [ 4, 3, 3, 3, 4, 4, 3, 3, 4, 5, 5, 6, 5, 6, 0, 0 ],
1477 [ 5, 3, 4, 4, 3, 3, 3, 4, 3, 4, 5, 5, 5, 0, 0, 0 ],
1478 [ 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 4, 5, 0, 0, 0, 0 ],
1479 [ 6, 5, 3, 3, 3, 3, 3, 3, 4, 3, 6, 0, 0, 0, 0, 0 ],
1480 [ 6, 5, 3, 3, 3, 2, 3, 4, 3, 6, 0, 0, 0, 0, 0, 0 ],
1481 [ 6, 4, 5, 3, 2, 2, 3, 3, 6, 0, 0, 0, 0, 0, 0, 0 ],
1482 [ 6, 6, 4, 2, 2, 3, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 ],
1483 [ 5, 5, 3, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1484 [ 4, 4, 3, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1485 [ 4, 4, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1486 [ 3, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1487 [ 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1488 [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
1491 const ZERO_RUN_BITS: [[u8; 8]; 6] = [
1492 [ 1, 0, 0, 0, 0, 0, 0, 0 ],
1493 [ 1, 1, 0, 0, 0, 0, 0, 0 ],
1494 [ 3, 2, 1, 0, 0, 0, 0, 0 ],
1495 [ 3, 2, 1, 1, 0, 0, 0, 0 ],
1496 [ 3, 2, 3, 2, 1, 0, 0, 0 ],
1497 [ 3, 0, 1, 3, 2, 5, 4, 0 ]
1499 const ZERO_RUN_LENS: [[u8; 8]; 6] = [
1500 [ 1, 1, 0, 0, 0, 0, 0, 0 ],
1501 [ 1, 2, 2, 0, 0, 0, 0, 0 ],
1502 [ 2, 2, 2, 2, 0, 0, 0, 0 ],
1503 [ 2, 2, 2, 3, 3, 0, 0, 0 ],
1504 [ 2, 2, 3, 3, 3, 3, 0, 0 ],
1505 [ 2, 3, 3, 3, 3, 3, 3, 0 ]