1 use nihav_core::io::bitreader::*;
2 use nihav_core::formats;
3 use nihav_core::frame::*;
4 use nihav_core::codecs::*;
5 use nihav_codec_support::codecs::ZIGZAG;
10 fn mclip8(a: i32) -> u8 {
11 if (a as u16) > 255 { !(a >> 16) as u8 }
20 fn calc_quant(glob_q: u32, qd: i16) -> u8 {
21 let q = (glob_q as i16) + qd;
40 impl IndeoXParser for Indeo4Parser {
41 fn decode_picture_header(&mut self, br: &mut BitReader) -> DecoderResult<PictureHeader> {
42 let sync = br.read(18)?;
43 validate!(sync == 0x3FFF8);
44 let ftype_idx = br.read(3)?;
45 validate!(ftype_idx < 7);
46 let ftype = INDEO4_FRAME_TYPE[ftype_idx as usize];
47 let transparent = br.read_bool()?;
49 let _data_size = if br.read_bool()? { br.read(24)? as usize } else { 0 };
51 return Ok(PictureHeader::new_null(ftype));
54 br.skip(32)?; // key lock
58 let pic_size_idx = br.read(3)?;
60 width = INDEO4_PICTURE_SIZE_TAB[pic_size_idx as usize][0];
61 height = INDEO4_PICTURE_SIZE_TAB[pic_size_idx as usize][1];
63 height = br.read(16)? as usize;
64 width = br.read(16)? as usize;
65 validate!((width > 0) && ((width & 3) == 0));
66 validate!((height > 0) && ((height & 3) == 0));
72 let idx = br.read(4)? as usize;
73 slice_h = if idx < 15 { INDEO4_SLICE_SIZE_TAB[idx] } else { height };
74 let idx = br.read(4)? as usize;
75 slice_w = if idx < 15 { INDEO4_SLICE_SIZE_TAB[idx] } else { width };
80 let subsampling = br.read(2)?;
81 validate!(subsampling == 0);
82 let sc_idx = br.read(2)?;
85 2 => { validate!(br.read(2*4)? == 0xFF); }
86 _ => { return Err(DecoderError::InvalidData); }
88 let luma_bands = if sc_idx == 2 { 4 } else { 1 };
89 let sc_idx = br.read(2)?;
92 2 => { validate!(br.read(2*4)? == 0xFF); }
93 _ => { return Err(DecoderError::InvalidData); }
95 let chroma_bands = if sc_idx == 2 { 4 } else { 1 };
96 let _frame_no = if br.read_bool()? { br.read(20)? } else { 0 };
98 br.skip(8)?; // decTimeEst
100 let desc_coded = br.read_bool()?;
101 self.mb_cb = br.read_ivi_codebook_desc(true, desc_coded)?;
102 let desc_coded = br.read_bool()?;
103 self.blk_cb = br.read_ivi_codebook_desc(false, desc_coded)?;
104 let _rvmap = if br.read_bool()? { br.read(3)? as usize } else { 8 };
105 let _in_imf = br.read_bool()?;
106 let in_q = br.read_bool()?;
107 let _glob_q = br.read(5)? as u8;
111 let _checksum = if br.read_bool()? { br.read(16)? } else { 0 };
113 br.skip(8)?; // pic hdr extension
116 println!("bad blocks bits!");
120 Ok(PictureHeader::new(ftype, width, height, slice_w, slice_h, transparent, luma_bands, chroma_bands, in_q))
123 #[allow(clippy::manual_range_contains)]
124 fn decode_band_header(&mut self, br: &mut BitReader, pic_hdr: &PictureHeader, plane: usize, band: usize) -> DecoderResult<BandHeader> {
125 let plane_no = br.read(2)? as usize;
126 let band_no = br.read(4)? as usize;
127 validate!(plane_no == plane);
128 validate!(band_no == band);
131 return Ok(BandHeader::new_empty(plane_no, band_no));
133 let _hdr_size = if br.read_bool()? { br.read(16)? as usize } else { 32 };
134 let mv_mode = br.read(2)?;
135 validate!(mv_mode < 2);
137 br.skip(16)?; //checksum
140 let scale = br.read(2)?;
141 validate!(scale != 3);
142 let mb_size = 16 >> scale;
143 let blk_size = 8 >> (scale >> 1);
144 let inherit_mv = br.read_bool()?;
145 let inherit_qd = br.read_bool()?;
146 let quant = br.read(5)?;
148 let tr: IVITransformType;
150 if !br.read_bool()? || pic_hdr.ftype == IVIFrameType::Intra {
151 let tr_id = br.read(5)?;
152 validate!(tr_id < 18);
153 let scan_idx = br.read(4)? as usize;
154 validate!(scan_idx != 15);
155 let qmat_idx = br.read(5)? as usize;
157 tr = INDEO4_TRANSFORMS[tr_id as usize];
158 if (scan_idx < 5) || (scan_idx >= 10) {
159 validate!(tr.is_8x8());
160 validate!(qmat_idx < 15);
161 let scan = if scan_idx < 5 { INDEO4_SCANS_8X8[scan_idx] }
162 else { INDEO4_SCANS_8X8[4] };
163 let qidx = INDEO4_Q8X8_IDX[qmat_idx];
164 let qintra = INDEO4_Q8_INTRA[qidx];
165 let qinter = INDEO4_Q8_INTER[qidx];
166 txtype = TxType::Transform8(TxParams8x8::new(qintra, qinter, scan));
167 } else if scan_idx < 10 {
168 validate!(!tr.is_8x8());
169 validate!((15..22).contains(&qmat_idx));
170 let scan = INDEO4_SCANS_4X4[scan_idx - 5];
171 let qidx = INDEO4_Q4X4_IDX[qmat_idx - 15];
172 let qintra = INDEO4_Q4_INTRA[qidx];
173 let qinter = INDEO4_Q4_INTER[qidx];
174 txtype = TxType::Transform4(TxParams4x4::new(qintra, qinter, scan));
179 tr = IVITransformType::None(TSize::T8x8);
180 txtype = TxType::None;
183 let blk_cb = if br.read_bool()? {
184 br.read_ivi_codebook_desc(false, true)?
188 let rvmap_idx = if br.read_bool()? { br.read(3)? as usize } else { 8 };
190 let mut corr_map: [u8; CORR_MAP_SIZE] = [0; CORR_MAP_SIZE];
192 num_corr = br.read(8)? as usize;
193 validate!(num_corr*2 <= CORR_MAP_SIZE);
194 for el in corr_map[..num_corr*2].iter_mut() {
195 *el = br.read(8)? as u8;
202 Ok(BandHeader::new(plane_no, band_no, mb_size, blk_size, mv_mode == 1, inherit_mv, false, inherit_qd, quant, rvmap_idx, num_corr, corr_map, blk_cb, tr, txtype))
205 fn decode_mb_info(&mut self, br: &mut BitReader, pic_hdr: &PictureHeader, band: &BandHeader, tile: &mut IVITile, ref_tile: Option<&IVITile>, mv_scale: u8) -> DecoderResult<()> {
210 for mb_y in 0..tile.mb_h {
211 for mb_x in 0..tile.mb_w {
212 let mut mb = MB::new(tile.pos_x + mb_x * band.mb_size, tile.pos_y + mb_y * band.mb_size);
213 if !br.read_bool()? {
214 if pic_hdr.ftype.is_intra() {
215 mb.mtype = MBType::Intra;
216 } else if band.inherit_mv {
217 if let Some(tileref) = ref_tile {
218 mb.mtype = tileref.mb[mb_idx].mtype;
220 return Err(DecoderError::MissingReference);
222 } else if !pic_hdr.ftype.is_bidir() {
223 mb.mtype = if br.read_bool()? { MBType::Inter } else { MBType::Intra };
225 mb.mtype = match br.read(2)? {
226 0 => { MBType::Intra },
227 1 => { MBType::Inter },
228 2 => { MBType::Backward },
229 _ => { MBType::Bidir },
232 if band.mb_size == band.blk_size {
233 mb.cbp = br.read(1)? as u8;
235 mb.cbp = br.read(4)? as u8;
238 if let Some(tileref) = ref_tile {
239 mb.qd = tileref.mb[mb_idx].qd;
240 mb.q = calc_quant(band.quant, mb.qd);
242 mb.q = band.quant as u8;
244 } else if (mb.cbp != 0) || ((band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q) {
245 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
246 mb.q = calc_quant(band.quant, mb.qd);
248 mb.q = band.quant as u8;
251 if mb.mtype != MBType::Intra {
253 if let Some(tileref) = ref_tile {
254 let mx = tileref.mb[mb_idx].mv_x;
255 let my = tileref.mb[mb_idx].mv_y;
260 mb.mv_x = scale_mv(mx, mv_scale);
261 mb.mv_y = scale_mv(my, mv_scale);
265 mv_y += br.read_ivi_cb_s(&self.mb_cb)?;
266 mv_x += br.read_ivi_cb_s(&self.mb_cb)?;
269 if mb.mtype == MBType::Backward {
272 } else if mb.mtype == MBType::Bidir {
273 mv_y += br.read_ivi_cb_s(&self.mb_cb)?;
274 mv_x += br.read_ivi_cb_s(&self.mb_cb)?;
281 validate!(!pic_hdr.ftype.is_intra());
282 mb.mtype = MBType::Inter;
285 if (band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q {
286 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
287 mb.q = calc_quant(band.quant, mb.qd);
290 if let Some(tileref) = ref_tile {
291 let mx = tileref.mb[mb_idx].mv_x;
292 let my = tileref.mb[mb_idx].mv_y;
297 mb.mv_x = scale_mv(mx, mv_scale);
298 mb.mv_y = scale_mv(my, mv_scale);
303 tile.mb[mb_idx] = mb;
311 fn recombine_plane(&mut self, src: &[i16], sstride: usize, dst: &mut [u8], dstride: usize, w: usize, h: usize) {
313 let mut idx1 = w / 2;
314 let mut idx2 = (h / 2) * sstride;
315 let mut idx3 = idx2 + idx1;
317 let mut oidx1 = dstride;
321 let p0 = src[idx0 + x];
322 let p1 = src[idx1 + x];
323 let p2 = src[idx2 + x];
324 let p3 = src[idx3 + x];
329 dst[oidx0 + x * 2 + 0] = clip8(((s0 + s1 + 2) >> 2) + 128);
330 dst[oidx0 + x * 2 + 1] = clip8(((d0 + d1 + 2) >> 2) + 128);
331 dst[oidx1 + x * 2 + 0] = clip8(((s0 - s1 + 2) >> 2) + 128);
332 dst[oidx1 + x * 2 + 1] = clip8(((d0 - d1 + 2) >> 2) + 128);
338 oidx0 += dstride * 2;
339 oidx1 += dstride * 2;
342 let hw = (w / 2) as isize;
343 let hh = (h / 2) as isize;
344 let mut band0 = src.as_ptr();
345 let mut band1 = band0.offset(hw);
346 let mut band2 = band0.add((h / 2) * sstride);
347 let mut band3 = band2.offset(hw);
348 let mut dst0 = dst.as_mut_ptr();
349 let mut dst1 = dst0.add(dstride);
351 let mut b0_ptr = band0;
352 let mut b1_ptr = band1;
353 let mut b2_ptr = band2;
354 let mut b3_ptr = band3;
355 let mut d0_ptr = dst0;
356 let mut d1_ptr = dst1;
358 let p0 = i32::from(*b0_ptr);
359 let p1 = i32::from(*b1_ptr);
360 let p2 = i32::from(*b2_ptr);
361 let p3 = i32::from(*b3_ptr);
362 let s0 = p0.wrapping_add(p2);
363 let s1 = p1.wrapping_add(p3);
364 let d0 = p0.wrapping_sub(p2);
365 let d1 = p1.wrapping_sub(p3);
366 let o0 = s0.wrapping_add(s1).wrapping_add(2);
367 let o1 = d0.wrapping_add(d1).wrapping_add(2);
368 let o2 = s0.wrapping_sub(s1).wrapping_add(2);
369 let o3 = d0.wrapping_sub(d1).wrapping_add(2);
370 *d0_ptr.offset(0) = mclip8((o0 >> 2).wrapping_add(128));
371 *d0_ptr.offset(1) = mclip8((o1 >> 2).wrapping_add(128));
372 *d1_ptr.offset(0) = mclip8((o2 >> 2).wrapping_add(128));
373 *d1_ptr.offset(1) = mclip8((o3 >> 2).wrapping_add(128));
374 b0_ptr = b0_ptr.offset(1);
375 b1_ptr = b1_ptr.offset(1);
376 b2_ptr = b2_ptr.offset(1);
377 b3_ptr = b3_ptr.offset(1);
378 d0_ptr = d0_ptr.offset(2);
379 d1_ptr = d1_ptr.offset(2);
381 band0 = band0.add(sstride);
382 band1 = band1.add(sstride);
383 band2 = band2.add(sstride);
384 band3 = band3.add(sstride);
385 dst0 = dst0.add(dstride * 2);
386 dst1 = dst1.add(dstride * 2);
392 struct Indeo4Decoder {
393 info: NACodecInfoRef,
400 info: NACodecInfo::new_dummy(),
401 dec: IVIDecoder::new(false),
406 impl NADecoder for Indeo4Decoder {
407 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
408 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
409 let w = vinfo.get_width();
410 let h = vinfo.get_height();
411 let f = vinfo.is_flipped();
412 let fmt = formats::YUV410_FORMAT;
413 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, f, fmt));
414 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
417 Err(DecoderError::InvalidData)
420 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
421 let src = pkt.get_buffer();
422 let mut br = BitReader::new(src.as_slice(), BitReaderMode::LE);
424 let mut ip = Indeo4Parser::new();
425 let bufinfo = self.dec.decode_frame(&mut ip, &mut br)?;
426 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
427 frm.set_keyframe(self.dec.is_intra());
428 frm.set_frame_type(self.dec.get_frame_type());
431 fn flush(&mut self) {
436 impl NAOptionHandler for Indeo4Decoder {
437 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
438 fn set_options(&mut self, _options: &[NAOption]) { }
439 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
442 const INDEO4_PICTURE_SIZE_TAB: [[usize; 2]; 7] = [
443 [640, 480], [320, 240], [160, 120], [704, 480], [352, 240], [352, 288], [176, 144]
446 const INDEO4_SLICE_SIZE_TAB: [usize; 15] = [
447 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480
450 const INDEO4_FRAME_TYPE: [IVIFrameType; 7] = [
451 IVIFrameType::Intra, IVIFrameType::Intra1, IVIFrameType::Inter, IVIFrameType::Bidir,
452 IVIFrameType::InterDroppable, IVIFrameType::NULL, IVIFrameType::NULL2
455 const INDEO4_TRANSFORMS: [IVITransformType; 18] = [
456 IVITransformType::Haar(TSize::T8x8, TDir::TwoD),
457 IVITransformType::Haar(TSize::T8x8, TDir::Row),
458 IVITransformType::Haar(TSize::T8x8, TDir::Col),
459 IVITransformType::None(TSize::T8x8),
460 IVITransformType::Slant(TSize::T8x8, TDir::TwoD),
461 IVITransformType::Slant(TSize::T8x8, TDir::Row),
462 IVITransformType::Slant(TSize::T8x8, TDir::Col),
463 IVITransformType::DCT(TSize::T8x8, TDir::TwoD),
464 IVITransformType::DCT(TSize::T8x8, TDir::Row),
465 IVITransformType::DCT(TSize::T8x8, TDir::Col),
466 IVITransformType::Haar(TSize::T4x4, TDir::TwoD),
467 IVITransformType::Slant(TSize::T4x4, TDir::TwoD),
468 IVITransformType::None(TSize::T4x4),
469 IVITransformType::Haar(TSize::T4x4, TDir::Row),
470 IVITransformType::Haar(TSize::T4x4, TDir::Col),
471 IVITransformType::Slant(TSize::T4x4, TDir::Row),
472 IVITransformType::Slant(TSize::T4x4, TDir::Col),
473 IVITransformType::DCT(TSize::T4x4, TDir::TwoD),
476 const INDEO4_SCAN_8X8_ALT: [usize; 64] = [
477 0, 8, 1, 9, 16, 24, 2, 3,
478 17, 25, 10, 11, 32, 40, 48, 56,
479 4, 5, 6, 7, 33, 41, 49, 57,
480 18, 19, 26, 27, 12, 13, 14, 15,
481 34, 35, 43, 42, 50, 51, 59, 58,
482 20, 21, 22, 23, 31, 30, 29, 28,
483 36, 37, 38, 39, 47, 46, 45, 44,
484 52, 53, 54, 55, 63, 62, 61, 60
486 const INDEO4_SCAN_4X4_ALT: [usize; 16] = [ 0, 1, 4, 5, 8, 12, 2, 3, 9, 13, 6, 7, 10, 11, 14, 15 ];
487 const INDEO4_SCAN_4X4_VER: [usize; 16] = [ 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 ];
488 const INDEO4_SCAN_4X4_HOR: [usize; 16] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ];
490 const INDEO4_SCANS_8X8: [&[usize; 64]; 5] = [
491 &ZIGZAG, &INDEO4_SCAN_8X8_ALT, &IVI_SCAN_8X8_HOR, &IVI_SCAN_8X8_VER, &ZIGZAG
493 const INDEO4_SCANS_4X4: [&[usize; 16]; 5] = [
494 &IVI_SCAN_4X4, &INDEO4_SCAN_4X4_ALT, &INDEO4_SCAN_4X4_VER, &INDEO4_SCAN_4X4_HOR, &IVI_SCAN_4X4
497 const INDEO4_Q8X8_IDX: [usize; 15] = [ 0, 1, 0, 2, 1, 3, 0, 4, 1, 5, 0, 1, 6, 7, 8 ];
498 const INDEO4_Q4X4_IDX: [usize; 7] = [ 0, 1, 2, 2, 3, 3, 4 ];
500 const INDEO4_QUANT8X8_INTRA: [[u16; 64]; 9] = [
502 43, 342, 385, 470, 555, 555, 598, 726,
503 342, 342, 470, 513, 555, 598, 726, 769,
504 385, 470, 555, 555, 598, 726, 726, 811,
505 470, 470, 555, 555, 598, 726, 769, 854,
506 470, 555, 555, 598, 683, 726, 854, 1025,
507 555, 555, 598, 683, 726, 854, 1025, 1153,
508 555, 555, 598, 726, 811, 982, 1195, 1451,
509 555, 598, 726, 811, 982, 1195, 1451, 1793
511 86, 1195, 2390, 2390, 4865, 4865, 4865, 4865,
512 1195, 1195, 2390, 2390, 4865, 4865, 4865, 4865,
513 2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827,
514 2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827,
515 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
516 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
517 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
518 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827
520 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
521 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
522 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
523 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
524 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
525 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
526 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
527 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835
529 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
530 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
531 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
532 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
533 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
534 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
535 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
536 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414
538 897, 897, 897, 897, 897, 897, 897, 897,
539 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067,
540 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
541 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409,
542 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579,
543 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750,
544 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921,
545 2091, 2091, 2091, 2091, 2091, 2091, 2091, 2091
547 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
548 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
549 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
550 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
551 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
552 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
553 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
554 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414
556 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
557 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
558 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
559 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
560 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
561 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
562 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
563 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390
565 22, 171, 214, 257, 257, 299, 299, 342,
566 171, 171, 257, 257, 299, 299, 342, 385,
567 214, 257, 257, 299, 299, 342, 342, 385,
568 257, 257, 257, 299, 299, 342, 385, 427,
569 257, 257, 299, 299, 342, 385, 427, 513,
570 257, 299, 299, 342, 385, 427, 513, 598,
571 299, 299, 299, 385, 385, 470, 598, 726,
572 299, 299, 385, 385, 470, 598, 726, 897
574 86, 598, 1195, 1195, 2390, 2390, 2390, 2390,
575 598, 598, 1195, 1195, 2390, 2390, 2390, 2390,
576 1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414,
577 1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414,
578 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
579 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
580 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
581 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414
584 const INDEO4_QUANT8X8_INTER: [[u16; 64]; 9] = [
586 427, 427, 470, 427, 427, 427, 470, 470,
587 427, 427, 470, 427, 427, 427, 470, 470,
588 470, 470, 470, 470, 470, 470, 470, 470,
589 427, 427, 470, 470, 427, 427, 470, 470,
590 427, 427, 470, 427, 427, 427, 470, 470,
591 427, 427, 470, 427, 427, 427, 470, 470,
592 470, 470, 470, 470, 470, 470, 470, 470,
593 470, 470, 470, 470, 470, 470, 470, 470
595 1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414,
596 1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414,
597 2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822,
598 2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822,
599 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
600 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
601 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
602 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414
604 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
605 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
606 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
607 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
608 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
609 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
610 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
611 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281
613 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
614 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
615 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
616 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
617 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
618 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
619 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
620 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433
622 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
623 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
624 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
625 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
626 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
627 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
628 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
629 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281
631 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
632 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
633 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
634 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
635 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
636 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
637 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
638 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433
640 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
641 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
642 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
643 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
644 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
645 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
646 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
647 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707
649 86, 171, 171, 214, 214, 214, 214, 257,
650 171, 171, 214, 214, 214, 214, 257, 257,
651 171, 214, 214, 214, 214, 257, 257, 257,
652 214, 214, 214, 214, 257, 257, 257, 299,
653 214, 214, 214, 257, 257, 257, 299, 299,
654 214, 214, 257, 257, 257, 299, 299, 299,
655 214, 257, 257, 257, 299, 299, 299, 342,
656 257, 257, 257, 299, 299, 299, 342, 342
658 854, 854, 1195, 1195, 1707, 1707, 1707, 1707,
659 854, 854, 1195, 1195, 1707, 1707, 1707, 1707,
660 1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390,
661 1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390,
662 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
663 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
664 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
665 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707
668 const INDEO4_QUANT4X4_INTRA: [[u16; 16]; 5] = [
675 129, 1025, 1451, 1451,
676 1025, 1025, 1451, 1451,
677 1451, 1451, 2049, 2049,
678 1451, 1451, 2049, 2049
696 const INDEO4_QUANT4X4_INTER: [[u16; 16]; 5] = [
703 513, 1025, 1238, 1238,
704 1025, 1025, 1238, 1238,
705 1238, 1238, 1451, 1451,
706 1238, 1238, 1451, 1451
724 const INDEO4_Q8_INTRA: [&[u16; 64]; 9] = [
725 &INDEO4_QUANT8X8_INTRA[0], &INDEO4_QUANT8X8_INTRA[1], &INDEO4_QUANT8X8_INTRA[2],
726 &INDEO4_QUANT8X8_INTRA[3], &INDEO4_QUANT8X8_INTRA[4], &INDEO4_QUANT8X8_INTRA[5],
727 &INDEO4_QUANT8X8_INTRA[6], &INDEO4_QUANT8X8_INTRA[7], &INDEO4_QUANT8X8_INTRA[8],
729 const INDEO4_Q8_INTER: [&[u16; 64]; 9] = [
730 &INDEO4_QUANT8X8_INTER[0], &INDEO4_QUANT8X8_INTER[1], &INDEO4_QUANT8X8_INTER[2],
731 &INDEO4_QUANT8X8_INTER[3], &INDEO4_QUANT8X8_INTER[4], &INDEO4_QUANT8X8_INTER[5],
732 &INDEO4_QUANT8X8_INTER[6], &INDEO4_QUANT8X8_INTER[7], &INDEO4_QUANT8X8_INTER[8],
734 const INDEO4_Q4_INTRA: [&[u16; 16]; 5] = [
735 &INDEO4_QUANT4X4_INTRA[0], &INDEO4_QUANT4X4_INTRA[1], &INDEO4_QUANT4X4_INTRA[2],
736 &INDEO4_QUANT4X4_INTRA[3], &INDEO4_QUANT4X4_INTRA[4]
738 const INDEO4_Q4_INTER: [&[u16; 16]; 5] = [
739 &INDEO4_QUANT4X4_INTER[0], &INDEO4_QUANT4X4_INTER[1], &INDEO4_QUANT4X4_INTER[2],
740 &INDEO4_QUANT4X4_INTER[3], &INDEO4_QUANT4X4_INTER[4]
743 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
744 Box::new(Indeo4Decoder::new())
749 use nihav_core::codecs::RegisteredDecoders;
750 use nihav_core::demuxers::RegisteredDemuxers;
751 use nihav_codec_support::test::dec_video::*;
752 use crate::indeo_register_all_decoders;
753 use nihav_commonfmt::generic_register_all_demuxers;
756 let mut dmx_reg = RegisteredDemuxers::new();
757 generic_register_all_demuxers(&mut dmx_reg);
758 let mut dec_reg = RegisteredDecoders::new();
759 indeo_register_all_decoders(&mut dec_reg);
761 // sample: https://samples.mplayerhq.hu/V-codecs/IV41/indeo4-avi/volcano.avi
762 test_decoding("avi", "indeo4", "assets/Indeo/IV4/volcano.avi", Some(16),
763 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
764 [0x194f626b, 0x023fdfd0, 0x9809665a, 0xd68f6f47],
765 [0x194f626b, 0x023fdfd0, 0x9809665a, 0xd68f6f47],
766 [0x194f626b, 0x023fdfd0, 0x9809665a, 0xd68f6f47],
767 [0x194f626b, 0x023fdfd0, 0x9809665a, 0xd68f6f47],
768 [0x46c6719d, 0xe6415ac0, 0x3e4d9799, 0xd2f5747d],
769 [0xe0278b0f, 0x3e4763d5, 0x88033344, 0xc9c2e6de],
770 [0xd962be7f, 0xafc1ac64, 0x0647cdcc, 0xd06465c6],
771 [0xedef0e19, 0xec75eed2, 0x955a2ae2, 0xd6145b4c],
772 [0x89ec8d4b, 0x3d446d74, 0xbd3d681d, 0x2d219dca],
773 [0x89e81643, 0x77fb2f1b, 0x2aa0782f, 0xb1b9b7ef],
774 [0xea283aec, 0x94d7cdf9, 0x961bbb69, 0x2b38162a],
775 [0x1d1b315c, 0x6613c5fa, 0xeff36485, 0x5025fbf2],
776 [0x4145c6a8, 0xd8d513b1, 0x34a5d353, 0x07750cd5],
777 [0xace12feb, 0x468754f3, 0xa72327f5, 0x1a6f6350],
778 [0x4b04dc0e, 0x684533a7, 0x6a4e4b16, 0x0b8a5e68],
779 [0xa3eb64fc, 0x5e02a31b, 0x6b484eae, 0xbb6e6c49],
780 [0x7d4ef46e, 0x6761c447, 0x02e002f5, 0x02d0231c]]));
781 // a sample from Civilization II
782 test_decoding("avi", "indeo4", "assets/Indeo/IV4/HRLDVIK.AVI", Some(8),
783 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
784 [0x239b8b87, 0x6dbec08c, 0x82bae1f0, 0x868e00c2],
785 [0xe2298beb, 0x4e08866d, 0x00cb6201, 0x6b0a6df3],
786 [0x9d7f4cf0, 0xed33df12, 0x2677be16, 0xce7e99b0],
787 [0x0c8d7489, 0x2b3ac56e, 0x36d75559, 0x70550903],
788 [0xc32b4b78, 0x2fc81737, 0xe4d7722b, 0xbcbbb35e],
789 [0x20bfd5e8, 0x6cfad540, 0xfc6c6b6c, 0xa4f39a7d],
790 [0xc327428d, 0x4e817b56, 0x4376eba2, 0xebafd04a],
791 [0x6a53a6ec, 0x7477a471, 0xd55bc98e, 0x7498de0f],
792 [0x398eba3a, 0x3cf3cce1, 0x90211dfe, 0x82c906f0]]));