add LinePack decoder
[nihav.git] / nihav-game / src / codecs / midivid3.rs
CommitLineData
f42a4a86
KS
1use nihav_core::codecs::*;
2use nihav_core::io::byteio::*;
3use nihav_core::io::bitreader::*;
4use nihav_core::io::codebook::*;
5use nihav_codec_support::codecs::IPShuffler;
6
7const COEFFS_PER_BLOCK: [usize; 4] = [0, 1, 4, 64];
8
9struct BlockTypeReader<'a> {
10 src: &'a [u8],
11 pos: usize,
12 bpos: usize,
13}
14
15impl<'a> BlockTypeReader<'a> {
16 fn read_block_type(&mut self) -> DecoderResult<usize> {
17 if self.pos >= self.src.len() {
18 return Err(DecoderError::ShortData);
19 }
20 let btype = (self.src[self.pos] >> self.bpos) & 3;
21 self.bpos += 2;
22 if self.bpos == 8 {
23 self.bpos = 0;
24 self.pos += 1;
25 }
26 Ok(btype as usize)
27 }
28}
29
30struct MaskReader<'a> {
31 src: &'a [u8],
32 pos: usize,
33 bpos: usize,
34}
35
36impl<'a> MaskReader<'a> {
37 fn read_type(&mut self) -> DecoderResult<(bool, bool)> {
38 if self.pos >= self.src.len() {
39 return Err(DecoderError::ShortData);
40 }
41 let is_intra = ((self.src[self.pos] >> self.bpos) & 1) == 0;
42 let has_residue = ((self.src[self.pos] >> (self.bpos + 4)) & 1) == 0;
43 self.bpos += 1;
44 if self.bpos == 4 {
45 self.bpos = 0;
46 self.pos += 1;
47 }
48 Ok((is_intra, has_residue))
49 }
50}
51
52struct Midivid3Decoder {
53 info: NACodecInfoRef,
54 shuf: IPShuffler,
55 cb: Codebook<u32>,
56 width: usize,
57 height: usize,
58 num_mbs: usize,
59 coeffs: [i16; 65536],
60 mvs: Vec<i16>,
61 qmat_y_intra: [i16; 64],
62 qmat_c_intra: [i16; 64],
63 qmat_y_inter: [i16; 64],
64 qmat_c_inter: [i16; 64],
65}
66
67impl Midivid3Decoder {
68 fn new() -> Self {
69 let mut cr = ShortCodebookDescReader::new(vec![
70 ShortCodebookDesc { code: 0b00, bits: 2 },
71 ShortCodebookDesc { code: 0b01, bits: 2 },
72 ShortCodebookDesc { code: 0b100, bits: 3 },
73 ShortCodebookDesc { code: 0b101, bits: 3 },
74 ShortCodebookDesc { code: 0b110, bits: 3 },
75 ShortCodebookDesc { code: 0b1110, bits: 4 },
76 ShortCodebookDesc { code: 0b11110, bits: 5 },
77 ShortCodebookDesc { code: 0b111110, bits: 6 },
78 ShortCodebookDesc { code: 0b1111110, bits: 7 },
79 ShortCodebookDesc { code: 0b11111110, bits: 8 },
80 ShortCodebookDesc { code: 0b111111110, bits: 9 },
81 ShortCodebookDesc { code: 0b111111111, bits: 9 }
82 ]);
83 let cb = Codebook::new(&mut cr, CodebookMode::MSB).unwrap();
84 Midivid3Decoder {
85 info: NACodecInfoRef::default(),
86 shuf: IPShuffler::default(),
87 cb,
88 width: 0, height: 0, num_mbs: 0,
89 coeffs: [0; 65536],
90 mvs: Vec::new(),
91 qmat_y_intra: [0; 64],
92 qmat_c_intra: [0; 64],
93 qmat_y_inter: [0; 64],
94 qmat_c_inter: [0; 64],
95 }
96 }
97 fn decode_intra(&mut self, frm: &mut NASimpleVideoFrame<u8>, bt_reader: &mut BlockTypeReader, br: &mut BitReader) -> DecoderResult<()> {
98 let mut ydst = frm.offset[0];
99 let mut udst = frm.offset[1];
100 let mut vdst = frm.offset[2];
101 for _y in (0..self.height).step_by(16) {
102 let mut ydc = 0;
103 let mut udc = 0;
104 let mut vdc = 0;
105 let ncoeffs = br.read(16)? as usize;
106 decode_values(br, &mut self.coeffs[..ncoeffs], &self.cb)?;
107 let mut cpos = 0;
108 for x in (0..self.width).step_by(16) {
109 for blk in 0..4 {
110 let btype = bt_reader.read_block_type()?;
111 let nc = COEFFS_PER_BLOCK[btype];
112 validate!(cpos + nc <= ncoeffs);
113 let cur_off = x + (blk & 1) * 8 + (blk & 2) * 4 * frm.stride[0];
114 if btype != 0 {
115 self.coeffs[cpos] += ydc;
116 ydc = self.coeffs[cpos];
117 }
118 decode_block_intra(&mut frm.data[ydst + cur_off..], frm.stride[0], btype, &self.coeffs[cpos..], &self.qmat_y_intra);
119 cpos += nc;
120 }
121 let btype = bt_reader.read_block_type()?;
122 let nc = COEFFS_PER_BLOCK[btype];
123 validate!(cpos + nc <= ncoeffs);
124 if btype != 0 {
125 self.coeffs[cpos] += udc;
126 udc = self.coeffs[cpos];
127 }
128 decode_block_intra(&mut frm.data[udst + x / 2..], frm.stride[1], btype, &self.coeffs[cpos..], &self.qmat_c_intra);
129 cpos += nc;
130 let btype = bt_reader.read_block_type()?;
131 let nc = COEFFS_PER_BLOCK[btype];
132 validate!(cpos + nc <= ncoeffs);
133 if btype != 0 {
134 self.coeffs[cpos] += vdc;
135 vdc = self.coeffs[cpos];
136 }
137 decode_block_intra(&mut frm.data[vdst + x / 2..], frm.stride[2], btype, &self.coeffs[cpos..], &self.qmat_c_intra);
138 cpos += nc;
139 }
140 ydst += frm.stride[0] * 16;
141 udst += frm.stride[1] * 8;
142 vdst += frm.stride[2] * 8;
143 }
144 Ok(())
145 }
146 fn decode_inter(&mut self, frm: &mut NASimpleVideoFrame<u8>, mask_reader: &mut MaskReader, bt_reader: &mut BlockTypeReader, br: &mut BitReader, num_mvs: usize) -> DecoderResult<()> {
147 let ref_frm = self.shuf.get_ref();
148 if ref_frm.is_none() {
149 return Err(DecoderError::MissingReference);
150 }
151 let ref_frm = ref_frm.unwrap();
152
153 decode_values(br, &mut self.mvs[..num_mvs * 2], &self.cb)?;
154
155 let mut ydst = frm.offset[0];
156 let mut udst = frm.offset[1];
157 let mut vdst = frm.offset[2];
158 let mut cur_mv = 0;
159 for y in (0..self.height).step_by(16) {
160 let mut ydc = 0;
161 let mut udc = 0;
162 let mut vdc = 0;
163 let ncoeffs = br.read(16)? as usize;
164 let pred_mbs = br.read(8)? as usize;
165 decode_values(br, &mut self.coeffs[..ncoeffs], &self.cb)?;
166 let mut cpos = 0;
167 let mut cur_mb = 0;
168 for x in (0..self.width).step_by(16) {
169 let (is_intra, has_residue) = mask_reader.read_type()?;
170 if is_intra {
171 for blk in 0..4 {
172 let btype = bt_reader.read_block_type()?;
173 let nc = COEFFS_PER_BLOCK[btype];
174 validate!(cpos + nc <= ncoeffs);
175 if (btype != 0) && (cur_mb < pred_mbs) {
176 self.coeffs[cpos] += ydc;
177 ydc = self.coeffs[cpos];
178 }
179 let cur_off = x + (blk & 1) * 8 + (blk & 2) * 4 * frm.stride[0];
180 decode_block_intra(&mut frm.data[ydst + cur_off..], frm.stride[0], btype, &self.coeffs[cpos..], &self.qmat_y_intra);
181 cpos += nc;
182 }
183 let btype = bt_reader.read_block_type()?;
184 let nc = COEFFS_PER_BLOCK[btype];
185 validate!(cpos + nc <= ncoeffs);
186 if (btype != 0) && (cur_mb < pred_mbs) {
187 self.coeffs[cpos] += udc;
188 udc = self.coeffs[cpos];
189 }
190 decode_block_intra(&mut frm.data[udst + x / 2..], frm.stride[1], btype, &self.coeffs[cpos..], &self.qmat_c_intra);
191 cpos += nc;
192 let btype = bt_reader.read_block_type()?;
193 let nc = COEFFS_PER_BLOCK[btype];
194 validate!(cpos + nc <= ncoeffs);
195 if (btype != 0) && (cur_mb < pred_mbs) {
196 self.coeffs[cpos] += vdc;
197 vdc = self.coeffs[cpos];
198 }
199 decode_block_intra(&mut frm.data[vdst + x / 2..], frm.stride[2], btype, &self.coeffs[cpos..], &self.qmat_c_intra);
200 cpos += nc;
201 } else {
202 validate!(cur_mv < num_mvs);
203 let mv_x = self.mvs[cur_mv * 2];
204 let mv_y = self.mvs[cur_mv * 2 + 1];
205 cur_mv += 1;
206 let src_x = (x as isize) + (mv_x as isize);
207 let src_y = (y as isize) + (mv_y as isize);
208 validate!(src_x >= 0 && src_x + 16 <= self.width as isize);
209 validate!(src_y >= 0 && src_y + 16 <= self.height as isize);
210 let sstride = ref_frm.get_stride(0);
211 let src = &ref_frm.get_data()[ref_frm.get_offset(0) + (src_x as usize) + (src_y as usize) * sstride..];
212 let dst = &mut frm.data[ydst + x..];
213 for (dst, src) in dst.chunks_mut(frm.stride[0]).zip(src.chunks(sstride)).take(16) {
e6aaad5c 214 dst[..16].copy_from_slice(&src[..16]);
f42a4a86
KS
215 }
216 let xoff = (src_x as usize) >> 1;
217 let yoff = (src_y as usize) >> 1;
218 for plane in 1..3 {
219 let sstride = ref_frm.get_stride(plane);
220 let src = &ref_frm.get_data()[ref_frm.get_offset(plane) + xoff + yoff * sstride..];
221 let dst = &mut frm.data[if plane == 1 { udst } else { vdst } + x / 2..];
222 for (dst, src) in dst.chunks_mut(frm.stride[plane]).zip(src.chunks(sstride)).take(8) {
e6aaad5c 223 dst[..8].copy_from_slice(&src[..8]);
f42a4a86
KS
224 }
225 }
226 if has_residue {
227 for blk in 0..4 {
228 let btype = bt_reader.read_block_type()?;
229 let nc = COEFFS_PER_BLOCK[btype];
230 validate!(cpos + nc <= ncoeffs);
231 if (btype != 0) && (cur_mb < pred_mbs) {
232 self.coeffs[cpos] += ydc;
233 ydc = self.coeffs[cpos];
234 }
235 let cur_off = x + (blk & 1) * 8 + (blk & 2) * 4 * frm.stride[0];
236 decode_block_inter(&mut frm.data[ydst + cur_off..], frm.stride[0], btype, &self.coeffs[cpos..], &self.qmat_y_inter);
237 cpos += nc;
238 }
239 let btype = bt_reader.read_block_type()?;
240 let nc = COEFFS_PER_BLOCK[btype];
241 validate!(cpos + nc <= ncoeffs);
242 if (btype != 0) && (cur_mb < pred_mbs) {
243 self.coeffs[cpos] += udc;
244 udc = self.coeffs[cpos];
245 }
246 decode_block_inter(&mut frm.data[udst + x / 2..], frm.stride[1], btype, &self.coeffs[cpos..], &self.qmat_c_inter);
247 cpos += nc;
248 let btype = bt_reader.read_block_type()?;
249 let nc = COEFFS_PER_BLOCK[btype];
250 validate!(cpos + nc <= ncoeffs);
251 if (btype != 0) && (cur_mb < pred_mbs) {
252 self.coeffs[cpos] += vdc;
253 vdc = self.coeffs[cpos];
254 }
255 decode_block_inter(&mut frm.data[vdst + x / 2..], frm.stride[2], btype, &self.coeffs[cpos..], &self.qmat_c_inter);
256 cpos += nc;
257 }
258 }
259 if is_intra || has_residue {
260 cur_mb += 1;
261 }
262 }
263 ydst += frm.stride[0] * 16;
264 udst += frm.stride[1] * 8;
265 vdst += frm.stride[2] * 8;
266 }
267 Ok(())
268 }
269}
270
271fn decode_values(br: &mut BitReader, dst: &mut [i16], cb: &Codebook<u32>) -> DecoderResult<()> {
272 let mut zero_run = 0usize;
273 for el in dst.iter_mut() {
274 if zero_run > 0 {
275 *el = 0;
276 zero_run -= 1;
277 } else {
6f263099 278 let val = br.read_cb(cb)? as u8;
f42a4a86
KS
279 if val == 0 {
280 zero_run = if br.read_bool()? {
281 br.read(6)? as usize + 8
282 } else {
283 br.read(3)? as usize
284 };
285 *el = 0;
286 } else {
287 let sign = br.read_bool()?;
288 let abits = br.read(val - 1)? as i16;
289 *el = (1 << (val - 1)) + abits;
290 if sign {
291 *el = -*el;
292 }
293 }
294 }
295 }
296 Ok(())
297}
298
299fn dequant(val: i16, q: i16) -> i32 {
7450554d 300 i32::from(val) * i32::from(q)
f42a4a86
KS
301}
302
303fn scale_coef(val: i32, scale: i16) -> i32 {
7450554d 304 (val * i32::from(scale)) >> 8
f42a4a86
KS
305}
306
307macro_rules! idct_1d {
e65c0040 308 ($c0: expr, $c1: expr, $c2: expr, $c3: expr, $c4: expr, $c5: expr, $c6: expr, $c7: expr) => {
f42a4a86
KS
309 let t0 = $c0 + $c4;
310 let t1 = $c0 - $c4;
311 let t2 = $c2 + $c6;
312 let t3 = scale_coef($c2 - $c6, 362) - t2;
313 let t4 = t0 + t2;
314 let t5 = t0 - t2;
315 let t6 = t1 + t3;
316 let t7 = t1 - t3;
317 let t8 = $c5 + $c3;
318 let t9 = $c5 - $c3;
319 let ta = $c1 + $c7;
320 let tb = $c1 - $c7;
321 let tc = t8 + ta;
322 let td = scale_coef(tb + t9, 473);
323 let te = scale_coef(t9, -669) - tc + td;
324 let tf = scale_coef(ta - t8, 362) - te;
325 let t10 = scale_coef(tb, 277) - td + tf;
326 $c0 = t4 + tc;
327 $c1 = t6 + te;
328 $c2 = t7 + tf;
329 $c3 = t5 - t10;
330 $c4 = t5 + t10;
331 $c5 = t7 - tf;
332 $c6 = t6 - te;
333 $c7 = t4 - tc;
334 }
335}
336
7450554d
KS
337#[allow(clippy::erasing_op)]
338#[allow(clippy::identity_op)]
f42a4a86
KS
339fn idct(blk: &mut [i32; 64]) {
340 for i in 0..8 {
341 idct_1d!(blk[i + 0 * 8], blk[i + 1 * 8], blk[i + 2 * 8], blk[i + 3 * 8],
342 blk[i + 4 * 8], blk[i + 5 * 8], blk[i + 6 * 8], blk[i + 7 * 8]);
343 }
344 for row in blk.chunks_mut(8) {
345 idct_1d!(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
346 }
347 for el in blk.iter_mut() {
7450554d 348 *el >>= 5;
f42a4a86
KS
349 }
350}
351
352fn decode_block_intra(dst: &mut [u8], stride: usize, btype: usize, coeffs: &[i16], qmat: &[i16; 64]) {
353 match btype {
354 0 | 1 => {
355 let fill_val = if btype == 0 { 0x80 } else {
356 ((dequant(coeffs[0], qmat[0]) >> 5) + 128).max(0).min(255) as u8
357 };
358 for line in dst.chunks_mut(stride).take(8) {
359 for el in line.iter_mut().take(8) {
360 *el = fill_val;
361 }
362 }
363 },
364 2 => {
365 let mut blk = [0i32; 64];
366 blk[0] = dequant(coeffs[0], qmat[0]);
367 blk[1] = dequant(coeffs[1], qmat[1]);
368 blk[8] = dequant(coeffs[2], qmat[8]);
369 blk[9] = dequant(coeffs[3], qmat[9]);
370 idct(&mut blk);
371 for (line, row) in dst.chunks_mut(stride).zip(blk.chunks(8)).take(8) {
372 for (dst, coef) in line.iter_mut().zip(row.iter()).take(8) {
373 *dst = (*coef + 128).max(0).min(255) as u8;
374 }
375 }
376 },
377 _ => {
378 let mut blk = [0i32; 64];
379 for i in 0..64 {
380 blk[SCAN[i]] = dequant(coeffs[i], qmat[SCAN[i]]);
381 }
382 idct(&mut blk);
383 for (line, row) in dst.chunks_mut(stride).zip(blk.chunks(8)).take(8) {
384 for (dst, coef) in line.iter_mut().zip(row.iter()).take(8) {
385 *dst = (*coef + 128).max(0).min(255) as u8;
386 }
387 }
388 },
389 };
390}
391
392fn decode_block_inter(dst: &mut [u8], stride: usize, btype: usize, coeffs: &[i16], qmat: &[i16; 64]) {
393 match btype {
394 0 => {}
395 1 => {
396 let dc = dequant(coeffs[0], qmat[0]) >> 5;
397 for line in dst.chunks_mut(stride).take(8) {
398 for el in line.iter_mut().take(8) {
7450554d 399 *el = (i32::from(*el) + dc).max(0).min(255) as u8;
f42a4a86
KS
400 }
401 }
402 },
403 2 => {
404 let mut blk = [0i32; 64];
405 blk[0] = dequant(coeffs[0], qmat[0]);
406 blk[1] = dequant(coeffs[1], qmat[1]);
407 blk[8] = dequant(coeffs[2], qmat[8]);
408 blk[9] = dequant(coeffs[3], qmat[9]);
409 idct(&mut blk);
410 for (line, row) in dst.chunks_mut(stride).zip(blk.chunks(8)).take(8) {
411 for (dst, coef) in line.iter_mut().zip(row.iter()).take(8) {
7450554d 412 *dst = (i32::from(*dst) + *coef).max(0).min(255) as u8;
f42a4a86
KS
413 }
414 }
415 },
416 _ => {
417 let mut blk = [0i32; 64];
418 for i in 0..64 {
419 blk[SCAN[i]] = dequant(coeffs[i], qmat[SCAN[i]]);
420 }
421 idct(&mut blk);
422 for (line, row) in dst.chunks_mut(stride).zip(blk.chunks(8)).take(8) {
423 for (dst, coef) in line.iter_mut().zip(row.iter()).take(8) {
7450554d 424 *dst = (i32::from(*dst) + *coef).max(0).min(255) as u8;
f42a4a86
KS
425 }
426 }
427 },
428 };
429}
430
431fn init_quant(qmat: &mut [i16; 64], base_qmat: &[u8; 64], quant: u8) {
432 let q = if quant < 50 {
7450554d 433 5000 / i32::from(quant.max(1))
f42a4a86 434 } else {
7450554d 435 i32::from((100 - quant.min(100)) * 2)
f42a4a86
KS
436 };
437 for (inq, (outq, scale)) in base_qmat.iter().zip(qmat.iter_mut().zip(QUANT_MATRIX.iter())) {
7450554d
KS
438 let val = ((i32::from(*inq) * q + 50) / 100).max(1).min(0x7FFF);
439 *outq = ((val * i32::from(*scale) + 0x800) >> 12) as i16;
f42a4a86
KS
440 }
441}
442
443impl NADecoder for Midivid3Decoder {
444 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
445 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
446 self.width = vinfo.get_width();
447 self.height = vinfo.get_height();
448 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(self.width, self.height, true, YUV420_FORMAT));
449 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
450 self.num_mbs = ((self.width + 15) >> 4) * ((self.height + 15) >> 4);
451 self.mvs.resize(self.num_mbs * 2, 0);
452
453 Ok(())
454 } else {
455 Err(DecoderError::InvalidData)
456 }
457 }
458 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
459 let src = pkt.get_buffer();
460 validate!(src.len() > 8);
461
462 let i_quant = src[0];
463 let p_quant = i_quant.wrapping_add(src[1]);
464 let inter_flag = read_u16le(&src[2..])?;
465 validate!(inter_flag < 2);
466 let is_intra = inter_flag == 0;
467
468 init_quant(&mut self.qmat_y_intra, &QUANT_MAT_LUMA, i_quant);
469 init_quant(&mut self.qmat_c_intra, &QUANT_MAT_CHROMA, i_quant);
470 init_quant(&mut self.qmat_y_inter, &QUANT_MAT_LUMA, p_quant);
471 init_quant(&mut self.qmat_c_inter, &QUANT_MAT_CHROMA, p_quant);
472
473 let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 4)?;
474 let mut buf = bufinfo.get_vbuf().unwrap();
475
476 let mut frm = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
477 let bt_size = read_u16le(&src[4..])? as usize;
478 if is_intra {
479 validate!(bt_size + 6 <= src.len());
480
481 let bt_buf = if is_intra { &src[6..][..bt_size] } else { &src[8..][..bt_size] };
482 let mut bt_reader = BlockTypeReader { src: bt_buf, pos: 0, bpos: 0 };
483 let mut br = BitReader::new(&src[6 + bt_size..], BitReaderMode::BE);
484
485 self.decode_intra(&mut frm, &mut bt_reader, &mut br)?;
486 } else {
487 let num_mvs = read_u16le(&src[6..])? as usize;
488 let mask_len = (self.num_mbs + 3) >> 2;
489 let data_start = 8 + bt_size + mask_len;
490 validate!(data_start <= src.len());
491 validate!(num_mvs <= self.num_mbs);
492
493 let bt_buf = &src[8 + mask_len..][..bt_size];
494 let mask = &src[8..][..mask_len];
495 let mut mask_reader = MaskReader { src: mask, pos: 0, bpos: 0 };
496 let mut bt_reader = BlockTypeReader { src: bt_buf, pos: 0, bpos: 0 };
497 let mut br = BitReader::new(&src[data_start..], BitReaderMode::BE);
498
499 self.decode_inter(&mut frm, &mut mask_reader, &mut bt_reader, &mut br, num_mvs)?;
500 }
501
502 self.shuf.add_frame(buf.clone());
503
504 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
505 frm.set_keyframe(is_intra);
506 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
507 Ok(frm.into_ref())
508 }
509 fn flush(&mut self) {
510 self.shuf.clear();
511 }
512}
513
7d57ae2f
KS
514impl NAOptionHandler for Midivid3Decoder {
515 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
516 fn set_options(&mut self, _options: &[NAOption]) { }
517 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
518}
519
f42a4a86
KS
520
521pub fn get_decoder_video() -> Box<dyn NADecoder + Send> {
522 Box::new(Midivid3Decoder::new())
523}
524
525#[cfg(test)]
526mod test {
527 use nihav_core::codecs::RegisteredDecoders;
528 use nihav_core::demuxers::RegisteredDemuxers;
529 use nihav_codec_support::test::dec_video::*;
78fb6560 530 use crate::game_register_all_decoders;
f42a4a86
KS
531 use nihav_commonfmt::generic_register_all_demuxers;
532 #[test]
533 fn test_midivid3_video() {
534 let mut dmx_reg = RegisteredDemuxers::new();
535 generic_register_all_demuxers(&mut dmx_reg);
536 let mut dec_reg = RegisteredDecoders::new();
78fb6560 537 game_register_all_decoders(&mut dec_reg);
f42a4a86 538
886cde48 539 // sample: https://samples.mplayerhq.hu/V-codecs/mv30.avi
f42a4a86
KS
540 test_decoding("avi", "midivid3", "assets/Game/mv30.avi", Some(16), &dmx_reg, &dec_reg,
541 ExpectedTestResult::MD5Frames(vec![
542 [0x0f4f2377, 0xe017458f, 0xebf6d59d, 0x238a3e64],
543 [0xdca83224, 0xbd2fd721, 0x954804c6, 0xaa38b1f3],
544 [0x35104196, 0xf96eacb5, 0x5d34910a, 0xb6dfde27],
545 [0x6106ddf6, 0xda75f5bf, 0x1eaeef52, 0xffbfbdb8],
546 [0xdd429c46, 0x4bc67009, 0xdc14d6e2, 0x816f7e4a],
547 [0xa58a19fa, 0x663edfc1, 0x12a89fe7, 0x7ffd8484],
548 [0xf4f2f0c5, 0x5479661c, 0x22839c5f, 0x8ff45232],
549 [0xb70cb7d9, 0x9c514449, 0xabb85bb4, 0x5b20d9d7],
550 [0xd65c33cc, 0xba03ff85, 0x615b3171, 0xfd16334f],
551 [0x13c5ffc3, 0x1e279df1, 0x48393c15, 0x394bfabe],
552 [0x169cb91a, 0x2a8f8a63, 0x995d53c2, 0x1123d5e9],
553 [0x26a8bc57, 0x3b8ba658, 0xb960ef85, 0xf4dbd720],
554 [0x13a405e9, 0x3fae3101, 0xee1c29f4, 0x3bf69d94],
555 [0x3d7b1b6b, 0x9026d717, 0x97e1c6c1, 0x4c6877a7],
556 [0x8f2f4b9a, 0x6afa65f3, 0x9b0e0173, 0x56725a4a],
557 [0x4b140176, 0x10ee87d5, 0x899e86fe, 0xb30fc404],
558 [0xb82892a1, 0x2eda670c, 0x7a130bb4, 0x810fc089]]));
559 }
560}
561
562const QUANT_MAT_LUMA: [u8; 64] = [
563 12, 12, 15, 19, 25, 34, 40, 48,
564 12, 12, 18, 22, 27, 44, 47, 46,
565 17, 18, 21, 26, 35, 46, 52, 47,
566 18, 20, 24, 28, 40, 61, 59, 51,
567 20, 24, 32, 43, 50, 72, 72, 63,
568 25, 31, 42, 48, 58, 72, 81, 75,
569 38, 46, 54, 61, 71, 84, 88, 85,
570 50, 61, 65, 68, 79, 78, 86, 91
571];
572
573const QUANT_MAT_CHROMA: [u8; 64] = [
574 12, 16, 24, 47, 99, 99, 99, 99,
575 16, 21, 26, 66, 99, 99, 99, 99,
576 24, 26, 56, 99, 99, 99, 99, 99,
577 47, 66, 99, 99, 99, 99, 99, 99,
578 99, 99, 99, 99, 99, 99, 99, 99,
579 99, 99, 99, 99, 99, 99, 99, 99,
580 99, 99, 99, 99, 99, 99, 99, 99,
581 99, 99, 99, 99, 99, 99, 99, 99
582];
583
584const QUANT_MATRIX: [i16; 64] = [
585 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
586 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
587 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
588 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
589 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
590 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
591 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
592 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
593];
594
595const SCAN: [usize; 64] = [
596 0, 1, 8, 9, 16, 2, 3, 10,
597 17, 24, 32, 25, 18, 11, 4, 5,
598 12, 19, 26, 33, 40, 48, 41, 34,
599 27, 20, 13, 6, 7, 14, 21, 28,
600 35, 42, 49, 56, 57, 50, 43, 36,
601 29, 22, 15, 23, 30, 37, 44, 51,
602 58, 59, 52, 45, 38, 31, 39, 46,
603 53, 60, 61, 54, 47, 55, 62, 63
604];