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, l0, 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 (val1, val2) = if is_even_block {
406 (dm, blk[pos + w2off - 256])
408 (blk[pos + woff + h2off], blk[pos - 1 + h2off])
410 blk[pos + w2off + h2off] = avg_nr(val1, val2);
414 pred_plane(blk, pos, hw, hh);
415 pred_plane(blk, pos + hw, hw, hh);
416 pred_plane(blk, pos + hh * 256, hw, hh);
417 pred_plane(blk, pos + hw + hh * 256, hw, hh);
419 fn pred_plane_delta(blk: &mut [u8], pos: usize, w: usize, h: usize, delta: i32) {
420 let tr = blk[pos + w - 1 - 256];
421 let dl = blk[pos + 256 * (h - 1) - 1];
422 let pred = avg(tr, dl).wrapping_add(delta as u8);
423 blk[pos + 256 * (h - 1) + w - 1] = pred;
424 pred_plane(blk, pos, w, h);
428 nc_cb: [Codebook<u8>; 3],
429 num_zero_cb: [Codebook<u8>; 15],
430 zero_run_cb: [Codebook<u8>; 6],
433 fn map_idx(idx: usize) -> u8 { idx as u8 }
434 macro_rules! create_cb {
435 ($bits_tab: expr, $lens_tab: expr) => {{
436 let mut cbr = TableCodebookDescReader::new($bits_tab, $lens_tab, map_idx);
437 Codebook::new(&mut cbr, CodebookMode::MSB).unwrap()
443 let nc_cb0 = create_cb!(&NC_BITS[0], &NC_LENS[0]);
444 let nc_cb1 = create_cb!(&NC_BITS[1], &NC_LENS[1]);
445 let nc_cb2 = create_cb!(&NC_BITS[2], &NC_LENS[2]);
447 let nz0 = create_cb!(&NUM_ZERO_BITS[ 0], &NUM_ZERO_LENS[ 0]);
448 let nz1 = create_cb!(&NUM_ZERO_BITS[ 1], &NUM_ZERO_LENS[ 1]);
449 let nz2 = create_cb!(&NUM_ZERO_BITS[ 2], &NUM_ZERO_LENS[ 2]);
450 let nz3 = create_cb!(&NUM_ZERO_BITS[ 3], &NUM_ZERO_LENS[ 3]);
451 let nz4 = create_cb!(&NUM_ZERO_BITS[ 4], &NUM_ZERO_LENS[ 4]);
452 let nz5 = create_cb!(&NUM_ZERO_BITS[ 5], &NUM_ZERO_LENS[ 5]);
453 let nz6 = create_cb!(&NUM_ZERO_BITS[ 6], &NUM_ZERO_LENS[ 6]);
454 let nz7 = create_cb!(&NUM_ZERO_BITS[ 7], &NUM_ZERO_LENS[ 7]);
455 let nz8 = create_cb!(&NUM_ZERO_BITS[ 8], &NUM_ZERO_LENS[ 8]);
456 let nz9 = create_cb!(&NUM_ZERO_BITS[ 9], &NUM_ZERO_LENS[ 9]);
457 let nz10 = create_cb!(&NUM_ZERO_BITS[10], &NUM_ZERO_LENS[10]);
458 let nz11 = create_cb!(&NUM_ZERO_BITS[11], &NUM_ZERO_LENS[11]);
459 let nz12 = create_cb!(&NUM_ZERO_BITS[12], &NUM_ZERO_LENS[12]);
460 let nz13 = create_cb!(&NUM_ZERO_BITS[13], &NUM_ZERO_LENS[13]);
461 let nz14 = create_cb!(&NUM_ZERO_BITS[14], &NUM_ZERO_LENS[14]);
463 let zcb0 = create_cb!(&ZERO_RUN_BITS[0], &ZERO_RUN_LENS[0]);
464 let zcb1 = create_cb!(&ZERO_RUN_BITS[1], &ZERO_RUN_LENS[1]);
465 let zcb2 = create_cb!(&ZERO_RUN_BITS[2], &ZERO_RUN_LENS[2]);
466 let zcb3 = create_cb!(&ZERO_RUN_BITS[3], &ZERO_RUN_LENS[3]);
467 let zcb4 = create_cb!(&ZERO_RUN_BITS[4], &ZERO_RUN_LENS[4]);
468 let zcb5 = create_cb!(&ZERO_RUN_BITS[5], &ZERO_RUN_LENS[5]);
470 nc_cb: [nc_cb0, nc_cb1, nc_cb2],
471 num_zero_cb: [nz0, nz1, nz2, nz3, nz4, nz5, nz6, nz7, nz8, nz9, nz10, nz11, nz12, nz13, nz14],
472 zero_run_cb: [zcb0, zcb1, zcb2, zcb3, zcb4, zcb5],
477 macro_rules! transform {
478 ($a: expr, $b: expr, $c: expr, $d: expr, $q0: expr, $q1: expr) => {
479 let t0 = ($a + $c).wrapping_mul($q0);
480 let t1 = ($a - $c).wrapping_mul($q0);
481 let tb = $b.wrapping_mul($q1);
482 let td = $d.wrapping_mul($q1);
483 let t2 = tb + (td >> 1);
484 let t3 = (tb >> 1) - td;
492 fn idct_add(qmat: &[i32; 8], blk: &mut [i32; 16], dst: &mut [u8]) {
494 transform!(blk[i + 0 * 4], blk[i + 1 * 4], blk[i + 2 * 4], blk[i + 3 * 4], qmat[i], qmat[i + 4]);
496 for (dline, row) in dst.chunks_mut(256).zip(blk.chunks_mut(4)) {
497 transform!(row[0], row[1], row[2], row[3], 1, 1);
498 for (out, coef) in dline.iter_mut().zip(row.iter_mut()) {
499 *out = (i32::from(*out) + ((*coef + 0x20) >> 6)).max(0).min(255) as u8;
504 fn decode_coeffs(br: &mut BitReader, codebooks: &Codebooks, qmat: &[i32; 8], ctx: u8, dst: &mut [u8]) -> DecoderResult<u8> {
505 const ZIGZAG: [usize; 16] = [
511 const MAX_LEVEL: [i32; 6] = [ 2, 5, 11, 23, 47, 0x8000 ];
513 let (ncoeffs, nones) = if ctx < 8 {
514 let sym = br.read_cb(&codebooks.nc_cb[NC_MAP[ctx as usize]])?;
520 let ncoeffs = (br.read(4)? + 1) as u8;
521 let nones = br.read(2)? as u8;
527 let mut num_zero = if ncoeffs == 16 { 0 } else {
528 br.read_cb(&codebooks.num_zero_cb[ncoeffs as usize - 1])?
530 validate!(ncoeffs + num_zero <= 16);
531 let mut blk = [0i32; 16];
532 let mut level = 0usize;
533 let mut coef_left = ncoeffs;
534 let mut ones_left = nones;
535 let mut idx = ncoeffs + num_zero;
536 while coef_left > 0 {
537 let val = if ones_left > 0 {
539 if !br.read_bool()? { 1 } else { -1 }
541 let prefix = br.read_unary()?;
542 let val = if prefix < 15 {
543 (br.read(level as u8)? | (prefix << level)) as i32
545 (br.read(11)? + (15 << level)) as i32
547 if val > MAX_LEVEL[level] {
550 if !br.read_bool()? {
557 blk[ZIGZAG[idx as usize]] = val;
559 if num_zero > 0 && coef_left > 0 {
560 let run = if num_zero < 7 {
561 br.read_cb(&codebooks.zero_run_cb[num_zero as usize - 1])?
564 7 - (br.read(3)? as u8)
566 (br.read_unary()? as u8) + 4
569 validate!(run <= num_zero);
574 idct_add(qmat, &mut blk, dst);
578 const NCSTRIDE: usize = 64 + 1;
580 struct VXVideoDecoder {
581 info: NACodecInfoRef,
584 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
587 y_ncoeffs: [u8; NCSTRIDE * (256 / 4 + 1)],
588 c_ncoeffs: [u8; NCSTRIDE * (256 / 8 + 1)],
593 codebooks: Codebooks,
596 impl VXVideoDecoder {
599 info: NACodecInfoRef::default(),
600 buf: [[0x80; 256 * 392]; 4],
605 y_ncoeffs: [0; NCSTRIDE * (256 / 4 + 1)],
606 c_ncoeffs: [0; NCSTRIDE * (256 / 8 + 1)],
607 mvs: [MV::default(); 16 * 16],
608 cur_mv: MV::default(),
609 pred_mv: MV::default(),
611 codebooks: Codebooks::new(),
614 fn update_refs(&mut self) {
615 for el in self.refs.iter_mut() {
619 fn decode_frame(&mut self, br: &mut BitReader) -> DecoderResult<()> {
621 for ypos in (0..self.height).step_by(16) {
622 for xpos in (0..self.width).step_by(16) {
623 let left_mv = self.mvs[mv_pos - 1];
624 let top_mv = self.mvs[mv_pos - 17];
625 let tl_mv = self.mvs[mv_pos - 18];
626 self.pred_mv = MV::pred(top_mv, tl_mv, left_mv);
627 self.cur_mv = MV::default();
628 self.decode_block(br, xpos, ypos, 16, 16)?;
629 self.mvs[mv_pos] = self.cur_mv;
632 mv_pos -= self.width / 16;
637 fn copy_block(&mut self, xpos: usize, ypos: usize, w: usize, h: usize, ref_buf: usize) -> DecoderResult<()> {
638 let src = self.refs[ref_buf];
639 let dst = self.refs[CUR_BUF];
640 self.cur_mv = self.pred_mv;
641 let mx = self.pred_mv.x as isize;
642 let my = self.pred_mv.y as isize;
643 mc!(self.buf, src, dst, mx, my, xpos, ypos, w, h, 0, 0, 0, self.width, self.height);
646 fn do_mc(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize, ref_buf: usize) -> DecoderResult<()> {
647 let src = self.refs[ref_buf];
648 let dst = self.refs[CUR_BUF];
649 let dx = br.read_gammap_s()? as i8;
650 let dy = br.read_gammap_s()? as i8;
651 self.cur_mv = self.pred_mv + MV { x: dx, y: dy };
652 let mx = self.cur_mv.x as isize;
653 let my = self.cur_mv.y as isize;
654 mc!(self.buf, src, dst, mx, my, xpos, ypos, w, h, 0, 0, 0, self.width, self.height);
658 fn do_mc_bias(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> {
659 let src = self.refs[0];
660 let dst = self.refs[CUR_BUF];
661 let mx = br.read_gammap_s()? as isize;
662 let my = br.read_gammap_s()? as isize;
663 let ydelta = br.read_gammap_s()? * 2;
664 let udelta = br.read_gammap_s()? * 2;
665 let vdelta = br.read_gammap_s()? * 2;
666 mc!(self.buf, src, dst, mx, my, xpos, ypos, w, h, ydelta, udelta, vdelta, self.width, self.height);
670 fn pred_plane(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> {
671 let ydelta = br.read_gammap_s()? * 2;
672 let udelta = br.read_gammap_s()? * 2;
673 let vdelta = br.read_gammap_s()? * 2;
674 let yoff = xpos + ypos * 256;
675 let coff = CHROMA_OFF + xpos / 2 + ypos / 2 * 256;
676 pred_plane_delta(&mut self.buf[self.refs[CUR_BUF]], yoff, w, h, ydelta);
677 pred_plane_delta(&mut self.buf[self.refs[CUR_BUF]], coff, w / 2, h / 2, udelta);
678 pred_plane_delta(&mut self.buf[self.refs[CUR_BUF]], coff + 128, w / 2, h / 2, vdelta);
681 fn intra_pred(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> {
682 let ymode = br.read_gammap()? as usize;
683 let cmode = br.read_gammap()? as usize;
684 let yoff = xpos + ypos * 256;
685 let coff = CHROMA_OFF + xpos / 2 + ypos / 2 * 256;
686 let blk = &mut self.buf[self.refs[CUR_BUF]];
688 0 => pred_ver(blk, yoff, w, h),
689 1 => pred_hor(blk, yoff, w, h),
690 2 => pred_dc (blk, yoff, xpos, ypos, w, h),
691 3 => pred_plane_delta(blk, yoff, w, h, 0),
692 _ => return Err(DecoderError::InvalidData),
696 pred_dc(blk, coff, xpos / 2, ypos / 2, w / 2, h / 2);
697 pred_dc(blk, coff + 128, xpos / 2, ypos / 2, w / 2, h / 2);
700 pred_hor(blk, coff, w / 2, h / 2);
701 pred_hor(blk, coff + 128, w / 2, h / 2);
704 pred_ver(blk, coff, w / 2, h / 2);
705 pred_ver(blk, coff + 128, w / 2, h / 2);
708 pred_plane_delta(blk, coff, w / 2, h / 2, 0);
709 pred_plane_delta(blk, coff + 128, w / 2, h / 2, 0);
711 _ => return Err(DecoderError::InvalidData),
715 fn intra_pred4x4(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> {
716 let mut yoff = xpos + ypos * 256;
718 let blk = &mut self.buf[self.refs[CUR_BUF]];
719 for y in (0..h).step_by(4) {
720 for x in (0..w).step_by(4) {
721 let mut mode = self.ipred4x4[idx - 5].min(self.ipred4x4[idx - 1]);
725 if !br.read_bool()? {
726 let mode1 = br.read(3)? as u8;
727 mode = if mode1 >= mode { mode1 + 1 } else { mode1 };
730 0 => pred_ver(blk, yoff + x, 4, 4),
731 1 => pred_hor(blk, yoff + x, 4, 4),
732 2 => pred_dc4x4(blk, yoff + x, xpos + x, ypos + y),
733 3 => pred_ddown_left (blk, yoff + x),
734 4 => pred_ddown_right(blk, yoff + x),
735 5 => pred_ver_right (blk, yoff + x),
736 6 => pred_hor_down (blk, yoff + x),
737 7 => pred_ver_left (blk, yoff + x),
738 8 => pred_hor_up (blk, yoff + x),
741 self.ipred4x4[idx] = mode;
748 let cmode = br.read_gammap()? as usize;
749 let coff = CHROMA_OFF + xpos / 2 + ypos / 2 * 256;
752 pred_dc(blk, coff, xpos / 2, ypos / 2, w / 2, h / 2);
753 pred_dc(blk, coff + 128, xpos / 2, ypos / 2, w / 2, h / 2);
756 pred_hor(blk, coff, w / 2, h / 2);
757 pred_hor(blk, coff + 128, w / 2, h / 2);
760 pred_ver(blk, coff, w / 2, h / 2);
761 pred_ver(blk, coff + 128, w / 2, h / 2);
764 pred_plane_delta(blk, coff, w / 2, h / 2, 0);
765 pred_plane_delta(blk, coff + 128, w / 2, h / 2, 0);
767 _ => return Err(DecoderError::InvalidData),
771 fn decode_residue(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> {
772 const CBP: [u8; 32] = [
773 0x00, 0x08, 0x04, 0x02, 0x01, 0x1F, 0x0F, 0x0A,
774 0x05, 0x0C, 0x03, 0x10, 0x0E, 0x0D, 0x0B, 0x07,
775 0x09, 0x06, 0x1E, 0x1B, 0x1A, 0x1D, 0x17, 0x15,
776 0x18, 0x12, 0x11, 0x1C, 0x14, 0x13, 0x16, 0x19
779 let mut yoff = xpos + ypos * 256;
780 let mut coff = CHROMA_OFF + xpos / 2 + ypos / 2 * 256;
781 let blk = &mut self.buf[self.refs[CUR_BUF]];
782 let mut yidx = (xpos / 4 + 1) + NCSTRIDE * (ypos / 4 + 1);
783 let mut cidx = (xpos / 8 + 1) + NCSTRIDE * (ypos / 8 + 1);
784 for _y in (0..h).step_by(8) {
785 for x in (0..w).step_by(8) {
786 let idx = br.read_gammap()? as usize;
787 validate!(idx < CBP.len());
790 let cur_yidx = yidx + x / 4 + (bno & 1) + (bno / 2) * NCSTRIDE;
791 if (cbp & (1 << bno)) != 0 {
792 let ctx = avg(self.y_ncoeffs[cur_yidx - 1], self.y_ncoeffs[cur_yidx - NCSTRIDE]);
793 self.y_ncoeffs[cur_yidx] = decode_coeffs(br, &self.codebooks, &self.qmat, ctx, &mut blk[yoff + x + (bno & 1) * 4 + (bno / 2) * 4 * 256..])?;
795 self.y_ncoeffs[cur_yidx] = 0;
798 if (cbp & 0x10) != 0 {
799 let ctx = avg(self.c_ncoeffs[cidx + x / 8 - 1], self.c_ncoeffs[cidx + x / 8 - NCSTRIDE]);
800 let unc = decode_coeffs(br, &self.codebooks, &self.qmat, ctx, &mut blk[coff + x / 2..])?;
801 let vnc = decode_coeffs(br, &self.codebooks, &self.qmat, ctx, &mut blk[coff + 128 + x / 2..])?;
802 self.c_ncoeffs[cidx + x / 8] = avg(unc, vnc);
804 self.c_ncoeffs[cidx + x / 8] = 0;
807 yidx += NCSTRIDE * 2;
814 fn decode_block(&mut self, br: &mut BitReader, xpos: usize, ypos: usize, w: usize, h: usize) -> DecoderResult<()> {
815 let mode = br.read_gammap()?;
816 let min_dim = w.min(h);
817 let large_block = min_dim >= 8;
818 if mode >= 16 && !large_block {
819 return Err(DecoderError::InvalidData);
824 self.decode_block(br, xpos, ypos, hw, h)?;
825 self.decode_block(br, xpos + hw, ypos, hw, h)?;
827 1 => { self.copy_block(xpos, ypos, w, h, 0)?; },
830 self.decode_block(br, xpos, ypos, w, hh)?;
831 self.decode_block(br, xpos, ypos + hh, w, hh)?;
833 3 => { self.do_mc_bias(br, xpos, ypos, w, h)?; },
835 let ref_id = (mode - 4) as usize;
836 self.do_mc(br, xpos, ypos, w, h, ref_id)?;
838 7 => { self.pred_plane(br, xpos, ypos, w, h)?; },
839 8 if large_block => {
841 self.decode_block(br, xpos, ypos, hw, h)?;
842 self.decode_block(br, xpos + hw, ypos, hw, h)?;
843 self.decode_residue(br, xpos, ypos, w, h)?;
845 9 => { self.copy_block(xpos, ypos, w, h, 1)?; },
846 10 if large_block => {
847 self.do_mc_bias(br, xpos, ypos, w, h)?;
848 self.decode_residue(br, xpos, ypos, w, h)?;
852 self.intra_pred(br, xpos, ypos, w, h)?;
855 12 if large_block => {
856 self.copy_block(xpos, ypos, w, h, 0)?;
857 self.decode_residue(br, xpos, ypos, w, h)?;
859 13 if large_block => {
861 self.decode_block(br, xpos, ypos, w, hh)?;
862 self.decode_block(br, xpos, ypos + hh, w, hh)?;
863 self.decode_residue(br, xpos, ypos, w, h)?;
865 14 => { self.copy_block(xpos, ypos, w, h, 2)?; },
868 self.intra_pred4x4(br, xpos, ypos, w, h)?;
872 let ref_id = (mode - 16) as usize;
873 self.do_mc(br, xpos, ypos, w, h, ref_id)?;
874 self.decode_residue(br, xpos, ypos, w, h)?;
877 self.intra_pred4x4(br, xpos, ypos, w, h)?;
878 self.decode_residue(br, xpos, ypos, w, h)?;
881 self.copy_block(xpos, ypos, w, h, 1)?;
882 self.decode_residue(br, xpos, ypos, w, h)?;
885 self.copy_block(xpos, ypos, w, h, 2)?;
886 self.decode_residue(br, xpos, ypos, w, h)?;
889 self.intra_pred(br, xpos, ypos, w, h)?;
890 self.decode_residue(br, xpos, ypos, w, h)?;
893 self.pred_plane(br, xpos, ypos, w, h)?;
894 self.decode_residue(br, xpos, ypos, w, h)?;
896 _ => return Err(DecoderError::InvalidData),
902 const QUANTISERS: [u8; 52] = [
903 10, 13, 10, 13, 13, 16, 13, 16, 11, 14, 11, 14, 14, 18, 14, 18,
904 13, 16, 13, 16, 16, 20, 16, 20, 14, 18, 14, 18, 18, 23, 18, 23,
905 16, 20, 16, 20, 20, 25, 20, 25, 18, 23, 18, 23, 23, 29, 23, 29,
909 impl NADecoder for VXVideoDecoder {
910 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
911 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
912 self.width = vinfo.get_width();
913 self.height = vinfo.get_height();
914 validate!(self.width <= 256 && self.height <= 256);
916 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT));
917 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
919 if let Some(edata) = info.get_extradata() {
920 validate!(edata.len() > 0);
921 let fps = edata[0] as usize;
922 validate!(fps <= 60);
923 let base = &QUANTISERS[(fps % 6) * 8..][..8];
925 for (dq, iq) in self.qmat.iter_mut().zip(base.iter()) {
926 *dq = i32::from(*iq) << scale;
929 return Err(DecoderError::InvalidData);
932 for frm in self.buf.iter_mut() {
933 let (ybuf, cbuf) = frm.split_at_mut(CHROMA_OFF);
934 for el in ybuf.iter_mut() {
937 for el in cbuf.iter_mut() {
944 Err(DecoderError::InvalidData)
947 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
948 let src = pkt.get_buffer();
949 validate!(src.len() > 0);
951 let mut br = BitReader::new(&src[0..], BitReaderMode::LE16MSB);
953 self.y_ncoeffs = [0; NCSTRIDE * (256 / 4 + 1)];
954 self.c_ncoeffs = [0; NCSTRIDE * (256 / 8 + 1)];
955 self.mvs = [MV::default(); 16 * 16];
956 self.decode_frame(&mut br)?;
958 let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 4)?;
959 let mut buf = bufinfo.get_vbuf().unwrap();
960 let ystride = buf.get_stride(0);
961 let ustride = buf.get_stride(1);
962 let vstride = buf.get_stride(2);
963 let yoff = buf.get_offset(0);
964 let uoff = buf.get_offset(1);
965 let voff = buf.get_offset(2);
966 let data = buf.get_data_mut().unwrap();
967 let cur = self.refs[CUR_BUF];
968 for (sline, dline) in self.buf[cur][0..].chunks(256).take(self.height).zip(data[yoff..].chunks_mut(ystride)) {
969 dline[..self.width].copy_from_slice(&sline[..self.width]);
971 for (sline, dline) in self.buf[cur][CHROMA_OFF..].chunks(256).take(self.height / 2).zip(data[uoff..].chunks_mut(ustride)) {
972 dline[..self.width / 2].copy_from_slice(&sline[..self.width / 2]);
974 for (sline, dline) in self.buf[cur][CHROMA_OFF + 128..].chunks(256).take(self.height / 2).zip(data[voff..].chunks_mut(vstride)) {
975 dline[..self.width / 2].copy_from_slice(&sline[..self.width / 2]);
977 let videobuf = NABufferType::Video(buf);
980 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), videobuf);
981 let is_intra = pkt.get_pts() == Some(0);
982 frm.set_keyframe(is_intra);
983 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
986 fn flush(&mut self) {
990 impl NAOptionHandler for VXVideoDecoder {
991 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
992 fn set_options(&mut self, _options: &[NAOption]) { }
993 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
997 pub fn get_decoder_video() -> Box<dyn NADecoder + Send> {
998 Box::new(VXVideoDecoder::new())
1010 lpc0_cb: [[i16; 8]; 64],
1011 lpc1_cb: [[i16; 8]; 64],
1012 lpc2_cb: [[i16; 8]; 64],
1014 base_filt: [i32; 8],
1028 lpc0_cb: [[0; 8]; 64],
1029 lpc1_cb: [[0; 8]; 64],
1030 lpc2_cb: [[0; 8]; 64],
1036 fn read_initial_params(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
1037 for entry in self.lpc0_cb.iter_mut() {
1038 for el in entry.iter_mut() {
1039 *el = br.read_u16le()? as i16;
1042 for entry in self.lpc1_cb.iter_mut() {
1043 for el in entry.iter_mut() {
1044 *el = br.read_u16le()? as i16;
1047 for entry in self.lpc2_cb.iter_mut() {
1048 for el in entry.iter_mut() {
1049 *el = br.read_u16le()? as i16;
1052 for el in self.decays.iter_mut() {
1053 *el = i32::from(br.read_u16le()? as i16);
1055 for el in self.base_filt.iter_mut() {
1056 *el = br.read_u32le()? as i32;
1058 self.base_scale = br.read_u32le()? as i32;
1061 fn unpack_data(&mut self, br: &mut ByteReader, val: u16, dst: &mut [i32]) -> DecoderResult<()> {
1062 self.lpc0_idx = (val & 0x3F) as usize;
1063 self.scale = (self.decays[((val >> 6) & 7) as usize] * self.scale) >> 13;
1064 let val1 = br.read_u16le()?;
1065 self.lpc1_idx = ((val1 >> 6) & 0x3F) as usize;
1066 self.lpc2_idx = (val1 & 0x3F) as usize;
1067 self.frame_mode = ((val1 >> 12) & 3) as usize;
1068 let mut idx = (val1 >> 14) as usize;
1069 if self.frame_mode == 0 {
1072 let val = br.read_u16le()?;
1074 let add = i32::from((val >> (13 - i * 3)) & 7);
1075 dst[idx] += self.scale * (add * 2 - 7);
1078 tail = tail * 2 + (val & 1);
1080 let add = i32::from((tail >> 5) & 7);
1081 dst[idx] += self.scale * (add * 2 - 7);
1083 let add = i32::from((tail >> 2) & 7);
1084 dst[idx] += self.scale * (add * 2 - 7);
1086 let (len, step) = match self.frame_mode {
1090 _ => unreachable!(),
1094 let val = br.read_u16le()?;
1096 let add = i32::from((val >> (14 - i * 2)) & 3);
1097 dst[idx] += self.scale * (add * 2 - 3);
1104 fn update_intra(&mut self) {
1105 self.cur_filt = self.base_filt;
1107 self.cur_filt[i] += i32::from(self.lpc0_cb[self.lpc0_idx][i]);
1108 self.cur_filt[i] += i32::from(self.lpc1_cb[self.lpc1_idx][i]);
1109 self.cur_filt[i] += i32::from(self.lpc2_cb[self.lpc2_idx][i]);
1112 fn update_inter(&mut self) {
1114 self.cur_filt[i] += i32::from(self.lpc0_cb[self.lpc0_idx][i]);
1115 self.cur_filt[i] += i32::from(self.lpc1_cb[self.lpc1_idx][i]);
1116 self.cur_filt[i] += i32::from(self.lpc2_cb[self.lpc2_idx][i]);
1121 fn apply_lpc(dst: &mut [i32], src: &[i32], hist: &mut [i32], filt: &[i32; 8]) {
1122 for (hidx, (out, src)) in dst.iter_mut().zip(src.iter()).enumerate() {
1123 let mut sum = *src << 14;
1125 sum += hist[(hidx + i) & 7] * filt[i];
1127 let samp = sum >> 14;
1129 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 test_decoding("vx", "vxvideo", "assets/Game/bioware.vx", Some(31), &dmx_reg, &dec_reg,
1335 ExpectedTestResult::MD5Frames(vec![
1336 [0x33de14fa, 0x00948eb7, 0x028141d7, 0x1d07abd6],
1337 [0x77a96135, 0x0cc2d0b5, 0x45862c7c, 0xe27f5b10],
1338 [0x3c3ed089, 0x3c643216, 0xe6aed381, 0x4d43c50f],
1339 [0x09e86330, 0x37d3a766, 0xa8198ac5, 0x21fa089c],
1340 [0xbcab34d7, 0xdffe234a, 0x6534709f, 0xc3050e32],
1341 [0x2bab595d, 0x7a19937e, 0xccc97277, 0x91b32191],
1342 [0xe082f77e, 0x6498fd0d, 0xa3828c0f, 0xb4f7a02a],
1343 [0x8515f6e2, 0xc0cb8ab3, 0xf91a3483, 0xd54470fc],
1344 [0x17b1b54a, 0x1b574323, 0xcdeec1ec, 0x7a00ae4e],
1345 [0x773f1d47, 0x86188681, 0xb111bcb8, 0x80fe34e9],
1346 [0xbc4a8e20, 0xca91d4b6, 0x7275a162, 0x9a73be7c],
1347 [0x0d4992b5, 0xd12a985a, 0x929ebec2, 0x0653fbc7],
1348 [0xc24691b7, 0xabd27a7a, 0xd62cbd73, 0xd72a49ea],
1349 [0x9024f7f4, 0xbe707e73, 0x27b4b4a0, 0x33bb515e],
1350 [0x31aee8fc, 0xd0a3fa6d, 0xea11ef6a, 0x53a5f031],
1351 [0x4a83f326, 0xceff4329, 0x54fbe91e, 0xf98ee74b],
1352 [0xe54b5450, 0x979f4b26, 0x910ee666, 0x05fd1996],
1353 [0xe48d66d0, 0x0a69b963, 0x9917084e, 0xf4b0486d],
1354 [0x624a8b32, 0x0d1ce036, 0x9de8ebf0, 0x472a77b9],
1355 [0x5d307d48, 0x1168f3a9, 0xaa792fb2, 0x34430b20],
1356 [0xf2d80474, 0xac6b0972, 0x500e569e, 0x3c8e7dde],
1357 [0x481310b3, 0x70cdeb91, 0xed007972, 0x70cefff3],
1358 [0x8b5b17ca, 0xca6f9a72, 0x0256908a, 0x4505cf85],
1359 [0xb6222c1d, 0x7a9760cb, 0xb3276304, 0x2ff1595e],
1360 [0xf98e3d89, 0xae957c83, 0xff849c05, 0x8ca54276],
1361 [0xbcebda1c, 0x6f6e4ac6, 0x023e7f0f, 0x9578142f],
1362 [0x399f5155, 0xd95b33e3, 0xf0b55af8, 0xe32db6b2],
1363 [0x0c4d4347, 0x5f5061e4, 0xe2fa4690, 0xa340d294],
1364 [0x6fcdddb5, 0xf101da80, 0x6f55ddd9, 0x0dfeead1],
1365 [0xb9623043, 0x1dab8a93, 0x22fd5f7a, 0x2c2a6633],
1366 [0xb3ac2652, 0xf474e49d, 0x7db51405, 0xcd1c13cc],
1367 [0x6a901339, 0xda88b2be, 0x6d943e18, 0xda9b5926]]));
1371 const NC_MAP: [usize; 8] = [ 0, 0, 1, 1, 2, 2, 2, 2 ];
1372 const NC_BITS: [[u16; 68]; 3] = [
1374 0x0001, 0x0000, 0x0000, 0x0000, 0x0005, 0x0001, 0x0000, 0x0000,
1375 0x0007, 0x0004, 0x0001, 0x0000, 0x0007, 0x0006, 0x0005, 0x0003,
1376 0x0007, 0x0006, 0x0005, 0x0003, 0x0007, 0x0006, 0x0005, 0x0004,
1377 0x000F, 0x0006, 0x0005, 0x0004, 0x000B, 0x000E, 0x0005, 0x0004,
1378 0x0008, 0x000A, 0x000D, 0x0004, 0x000F, 0x000E, 0x0009, 0x0004,
1379 0x000B, 0x000A, 0x000D, 0x000C, 0x000F, 0x000E, 0x0009, 0x000C,
1380 0x000B, 0x000A, 0x000D, 0x0008, 0x000F, 0x0001, 0x0009, 0x000C,
1381 0x000B, 0x000E, 0x000D, 0x0008, 0x0007, 0x000A, 0x0009, 0x000C,
1382 0x0004, 0x0006, 0x0005, 0x0008
1384 0x0003, 0x0000, 0x0000, 0x0000, 0x000B, 0x0002, 0x0000, 0x0000,
1385 0x0007, 0x0007, 0x0003, 0x0000, 0x0007, 0x000A, 0x0009, 0x0005,
1386 0x0007, 0x0006, 0x0005, 0x0004, 0x0004, 0x0006, 0x0005, 0x0006,
1387 0x0007, 0x0006, 0x0005, 0x0008, 0x000F, 0x0006, 0x0005, 0x0004,
1388 0x000B, 0x000E, 0x000D, 0x0004, 0x000F, 0x000A, 0x0009, 0x0004,
1389 0x000B, 0x000E, 0x000D, 0x000C, 0x0008, 0x000A, 0x0009, 0x0008,
1390 0x000F, 0x000E, 0x000D, 0x000C, 0x000B, 0x000A, 0x0009, 0x000C,
1391 0x0007, 0x000B, 0x0006, 0x0008, 0x0009, 0x0008, 0x000A, 0x0001,
1392 0x0007, 0x0006, 0x0005, 0x0004
1394 0x000F, 0x0000, 0x0000, 0x0000, 0x000F, 0x000E, 0x0000, 0x0000,
1395 0x000B, 0x000F, 0x000D, 0x0000, 0x0008, 0x000C, 0x000E, 0x000C,
1396 0x000F, 0x000A, 0x000B, 0x000B, 0x000B, 0x0008, 0x0009, 0x000A,
1397 0x0009, 0x000E, 0x000D, 0x0009, 0x0008, 0x000A, 0x0009, 0x0008,
1398 0x000F, 0x000E, 0x000D, 0x000D, 0x000B, 0x000E, 0x000A, 0x000C,
1399 0x000F, 0x000A, 0x000D, 0x000C, 0x000B, 0x000E, 0x0009, 0x000C,
1400 0x0008, 0x000A, 0x000D, 0x0008, 0x000D, 0x0007, 0x0009, 0x000C,
1401 0x0009, 0x000C, 0x000B, 0x000A, 0x0005, 0x0008, 0x0007, 0x0006,
1402 0x0001, 0x0004, 0x0003, 0x0002
1405 const NC_LENS: [[u8; 68]; 3] = [
1407 1, 0, 0, 0, 6, 2, 0, 0,
1408 8, 6, 3, 0, 9, 8, 7, 5,
1409 10, 9, 8, 6, 11, 10, 9, 7,
1410 13, 11, 10, 8, 13, 13, 11, 9,
1411 13, 13, 13, 10, 14, 14, 13, 11,
1412 14, 14, 14, 13, 15, 15, 14, 14,
1413 15, 15, 15, 14, 16, 15, 15, 15,
1414 16, 16, 16, 15, 16, 16, 16, 16,
1417 2, 0, 0, 0, 6, 2, 0, 0,
1418 6, 5, 3, 0, 7, 6, 6, 4,
1419 8, 6, 6, 4, 8, 7, 7, 5,
1420 9, 8, 8, 6, 11, 9, 9, 6,
1421 11, 11, 11, 7, 12, 11, 11, 9,
1422 12, 12, 12, 11, 12, 12, 12, 11,
1423 13, 13, 13, 12, 13, 13, 13, 13,
1424 13, 14, 13, 13, 14, 14, 14, 13,
1427 4, 0, 0, 0, 6, 4, 0, 0,
1428 6, 5, 4, 0, 6, 5, 5, 4,
1429 7, 5, 5, 4, 7, 5, 5, 4,
1430 7, 6, 6, 4, 7, 6, 6, 4,
1431 8, 7, 7, 5, 8, 8, 7, 6,
1432 9, 8, 8, 7, 9, 9, 8, 8,
1433 9, 9, 9, 8, 10, 9, 9, 9,
1434 10, 10, 10, 10, 10, 10, 10, 10,
1439 const NUM_ZERO_BITS: [[u8; 16]; 15] = [
1441 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01
1443 0x07, 0x06, 0x05, 0x04, 0x03, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01, 0x00, 0x00
1445 0x05, 0x07, 0x06, 0x05, 0x04, 0x03, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00
1447 0x03, 0x07, 0x05, 0x04, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00
1449 0x05, 0x04, 0x03, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
1451 0x01, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1453 0x01, 0x01, 0x05, 0x04, 0x03, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1455 0x01, 0x01, 0x01, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1457 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1459 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1461 0x00, 0x01, 0x01, 0x02, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1463 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1465 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1467 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1469 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1472 const NUM_ZERO_LENS: [[u8; 16]; 15] = [
1473 [ 1, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 ],
1474 [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 0 ],
1475 [ 4, 3, 3, 3, 4, 4, 3, 3, 4, 5, 5, 6, 5, 6, 0, 0 ],
1476 [ 5, 3, 4, 4, 3, 3, 3, 4, 3, 4, 5, 5, 5, 0, 0, 0 ],
1477 [ 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 4, 5, 0, 0, 0, 0 ],
1478 [ 6, 5, 3, 3, 3, 3, 3, 3, 4, 3, 6, 0, 0, 0, 0, 0 ],
1479 [ 6, 5, 3, 3, 3, 2, 3, 4, 3, 6, 0, 0, 0, 0, 0, 0 ],
1480 [ 6, 4, 5, 3, 2, 2, 3, 3, 6, 0, 0, 0, 0, 0, 0, 0 ],
1481 [ 6, 6, 4, 2, 2, 3, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 ],
1482 [ 5, 5, 3, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1483 [ 4, 4, 3, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1484 [ 4, 4, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1485 [ 3, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1486 [ 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1487 [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
1490 const ZERO_RUN_BITS: [[u8; 8]; 6] = [
1491 [ 1, 0, 0, 0, 0, 0, 0, 0 ],
1492 [ 1, 1, 0, 0, 0, 0, 0, 0 ],
1493 [ 3, 2, 1, 0, 0, 0, 0, 0 ],
1494 [ 3, 2, 1, 1, 0, 0, 0, 0 ],
1495 [ 3, 2, 3, 2, 1, 0, 0, 0 ],
1496 [ 3, 0, 1, 3, 2, 5, 4, 0 ]
1498 const ZERO_RUN_LENS: [[u8; 8]; 6] = [
1499 [ 1, 1, 0, 0, 0, 0, 0, 0 ],
1500 [ 1, 2, 2, 0, 0, 0, 0, 0 ],
1501 [ 2, 2, 2, 2, 0, 0, 0, 0 ],
1502 [ 2, 2, 2, 3, 3, 0, 0, 0 ],
1503 [ 2, 2, 3, 3, 3, 3, 0, 0 ],
1504 [ 2, 3, 3, 3, 3, 3, 3, 0 ]