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]) {
1123 for (out, src) in dst.iter_mut().zip(src.iter()) {
1124 let mut sum = *src << 14;
1126 sum += hist[(hidx + i) & 7] * filt[i];
1128 let samp = sum >> 14;
1130 hist[hidx & 7] = samp;
1135 struct VXAudioDecoder {
1137 info: Arc<NACodecInfo>,
1138 chmap: NAChannelMap,
1139 buf: [i32; 256 * 2],
1144 lpc_filt1: [i32; 8],
1147 impl VXAudioDecoder {
1150 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
1151 info: NACodecInfo::new_dummy(),
1152 chmap: NAChannelMap::new(),
1155 state: AudioState::new(),
1161 fn decode_inter(&mut self, br: &mut ByteReader, mode: u16, val: u16) -> DecoderResult<()> {
1162 let (mut cur_buf, mut prev_buf) = self.buf.split_at_mut(256);
1164 std::mem::swap(&mut cur_buf, &mut prev_buf);
1166 cur_buf[0..128].copy_from_slice(&prev_buf[128..]);
1168 for el in cur_buf[128..].iter_mut() {
1172 let src = &prev_buf[127 - (mode as usize)..];
1173 let dst = &mut cur_buf[128..];
1175 dst[i] = (src[i] * ((i + 1) as i32)) >> 4;
1178 dst[i] = src[i] >> 1;
1181 dst[i] = (src[i] * ((128 - i) as i32)) >> 4;
1185 self.state.unpack_data(br, val, prev_buf )?;
1186 self.state.update_inter();
1188 let (cfilt, pfilt) = if !self.flip_buf {
1189 (&mut self.lpc_filt, &mut self.lpc_filt1)
1191 (&mut self.lpc_filt1, &mut self.lpc_filt)
1193 *cfilt = self.state.cur_filt;
1194 let mut f0 = [0; 8];
1195 let mut f1 = [0; 8];
1196 let mut f2 = [0; 8];
1198 f1[i] = (pfilt[i] + cfilt[i]) >> 1;
1199 f0[i] = (pfilt[i] + f1 [i]) >> 1;
1200 f2[i] = (f1 [i] + cfilt[i]) >> 1;
1202 apply_lpc(&mut cur_buf[ 0..][..32], &prev_buf[128..], &mut self.lpc_hist, &f0);
1203 apply_lpc(&mut cur_buf[32..][..32], &prev_buf[128 + 32..], &mut self.lpc_hist, &f1);
1204 apply_lpc(&mut cur_buf[64..][..32], &prev_buf[128 + 64..], &mut self.lpc_hist, &f2);
1205 apply_lpc(&mut cur_buf[96..][..32], &prev_buf[128 + 96..], &mut self.lpc_hist, &cfilt);
1208 fn decode_intra(&mut self, br: &mut ByteReader, val: u16) -> DecoderResult<()> {
1209 self.state.scale = self.state.base_scale;
1210 self.lpc_hist = [0; 8];
1211 self.flip_buf = true;
1213 let (mut cur_buf, mut prev_buf) = self.buf.split_at_mut(256);
1215 std::mem::swap(&mut cur_buf, &mut prev_buf);
1217 for el in cur_buf[128..].iter_mut() {
1220 self.state.unpack_data(br, val, prev_buf)?;
1221 self.state.update_intra();
1223 self.lpc_filt = self.state.cur_filt;
1224 apply_lpc(&mut cur_buf[..128], &prev_buf[128..], &mut self.lpc_hist, &self.lpc_filt);
1227 fn output(&mut self, dst: &mut [i16]) {
1228 let src = if self.flip_buf { &self.buf[256..][..128] } else { &self.buf[..128] };
1229 for (src, dst) in src.iter().zip(dst.iter_mut()) {
1230 *dst = (*src).max(-0x8000).min(0x7FFF) as i16;
1232 self.flip_buf = !self.flip_buf;
1236 impl NADecoder for VXAudioDecoder {
1237 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
1238 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
1239 if let Some(edata) = info.get_extradata() {
1240 validate!(edata.len() >= 3124);
1241 let mut mr = MemoryReader::new_read(edata.as_slice());
1242 let mut br = ByteReader::new(&mut mr);
1243 self.state.read_initial_params(&mut br)?;
1245 return Err(DecoderError::InvalidData);
1247 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), 1, SND_S16_FORMAT, 1);
1248 self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo));
1249 self.chmap = NAChannelMap::from_str("C").unwrap();
1252 Err(DecoderError::InvalidData)
1255 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
1256 const SUBFRAME_LEN: [usize; 4] = [20, 14, 12, 10];
1258 let info = pkt.get_stream().get_info();
1259 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
1260 let pktbuf = pkt.get_buffer();
1261 validate!(pktbuf.len() >= 10);
1263 let mut mr = MemoryReader::new_read(&pktbuf);
1264 let mut br = ByteReader::new(&mut mr);
1265 let mut nblocks = 0;
1266 while br.left() > 4 {
1268 let val = br.read_u16le()?;
1270 let sf_len = SUBFRAME_LEN[((val >> 12) & 3) as usize];
1271 if br.left() <= sf_len as i64 {
1274 br.read_skip(sf_len - 4)?;
1277 let samples = 128 * nblocks;
1278 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
1279 let mut adata = abuf.get_abuf_i16().unwrap();
1280 let dst = adata.get_data_mut().unwrap();
1282 let mut mr = MemoryReader::new_read(&pktbuf);
1283 let mut br = ByteReader::new(&mut mr);
1285 let mut blk_no = 0usize;
1286 while br.left() > 0 {
1287 let val = br.read_u16le()?;
1288 let mode = val >> 9;
1290 self.decode_intra(&mut br, val)?;
1292 self.decode_inter(&mut br, val & 0x1FF, mode)?;
1294 self.output(&mut dst[blk_no * 128..]);
1298 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf);
1299 frm.set_duration(Some(samples as u64));
1300 frm.set_keyframe(true);
1303 Err(DecoderError::InvalidData)
1306 fn flush(&mut self) {
1311 impl NAOptionHandler for VXAudioDecoder {
1312 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
1313 fn set_options(&mut self, _options: &[NAOption]) { }
1314 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
1318 pub fn get_decoder_audio() -> Box<dyn NADecoder + Send> {
1319 Box::new(VXAudioDecoder::new())
1324 use nihav_core::codecs::RegisteredDecoders;
1325 use nihav_core::demuxers::RegisteredDemuxers;
1326 use nihav_codec_support::test::dec_video::*;
1327 use crate::game_register_all_decoders;
1328 use crate::game_register_all_demuxers;
1330 fn test_vx_video() {
1331 let mut dmx_reg = RegisteredDemuxers::new();
1332 game_register_all_demuxers(&mut dmx_reg);
1333 let mut dec_reg = RegisteredDecoders::new();
1334 game_register_all_decoders(&mut dec_reg);
1336 //XXX: the current version does not reconstruct videos perfectly yet
1337 test_decoding("vx", "vxvideo", "assets/Game/bioware.vx", Some(31), &dmx_reg, &dec_reg,
1338 ExpectedTestResult::MD5Frames(vec![
1339 [0x33de14fa, 0x00948eb7, 0x028141d7, 0x1d07abd6],
1340 [0x07442eef, 0x36ec00c1, 0x3d9556c6, 0x6ddbcd46],
1341 [0xb5b48d03, 0x0063faaf, 0xfa64de6f, 0xbe5d916b],
1342 [0xb760b777, 0xe7159f5e, 0x352b7326, 0xd21e3d14],
1343 [0xee1ccadc, 0xd2b54891, 0xb5f6f31a, 0x73d7e869],
1344 [0xcd234bd9, 0xad3d8f3e, 0xdb405b8c, 0x4faa738b],
1345 [0x615957be, 0x8a20b367, 0xadc031af, 0x886311cc],
1346 [0xade60b19, 0x2560fffa, 0x8bafff67, 0x698485ad],
1347 [0x131b874c, 0x4bb41da5, 0xc0f52bf2, 0x626d6e66],
1348 [0x1dc1bb4b, 0xc3552467, 0xa5598162, 0xe6220dde],
1349 [0xa1e27935, 0xd01c18c4, 0x6e6e1be7, 0xc42b021c],
1350 [0x28876ccb, 0xfaca435f, 0xe8cf81d7, 0x8f103d89],
1351 [0xab610d4d, 0x0bf5b213, 0x28749eda, 0xcbf5c34c],
1352 [0x48a452f8, 0x544b8a4d, 0x0a031be4, 0xe60b6f59],
1353 [0xe6f88898, 0x46171e3b, 0xf39e2605, 0x3d16e75a],
1354 [0xe1461669, 0x3dd4daa6, 0x1e82b9e7, 0x49214174],
1355 [0x39d89d57, 0x5c0bf9ba, 0xf254cdc4, 0x8c1b9bb9],
1356 [0x81f1a684, 0xd2a0bc8a, 0xe1355afa, 0xbe33e476],
1357 [0x571b0722, 0x25643452, 0x509ed72d, 0x1d55214e],
1358 [0xc799fa72, 0xed2bc13d, 0xa9be1b55, 0xece4d7f0],
1359 [0x0eae7358, 0x87d80481, 0xcac84bf9, 0x76bee392],
1360 [0xf0e6fb26, 0x95a9a362, 0x474edaa2, 0xd8d0b5fc],
1361 [0xee57bff2, 0x490b9ffc, 0x6189e2d4, 0xb1b97277],
1362 [0xa5f83723, 0xaa807527, 0x5c722b29, 0x3ea10cfc],
1363 [0x83562752, 0x27021714, 0x5b81f808, 0x192fa17c],
1364 [0x50f5ab82, 0x01a482b2, 0xa44b7525, 0xac4d1916],
1365 [0x8cf1fffd, 0xf09364c5, 0x57847078, 0x1a811a61],
1366 [0x3d8e4221, 0xe69532b1, 0x7bd4fa20, 0x78dc0676],
1367 [0x7b6432a5, 0x01ee9819, 0xfd0fd634, 0x96fd612b],
1368 [0xb0e0d469, 0xc651dd3a, 0xf2fa8e9b, 0xc58d55be],
1369 [0xa9d7fa17, 0xaf2d05f8, 0xd307d0c1, 0xd83dc57a],
1370 [0x14e644a7, 0xd8d9e459, 0x0d81e68c, 0xe57b9b81]]));
1374 const NC_MAP: [usize; 8] = [ 0, 0, 1, 1, 2, 2, 2, 2 ];
1375 const NC_BITS: [[u16; 68]; 3] = [
1377 0x0001, 0x0000, 0x0000, 0x0000, 0x0005, 0x0001, 0x0000, 0x0000,
1378 0x0007, 0x0004, 0x0001, 0x0000, 0x0007, 0x0006, 0x0005, 0x0003,
1379 0x0007, 0x0006, 0x0005, 0x0003, 0x0007, 0x0006, 0x0005, 0x0004,
1380 0x000F, 0x0006, 0x0005, 0x0004, 0x000B, 0x000E, 0x0005, 0x0004,
1381 0x0008, 0x000A, 0x000D, 0x0004, 0x000F, 0x000E, 0x0009, 0x0004,
1382 0x000B, 0x000A, 0x000D, 0x000C, 0x000F, 0x000E, 0x0009, 0x000C,
1383 0x000B, 0x000A, 0x000D, 0x0008, 0x000F, 0x0001, 0x0009, 0x000C,
1384 0x000B, 0x000E, 0x000D, 0x0008, 0x0007, 0x000A, 0x0009, 0x000C,
1385 0x0004, 0x0006, 0x0005, 0x0008
1387 0x0003, 0x0000, 0x0000, 0x0000, 0x000B, 0x0002, 0x0000, 0x0000,
1388 0x0007, 0x0007, 0x0003, 0x0000, 0x0007, 0x000A, 0x0009, 0x0005,
1389 0x0007, 0x0006, 0x0005, 0x0004, 0x0004, 0x0006, 0x0005, 0x0006,
1390 0x0007, 0x0006, 0x0005, 0x0008, 0x000F, 0x0006, 0x0005, 0x0004,
1391 0x000B, 0x000E, 0x000D, 0x0004, 0x000F, 0x000A, 0x0009, 0x0004,
1392 0x000B, 0x000E, 0x000D, 0x000C, 0x0008, 0x000A, 0x0009, 0x0008,
1393 0x000F, 0x000E, 0x000D, 0x000C, 0x000B, 0x000A, 0x0009, 0x000C,
1394 0x0007, 0x000B, 0x0006, 0x0008, 0x0009, 0x0008, 0x000A, 0x0001,
1395 0x0007, 0x0006, 0x0005, 0x0004
1397 0x000F, 0x0000, 0x0000, 0x0000, 0x000F, 0x000E, 0x0000, 0x0000,
1398 0x000B, 0x000F, 0x000D, 0x0000, 0x0008, 0x000C, 0x000E, 0x000C,
1399 0x000F, 0x000A, 0x000B, 0x000B, 0x000B, 0x0008, 0x0009, 0x000A,
1400 0x0009, 0x000E, 0x000D, 0x0009, 0x0008, 0x000A, 0x0009, 0x0008,
1401 0x000F, 0x000E, 0x000D, 0x000D, 0x000B, 0x000E, 0x000A, 0x000C,
1402 0x000F, 0x000A, 0x000D, 0x000C, 0x000B, 0x000E, 0x0009, 0x000C,
1403 0x0008, 0x000A, 0x000D, 0x0008, 0x000D, 0x0007, 0x0009, 0x000C,
1404 0x0009, 0x000C, 0x000B, 0x000A, 0x0005, 0x0008, 0x0007, 0x0006,
1405 0x0001, 0x0004, 0x0003, 0x0002
1408 const NC_LENS: [[u8; 68]; 3] = [
1410 1, 0, 0, 0, 6, 2, 0, 0,
1411 8, 6, 3, 0, 9, 8, 7, 5,
1412 10, 9, 8, 6, 11, 10, 9, 7,
1413 13, 11, 10, 8, 13, 13, 11, 9,
1414 13, 13, 13, 10, 14, 14, 13, 11,
1415 14, 14, 14, 13, 15, 15, 14, 14,
1416 15, 15, 15, 14, 16, 15, 15, 15,
1417 16, 16, 16, 15, 16, 16, 16, 16,
1420 2, 0, 0, 0, 6, 2, 0, 0,
1421 6, 5, 3, 0, 7, 6, 6, 4,
1422 8, 6, 6, 4, 8, 7, 7, 5,
1423 9, 8, 8, 6, 11, 9, 9, 6,
1424 11, 11, 11, 7, 12, 11, 11, 9,
1425 12, 12, 12, 11, 12, 12, 12, 11,
1426 13, 13, 13, 12, 13, 13, 13, 13,
1427 13, 14, 13, 13, 14, 14, 14, 13,
1430 4, 0, 0, 0, 6, 4, 0, 0,
1431 6, 5, 4, 0, 6, 5, 5, 4,
1432 7, 5, 5, 4, 7, 5, 5, 4,
1433 7, 6, 6, 4, 7, 6, 6, 4,
1434 8, 7, 7, 5, 8, 8, 7, 6,
1435 9, 8, 8, 7, 9, 9, 8, 8,
1436 9, 9, 9, 8, 10, 9, 9, 9,
1437 10, 10, 10, 10, 10, 10, 10, 10,
1442 const NUM_ZERO_BITS: [[u8; 16]; 15] = [
1444 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01
1446 0x07, 0x06, 0x05, 0x04, 0x03, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01, 0x00, 0x00
1448 0x05, 0x07, 0x06, 0x05, 0x04, 0x03, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00
1450 0x03, 0x07, 0x05, 0x04, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00
1452 0x05, 0x04, 0x03, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
1454 0x01, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1456 0x01, 0x01, 0x05, 0x04, 0x03, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1458 0x01, 0x01, 0x01, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1460 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1462 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1464 0x00, 0x01, 0x01, 0x02, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1466 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1468 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1470 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1472 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1475 const NUM_ZERO_LENS: [[u8; 16]; 15] = [
1476 [ 1, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 ],
1477 [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 0 ],
1478 [ 4, 3, 3, 3, 4, 4, 3, 3, 4, 5, 5, 6, 5, 6, 0, 0 ],
1479 [ 5, 3, 4, 4, 3, 3, 3, 4, 3, 4, 5, 5, 5, 0, 0, 0 ],
1480 [ 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 4, 5, 0, 0, 0, 0 ],
1481 [ 6, 5, 3, 3, 3, 3, 3, 3, 4, 3, 6, 0, 0, 0, 0, 0 ],
1482 [ 6, 5, 3, 3, 3, 2, 3, 4, 3, 6, 0, 0, 0, 0, 0, 0 ],
1483 [ 6, 4, 5, 3, 2, 2, 3, 3, 6, 0, 0, 0, 0, 0, 0, 0 ],
1484 [ 6, 6, 4, 2, 2, 3, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 ],
1485 [ 5, 5, 3, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1486 [ 4, 4, 3, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1487 [ 4, 4, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1488 [ 3, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1489 [ 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1490 [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
1493 const ZERO_RUN_BITS: [[u8; 8]; 6] = [
1494 [ 1, 0, 0, 0, 0, 0, 0, 0 ],
1495 [ 1, 1, 0, 0, 0, 0, 0, 0 ],
1496 [ 3, 2, 1, 0, 0, 0, 0, 0 ],
1497 [ 3, 2, 1, 1, 0, 0, 0, 0 ],
1498 [ 3, 2, 3, 2, 1, 0, 0, 0 ],
1499 [ 3, 0, 1, 3, 2, 5, 4, 0 ]
1501 const ZERO_RUN_LENS: [[u8; 8]; 6] = [
1502 [ 1, 1, 0, 0, 0, 0, 0, 0 ],
1503 [ 1, 2, 2, 0, 0, 0, 0, 0 ],
1504 [ 2, 2, 2, 2, 0, 0, 0, 0 ],
1505 [ 2, 2, 2, 3, 3, 0, 0, 0 ],
1506 [ 2, 2, 3, 3, 3, 3, 0, 0 ],
1507 [ 2, 3, 3, 3, 3, 3, 3, 0 ]