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;
9 fn calc_quant(glob_q: u32, qd: i16) -> usize {
10 let qq = (glob_q as i16) + (qd as i16);
54 fn skip_extension(br: &mut BitReader) -> DecoderResult<()> {
56 let len = br.read(8)?;
57 if len == 0 { break; }
63 impl IndeoXParser for Indeo5Parser {
64 #[allow(unused_variables)]
65 #[allow(unused_assignments)]
66 fn decode_picture_header(&mut self, br: &mut BitReader) -> DecoderResult<PictureHeader> {
67 let sync = br.read(5)?;
68 validate!(sync == 0x1F);
69 let ftype_idx = br.read(3)?;
70 validate!(ftype_idx < 5);
71 let ftype = INDEO5_FRAME_TYPE[ftype_idx as usize];
72 let fnum = br.read(8)?;
73 if ftype == IVIFrameType::Intra {
74 let gop_flags = br.read(8)?;
76 if (gop_flags & 0x01) != 0 {
77 hdr_size = br.read(16)?;
81 if (gop_flags & 0x20) != 0 {
82 br.skip(32)?; // lock word
86 if (gop_flags & 0x40) != 0 {
87 self.tile_w = 64 << br.read(2)?;
88 self.tile_h = self.tile_w;
90 validate!(self.tile_w < 256);
91 self.luma_bands = (br.read(2)? * 3 + 1) as usize;
92 self.chroma_bands = (br.read(1)? * 3 + 1) as usize;
93 validate!((self.luma_bands == 4) || (self.luma_bands == 1));
94 validate!(self.chroma_bands == 1);
95 let pic_size_idx = br.read(4)? as usize;
98 if pic_size_idx < 15 {
99 w = INDEO5_PICTURE_SIZE_TAB[pic_size_idx][0];
100 h = INDEO5_PICTURE_SIZE_TAB[pic_size_idx][1];
102 h = br.read(13)? as usize;
103 w = br.read(13)? as usize;
105 validate!((w != 0) && (h != 0));
109 validate!((gop_flags & 0x02) == 0);
110 if self.tile_w == 0 {
114 for b in 0..self.luma_bands+self.chroma_bands {
115 self.is_hpel[b] = br.read_bool()?;
116 let mb_scale = br.read(1)?;
117 self.blk_size[b] = 8 >> br.read(1)?;
118 self.mb_size[b] = self.blk_size[b] << (1 - mb_scale);
119 let ext_tr = br.read_bool()?;
121 let end_marker = br.read(2)?;
122 validate!(end_marker == 0);
124 if (gop_flags & 0x08) != 0 {
125 let align = br.read(3)?;
126 validate!(align == 0);
128 br.skip(24)?; // transparency color
133 if br.read_bool()? { // gop extension
135 let v = br.read(16)?;
136 if (v & 0x8000) == 0 { break; }
143 return Ok(PictureHeader::new_null(ftype));
145 let flags = br.read(8)?;
147 if (flags & 0x01) != 0 {
153 if (flags & 0x10) != 0 {
154 checksum = br.read(16)?;
158 if (flags & 0x20) != 0 {
161 let in_q = (flags & 0x08) != 0;
162 self.mb_cb = br.read_ivi_codebook_desc(true, (flags & 0x40) != 0)?;
166 Ok(PictureHeader::new(ftype, self.width, self.height, self.tile_w, self.tile_h, false, self.luma_bands, self.chroma_bands, in_q))
169 #[allow(unused_variables)]
170 fn decode_band_header(&mut self, br: &mut BitReader, pic_hdr: &PictureHeader, plane_no: usize, band_no: usize) -> DecoderResult<BandHeader> {
171 let band_flags = br.read(8)?;
173 if (band_flags & 0x01) != 0 {
175 return Ok(BandHeader::new_empty(plane_no, band_no));
177 let inherit_mv = (band_flags & 0x02) != 0;
178 let has_qdelta = (band_flags & 0x04) != 0;
179 let inherit_qd = ((band_flags & 0x08) != 0) || !has_qdelta;
180 let data_size: usize;
181 if (band_flags & 0x80) != 0 {
182 data_size = br.read(24)? as usize;
183 validate!(data_size >= 4);
187 validate!(data_size <= ((br.left() / 8) as usize) + 4);
190 let mut corr_map: [u8; CORR_MAP_SIZE] = [0; CORR_MAP_SIZE];
191 if (band_flags & 0x10) != 0 {
192 num_corr = br.read(8)? as usize;
193 validate!(num_corr*2 <= CORR_MAP_SIZE);
194 for i in 0..num_corr*2 {
195 corr_map[i] = br.read(8)? as u8;
201 if (band_flags & 0x40) != 0 {
202 rvmap_idx = br.read(3)? as usize;
206 let blk_cb = br.read_ivi_codebook_desc(false, (band_flags & 0x80) != 0)?;
208 br.skip(16)?; // checksum
210 let band_q = br.read(5)?;
211 if (band_flags & 0x20) != 0 {
218 let band_id = if plane_no == 0 { band_no } else { self.luma_bands };
221 let scan = INDEO5_SCAN8X8[band_no];
224 validate!(self.blk_size[band_id] == 8);
227 tr = IVITransformType::Slant(TSize::T8x8, TDir::TwoD);
228 if self.luma_bands == 1 {
229 qintra = INDEO5_Q8_INTRA[0];
230 qinter = INDEO5_Q8_INTER[0];
232 qintra = INDEO5_Q8_INTRA[1];
233 qinter = INDEO5_Q8_INTER[1];
237 tr = IVITransformType::Slant(TSize::T8x8, TDir::Row);
238 qintra = INDEO5_Q8_INTRA[2];
239 qinter = INDEO5_Q8_INTER[2];
242 tr = IVITransformType::Slant(TSize::T8x8, TDir::Col);
243 qintra = INDEO5_Q8_INTRA[3];
244 qinter = INDEO5_Q8_INTER[3];
247 tr = IVITransformType::None(TSize::T8x8);
248 qintra = INDEO5_Q8_INTRA[4];
249 qinter = INDEO5_Q8_INTER[4];
251 _ => { unreachable!(); }
253 txtype = TxType::Transform8(TxParams8x8::new(qintra, qinter, scan));
256 validate!(self.blk_size[band_id] == 4);
257 tr = IVITransformType::Slant(TSize::T4x4, TDir::TwoD);
258 let scan = INDEO5_SCAN4X4;
259 let qintra = INDEO5_Q4_INTRA;
260 let qinter = INDEO5_Q4_INTER;
261 txtype = TxType::Transform4(TxParams4x4::new(qintra, qinter, scan));
263 _ => { unreachable!(); }
266 Ok(BandHeader::new(plane_no, band_no, self.mb_size[band_id], self.blk_size[band_id], self.is_hpel[band_id], inherit_mv, has_qdelta, inherit_qd, band_q, rvmap_idx, num_corr, corr_map, blk_cb, tr, txtype))
269 #[allow(clippy::cognitive_complexity)]
270 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<()> {
273 let band_id = if pic_hdr.luma_bands == 4 { band.band_no + 1 } else { 0 };
275 for mb_y in 0..tile.mb_h {
276 for mb_x in 0..tile.mb_w {
277 let mut mb = MB::new(tile.pos_x + mb_x * band.mb_size, tile.pos_y + mb_y * band.mb_size);
278 if !br.read_bool()? {
279 if pic_hdr.ftype.is_intra() {
280 mb.mtype = MBType::Intra;
281 } else if band.inherit_mv {
282 if let Some(tileref) = ref_tile {
283 mb.mtype = tileref.mb[mb_idx].mtype;
285 return Err(DecoderError::MissingReference);
288 mb.mtype = if br.read_bool()? { MBType::Inter } else { MBType::Intra };
290 if band.mb_size == band.blk_size {
291 mb.cbp = br.read(1)? as u8;
293 mb.cbp = br.read(4)? as u8;
298 if let Some(tileref) = ref_tile {
299 mb.qd = tileref.mb[mb_idx].qd;
300 q = calc_quant(band.quant, mb.qd);
302 return Err(DecoderError::MissingReference);
304 } else if (mb.cbp != 0) || ((band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q) {
305 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
306 q = calc_quant(band.quant, mb.qd);
308 q = band.quant as usize;
311 q = band.quant as usize;
314 if mb.mtype == MBType::Intra {
315 if band.blk_size == 8 {
316 mb.q = INDEO5_QSCALE8_INTRA[band_id][q];
318 mb.q = INDEO5_QSCALE4_INTRA[q];
321 if band.blk_size == 8 {
322 mb.q = INDEO5_QSCALE8_INTER[band_id][q];
324 mb.q = INDEO5_QSCALE4_INTER[q];
328 if mb.mtype != MBType::Intra {
330 if let Some(tileref) = ref_tile {
331 let mx = tileref.mb[mb_idx].mv_x;
332 let my = tileref.mb[mb_idx].mv_y;
337 mb.mv_x = scale_mv(mx, mv_scale);
338 mb.mv_y = scale_mv(my, mv_scale);
342 mv_y += br.read_ivi_cb_s(&self.mb_cb)?;
343 mv_x += br.read_ivi_cb_s(&self.mb_cb)?;
349 validate!(!pic_hdr.ftype.is_intra());
350 mb.mtype = MBType::Inter;
353 if (band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q {
354 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
355 let q = calc_quant(band.quant, mb.qd);
356 if mb.mtype == MBType::Intra {
357 if band.blk_size == 8 {
358 mb.q = INDEO5_QSCALE8_INTRA[band_id][q];
360 mb.q = INDEO5_QSCALE4_INTRA[q];
363 if band.blk_size == 8 {
364 mb.q = INDEO5_QSCALE8_INTER[band_id][q];
366 mb.q = INDEO5_QSCALE4_INTER[q];
371 if let Some(tileref) = ref_tile {
372 let mx = tileref.mb[mb_idx].mv_x;
373 let my = tileref.mb[mb_idx].mv_y;
378 mb.mv_x = scale_mv(mx, mv_scale);
379 mb.mv_y = scale_mv(my, mv_scale);
384 tile.mb[mb_idx] = mb;
392 fn recombine_plane(&mut self, src: &[i16], sstride: usize, dst: &mut [u8], dstride: usize, w: usize, h: usize) {
394 let mut idx1 = w / 2;
395 let mut idx2 = (h / 2) * sstride;
396 let mut idx3 = idx2 + idx1;
397 let mut bidx1 = idx1;
398 let mut bidx3 = idx3;
400 let mut oidx1 = dstride;
401 let filt_lo = |a: i16, b: i16| a + b;
402 let filt_hi = |a: i16, b: i16, c: i16| a - b * 6 + c;
404 for _ in 0..(h/2)-1 {
405 let mut b0_1 = src[idx0];
406 let mut b0_2 = src[idx0 + sstride];
407 let mut b1_1 = src[bidx1];
408 let mut b1_2 = src[idx1];
409 let mut b1_3 = filt_hi(b1_1, b1_2, src[idx1 + sstride]);
411 let mut b2_2 = src[idx2];
414 let mut b2_5 = src[idx2 + sstride];
417 let mut b3_2 = src[bidx3];
420 let mut b3_5 = src[idx3];
422 let mut b3_8 = filt_hi(b3_2, b3_5, src[idx3 + sstride]);
426 for x in 0..(w/2)-1 {
440 b0_1 = src[idx0 + x + 1];
441 b0_2 = src[idx0 + x + 1 + sstride];
442 let mut p0 = tmp0 << 4;
443 let mut p1 = (tmp0 + b0_1) << 3;
444 let mut p2 = (tmp0 + tmp1) << 3;
445 let mut p3 = (tmp0 + tmp1 + b0_1 + b0_2) << 2;
449 let tmp2 = filt_lo(tmp0, tmp1);
450 let tmp3 = filt_hi(tmp0, tmp1, b1_3);
451 b1_2 = src[ idx1 + x + 1];
452 b1_1 = src[bidx1 + x + 1];
453 b1_3 = filt_hi(b1_1, b1_2, src[idx1 + x + 1 + sstride]);
455 p1 += (tmp2 + b1_1 + b1_2) << 2;
457 p3 += (tmp3 + b1_3) << 1;
459 b2_3 = src[idx2 + x + 1];
460 b2_6 = src[idx2 + x + 1 + sstride];
461 let tmp0 = filt_lo(b2_1, b2_2);
462 let tmp1 = filt_hi(b2_1, b2_2, b2_3);
465 p2 += (tmp0 + filt_lo(b2_4, b2_5)) << 2;
466 p3 += (tmp1 + filt_hi(b2_4, b2_5, b2_6)) << 1;
468 b3_6 = src[idx3 + x + 1];
469 b3_3 = src[bidx3 + x + 1];
470 b3_9 = filt_hi(b3_3, b3_6, src[idx3 + x + 1 + sstride]);
471 let tmp0 = b3_1 + b3_4;
472 let tmp1 = b3_2 + b3_5;
473 let tmp2 = b3_3 + b3_6;
474 p0 += filt_lo(tmp0, tmp1) << 2;
475 p1 += filt_hi(tmp0, tmp1, tmp2) << 1;
476 p2 += filt_lo(b3_7, b3_8) << 1;
477 p3 += filt_hi(b3_7, b3_8, b3_9) << 0;
479 dst[oidx0 + x * 2 + 0] = clip8((p0 >> 6) + 128);
480 dst[oidx0 + x * 2 + 1] = clip8((p1 >> 6) + 128);
481 dst[oidx1 + x * 2 + 0] = clip8((p2 >> 6) + 128);
482 dst[oidx1 + x * 2 + 1] = clip8((p3 >> 6) + 128);
490 oidx0 += dstride * 2;
491 oidx1 += dstride * 2;
496 struct Indeo5Decoder {
497 info: NACodecInfoRef,
503 fn new(scalable: bool) -> Self {
505 info: NACodecInfo::new_dummy(),
506 dec: IVIDecoder::new(scalable),
507 ip: Indeo5Parser::new(),
512 impl NADecoder for Indeo5Decoder {
513 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
514 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
515 let w = vinfo.get_width();
516 let h = vinfo.get_height();
517 let f = vinfo.is_flipped();
518 let fmt = formats::YUV410_FORMAT;
519 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, f, fmt));
520 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
523 Err(DecoderError::InvalidData)
526 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
527 let src = pkt.get_buffer();
528 let mut br = BitReader::new(src.as_slice(), BitReaderMode::LE);
530 let bufinfo = self.dec.decode_frame(&mut self.ip, &mut br)?;
531 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
532 frm.set_keyframe(self.dec.is_intra());
533 frm.set_frame_type(self.dec.get_frame_type());
536 fn flush(&mut self) {
541 impl NAOptionHandler for Indeo5Decoder {
542 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
543 fn set_options(&mut self, _options: &[NAOption]) { }
544 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
547 const INDEO5_PICTURE_SIZE_TAB: [[usize; 2]; 15] = [
548 [640, 480], [320, 240], [160, 120], [704, 480], [352, 240], [352, 288], [176, 144],
549 [240, 180], [640, 240], [704, 240], [80, 60], [88, 72], [0, 0], [0, 0], [0, 0]
552 const INDEO5_FRAME_TYPE: [IVIFrameType; 5] = [
553 IVIFrameType::Intra, IVIFrameType::Inter, IVIFrameType::InterScal,
554 IVIFrameType::InterDroppable, IVIFrameType::NULL,
557 const INDEO5_QUANT8X8_INTRA: [[u16; 64]; 5] = [
559 0x1a, 0x2e, 0x36, 0x42, 0x46, 0x4a, 0x4e, 0x5a,
560 0x2e, 0x32, 0x3e, 0x42, 0x46, 0x4e, 0x56, 0x6a,
561 0x36, 0x3e, 0x3e, 0x44, 0x4a, 0x54, 0x66, 0x72,
562 0x42, 0x42, 0x44, 0x4a, 0x52, 0x62, 0x6c, 0x7a,
563 0x46, 0x46, 0x4a, 0x52, 0x5e, 0x66, 0x72, 0x8e,
564 0x4a, 0x4e, 0x54, 0x62, 0x66, 0x6e, 0x86, 0xa6,
565 0x4e, 0x56, 0x66, 0x6c, 0x72, 0x86, 0x9a, 0xca,
566 0x5a, 0x6a, 0x72, 0x7a, 0x8e, 0xa6, 0xca, 0xfe,
568 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
569 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
570 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
571 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
572 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
573 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
574 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
575 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
577 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
578 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
579 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
580 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
581 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
582 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
583 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
584 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
586 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
587 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
588 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
589 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
590 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
591 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
592 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
593 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
595 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
596 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
597 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
598 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
599 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
600 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
601 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
602 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
605 const INDEO5_QUANT8X8_INTER: [[u16; 64]; 5] = [
607 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
608 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
609 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
610 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
611 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
612 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
613 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
614 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
616 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
617 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
618 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
619 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
620 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
621 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
622 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
623 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
625 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
626 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
627 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
628 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
629 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
630 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
631 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
632 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
634 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
635 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
636 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
637 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
638 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
639 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
640 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
641 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
643 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
644 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
645 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
646 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
647 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
648 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
649 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
650 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
653 const INDEO5_QUANT4X4_INTRA: [u16; 16] = [
654 0x1e, 0x3e, 0x4a, 0x52,
655 0x3e, 0x4a, 0x52, 0x5e,
656 0x4a, 0x52, 0x5e, 0x7a,
657 0x52, 0x5e, 0x7a, 0x92
659 const INDEO5_QUANT4X4_INTER: [u16; 16] = [
660 0x1e, 0x3e, 0x4a, 0x52,
661 0x3e, 0x4a, 0x52, 0x56,
662 0x4a, 0x52, 0x56, 0x5e,
663 0x52, 0x56, 0x5e, 0x66
665 const INDEO5_Q8_INTRA: [&[u16; 64]; 5] = [
666 &INDEO5_QUANT8X8_INTRA[0], &INDEO5_QUANT8X8_INTRA[1], &INDEO5_QUANT8X8_INTRA[2],
667 &INDEO5_QUANT8X8_INTRA[3], &INDEO5_QUANT8X8_INTRA[4],
669 const INDEO5_Q8_INTER: [&[u16; 64]; 5] = [
670 &INDEO5_QUANT8X8_INTER[0], &INDEO5_QUANT8X8_INTER[1], &INDEO5_QUANT8X8_INTER[2],
671 &INDEO5_QUANT8X8_INTER[3], &INDEO5_QUANT8X8_INTER[4],
673 const INDEO5_Q4_INTRA: &[u16; 16] = &INDEO5_QUANT4X4_INTRA;
674 const INDEO5_Q4_INTER: &[u16; 16] = &INDEO5_QUANT4X4_INTER;
676 const INDEO5_SCAN8X8: [&[usize; 64]; 4] = [
677 &ZIGZAG, &IVI_SCAN_8X8_VER, &IVI_SCAN_8X8_HOR, &IVI_SCAN_8X8_HOR
679 const INDEO5_SCAN4X4: &[usize; 16] = &IVI_SCAN_4X4;
681 const INDEO5_QSCALE8_INTRA: [[u8; 24]; 5] = [
683 0x0b, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
684 0x22, 0x24, 0x27, 0x28, 0x2a, 0x2d, 0x2f, 0x31, 0x34, 0x37, 0x39, 0x3c,
686 0x01, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x28, 0x2c,
687 0x30, 0x34, 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x52, 0x58, 0x5e, 0x65, 0x6c,
689 0x13, 0x22, 0x27, 0x2a, 0x2d, 0x33, 0x36, 0x3c, 0x41, 0x45, 0x49, 0x4e,
690 0x53, 0x58, 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x7c, 0x82, 0x88, 0x8e, 0x95,
692 0x13, 0x1f, 0x21, 0x24, 0x27, 0x29, 0x2d, 0x2f, 0x34, 0x37, 0x3a, 0x3d,
693 0x40, 0x44, 0x48, 0x4c, 0x4f, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6b,
695 0x31, 0x42, 0x47, 0x47, 0x4d, 0x52, 0x58, 0x58, 0x5d, 0x63, 0x67, 0x6b,
696 0x6f, 0x73, 0x78, 0x7c, 0x80, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa4,
699 const INDEO5_QSCALE8_INTER: [[u8; 24]; 5] = [
701 0x0b, 0x11, 0x13, 0x14, 0x15, 0x16, 0x18, 0x1a, 0x1b, 0x1d, 0x20, 0x22,
702 0x23, 0x25, 0x28, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x41, 0x44, 0x4a,
704 0x07, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
705 0x3a, 0x3f, 0x44, 0x4a, 0x50, 0x56, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x7e,
707 0x15, 0x25, 0x28, 0x2d, 0x30, 0x34, 0x3a, 0x3d, 0x42, 0x48, 0x4c, 0x51,
708 0x56, 0x5b, 0x60, 0x65, 0x6b, 0x70, 0x76, 0x7c, 0x82, 0x88, 0x8f, 0x97,
710 0x13, 0x1f, 0x20, 0x22, 0x25, 0x28, 0x2b, 0x2d, 0x30, 0x33, 0x36, 0x39,
711 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4b, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62,
713 0x3c, 0x52, 0x58, 0x5d, 0x63, 0x68, 0x68, 0x6d, 0x73, 0x78, 0x7c, 0x80,
714 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa3, 0xa9, 0xad, 0xb1, 0xb5, 0xba
717 const INDEO5_QSCALE4_INTRA: [u8; 24] = [
718 0x01, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14,
719 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
721 const INDEO5_QSCALE4_INTER: [u8; 24] = [
722 0x0b, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
723 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
726 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
727 Box::new(Indeo5Decoder::new(false))
730 pub fn get_decoder_scalable() -> Box<dyn NADecoder + Send> {
731 Box::new(Indeo5Decoder::new(true))
736 use nihav_core::codecs::RegisteredDecoders;
737 use nihav_core::demuxers::RegisteredDemuxers;
738 use nihav_codec_support::test::dec_video::*;
739 use crate::indeo_register_all_decoders;
740 use nihav_commonfmt::generic_register_all_demuxers;
743 let mut dmx_reg = RegisteredDemuxers::new();
744 generic_register_all_demuxers(&mut dmx_reg);
745 let mut dec_reg = RegisteredDecoders::new();
746 indeo_register_all_decoders(&mut dec_reg);
748 // sample: https://samples.mplayerhq.hu/V-codecs/IV50/sample.avi
749 test_decoding("avi", "indeo5", "assets/Indeo/IV5/sample.avi", Some(100),
750 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
751 [0xcb451428, 0x5c8b1519, 0x96a81eda, 0x0c9cccf0],
752 [0x7554e11f, 0x3b60d661, 0x3bcd14b5, 0x036dcc16],
753 [0x92a20e68, 0x83418e5c, 0x640b6786, 0x9c867622],
754 [0x0b2cde46, 0x67b68ac5, 0xc152edc6, 0xda591ac3],
755 [0x9034354b, 0x81c66b57, 0xcb671505, 0x0062a75f],
756 [0x38606276, 0x547b83df, 0x4a22f079, 0x2afb8362],
757 [0x0d3fe5df, 0xadc8b042, 0x4ee9cb0d, 0xf9b79b11],
758 [0x2b0b1ddb, 0x612a163a, 0x47b5afc8, 0xeb4c79a5],
759 [0x8eadd17e, 0xc4c8c932, 0x57508232, 0x643e1498],
760 [0x0dcc7da2, 0x7b059de2, 0x0ff46dd9, 0x04c11f77],
761 [0xe358728a, 0xe42fc515, 0x8f5cc35f, 0x02973436],
762 [0x66847a32, 0x884b41f0, 0x0c3062bc, 0xb58d923b],
763 [0x555b2711, 0xbcb54b64, 0x5a6141e5, 0xa7b5cc44],
764 [0x0f326348, 0x5d36cb21, 0xe7f8210d, 0x8a43c2c5],
765 [0x4e7b18a3, 0x42146bbb, 0x04c4cf2b, 0x78fe3c0d],
766 [0x220f0721, 0xe681444a, 0x974bf97b, 0x9b658cfe],
767 [0x2d5a5f22, 0x23bd1ed8, 0xed383633, 0x5905422d],
768 [0x982ae872, 0x17b8f765, 0x3d1735af, 0xa2872d9f],
769 [0x743a2819, 0x392d856e, 0xf2ee64ca, 0x63101b79],
770 [0x0c9e0aa7, 0x79414f6b, 0x162c19a6, 0x86d69b96],
771 [0x3eae05ad, 0xbff350bb, 0x97e8a205, 0xfa8e42b2],
772 [0x0ccae893, 0xdfcf9885, 0xef39d053, 0x0a655a73],
773 [0x75e98d11, 0x83fab601, 0xe836a6d2, 0xb2a7c7cb],
774 [0x1565b1ce, 0x8ab813c5, 0xb1658413, 0xeebaf068],
775 [0xe2bb47dd, 0xc3c277a7, 0x8c6bd4be, 0xbbca989d],
776 [0xea97912e, 0xcd224d66, 0x76fd31c2, 0x7a854abf],
777 [0x8eebb842, 0x0534b043, 0xf55a3b65, 0x3868b974],
778 [0x82c55a0b, 0x5d18c3c8, 0xbdc40fd1, 0x5d11f2e2],
779 [0xda46bff0, 0xedc1e115, 0x77cb8b8a, 0xf5fd6ddf],
780 [0x7c9c19e9, 0x4188e742, 0xd8c2cbaf, 0x0ecd1aaa],
781 [0x33145d5b, 0x0c8e2f61, 0x2ab4b213, 0xf1cf9ebe],
782 [0x64f561e1, 0xae2aa75b, 0xe4d56a57, 0xdcc54d10],
783 [0x25545f02, 0x8c271a6a, 0x6b676110, 0xa348628b],
784 [0x8c33d2d7, 0x7dfc25a0, 0xbdb68979, 0xac7ce8f1],
785 [0x8adc7126, 0x71c4d390, 0x4b47aeed, 0x444dbd2b],
786 [0xaab41fbc, 0x2c6de4d8, 0x83b61f31, 0xc68879b1],
787 [0x90961b3a, 0x9a1d4b51, 0xbf34d9d1, 0xe90137a7],
788 [0x2e988439, 0x2d7e67ec, 0x9bfd6405, 0xd851ee32],
789 [0x3b2b45e8, 0x76225018, 0xa2632614, 0x06234ca9],
790 [0xd52dc6af, 0x36c0d185, 0x90f4a9d2, 0x0b024990],
791 [0x5ed3ebb2, 0xb19b49a2, 0xd691c27a, 0x7d52941c],
792 [0xcb22479a, 0x3713b23d, 0x24abe31b, 0x45877b4e],
793 [0x143aa9f1, 0xe7709011, 0xa6ef993b, 0x8e4f33e2],
794 [0xc8b1ad16, 0x820b4f85, 0xe9d1482a, 0x806af90c],
795 [0x4f1eda2b, 0xa73eac8c, 0x8004e66b, 0xa0804e11],
796 [0x668ceb7b, 0xad020ed3, 0x90687534, 0x96eded7e],
797 [0x8bbd77d0, 0x29fc1ae4, 0xc41fb7cf, 0x31b08f08],
798 [0x02d07857, 0x4ed79f55, 0x89cfe082, 0x97167616],
799 [0xd99dbf57, 0x87ef7406, 0x59c9abdf, 0xf664be32],
800 [0x6d2bd834, 0x6b61d6e5, 0x3fd282ce, 0xbc877248],
801 [0xb4dbab3f, 0x7006dded, 0x39608927, 0x9773b83e],
802 [0x6e1f21e8, 0xff1a76c0, 0x197dd40b, 0x3cedee3d],
803 [0x551f64b8, 0x98161c0f, 0xb93103a7, 0xac12366e],
804 [0x6854311c, 0x6bc09f24, 0x226ec3e9, 0x91507815],
805 [0xb106d988, 0x6c9cda70, 0xebf972ce, 0x97b1efa8],
806 [0x91b8c27b, 0x257ff731, 0x1589d60d, 0xcb2b3de9],
807 [0x819d3677, 0xa6afca81, 0x3d2b4ba9, 0xba8cc70f],
808 [0xfb2c67fa, 0x75af7785, 0xde6133b0, 0x1bb59f2c],
809 [0xceb72cd4, 0x8c581ccb, 0x803233f2, 0xb88a174b],
810 [0xe2811f64, 0xa488d42c, 0x3a62a574, 0x918df881],
811 [0x95a66cf8, 0x0529a646, 0x3bc15b00, 0xfb0eedc9],
812 [0x1e90f3ce, 0xa8f81b7f, 0x13d5445c, 0xc969a914],
813 [0x25287783, 0x19869a3d, 0x93672c2a, 0x07a57f5e],
814 [0x44dfacc0, 0x528ae192, 0x141721a9, 0x85b2a3d9],
815 [0x45f13c20, 0x90b07bb5, 0x9a155a2f, 0x3933fb77],
816 [0x40531c62, 0x437c14b6, 0xc03c8d39, 0x35f5ae87],
817 [0x32e58909, 0xdb068147, 0xa967c6cf, 0x33d9416a],
818 [0xa8c44523, 0x12a89332, 0xddd09ccf, 0x7b04c0d2],
819 [0xae00b8b4, 0x589efb18, 0xf8c1dec1, 0xfd9d867f],
820 [0xe2fc1828, 0x5f7a3b28, 0x72de1c32, 0xc01e6ea6],
821 [0x8be4c525, 0xcde70d98, 0xd7f5f5a1, 0xf39faadf],
822 [0x9c744944, 0x00a491f4, 0x665707a9, 0xa93fad9d],
823 [0x036f2525, 0x827ddd36, 0x989c99db, 0x6b9455fc],
824 [0x52c6b5d2, 0xfd4e23f9, 0xb620b0da, 0x462d7566],
825 [0x00ba54e6, 0xfe9021ae, 0xa8c65c37, 0xda979c78],
826 [0x6e11dca0, 0x41887539, 0x2b9781af, 0x94e6b930],
827 [0x086be7db, 0xcce50438, 0x2d94bc75, 0x00f4ebfe],
828 [0xd2216f7c, 0x33321d48, 0x8ce0f144, 0x34c1fd4f],
829 [0x9083c0fc, 0x6cb46451, 0xd8202b2f, 0xae5db326],
830 [0xe894be71, 0x0e1b6c67, 0x70d5e81f, 0x2075d5ff],
831 [0x7f9f10f7, 0x0a8df81d, 0x406cb9cc, 0x524879b5],
832 [0x4c329904, 0x6f939b2c, 0xd49f8bba, 0xad54aee5],
833 [0x92d68b43, 0x2c631f71, 0x98329455, 0x91971f7f],
834 [0x1b06289e, 0x4879af78, 0xc66d7c82, 0xda19e863],
835 [0x399741da, 0xd362b007, 0x8f94e50c, 0xcdd23209],
836 [0xa2063194, 0xc67f368a, 0x83462433, 0xe719c2db],
837 [0x9da0bfd1, 0x8977f90e, 0x7f2f4172, 0xab5213ff],
838 [0x82823c8f, 0xd7cdd62e, 0xac3a59ba, 0x17ef0fb9],
839 [0xb3e51375, 0xfebb3ad3, 0x54ffdda4, 0xfbf44cf9],
840 [0x261f8183, 0x8328012b, 0x47d7e527, 0xc19cca15],
841 [0xef25bfc7, 0x79460e21, 0xeb65f2ef, 0x63731f9f],
842 [0xd14fc8f5, 0x209123ea, 0xf5f1cf21, 0x93f84381],
843 [0xf5375f67, 0x0846d9a1, 0x07aaf802, 0xe753fa08],
844 [0x65a56edd, 0x4ea28e39, 0x10d17a7b, 0xa9445d87],
845 [0xbeb8eb53, 0xd01b9c94, 0xd1d15e41, 0x639307cc],
846 [0xc2272546, 0xd1701452, 0x2fe76cbd, 0xe1dd7697],
847 [0xff6c09f6, 0x1d7804c2, 0x1ca3a2f8, 0x3fffb67b],
848 [0xfe48f3fd, 0x0046ec25, 0x1ed4401a, 0xd67f4ed6],
849 [0x46c3c72f, 0x8398b8c1, 0xe26aff08, 0x0dd1ecbb],
850 [0xc7f49f94, 0xca32d87c, 0x2e063788, 0x0229c6c0],
851 [0xa9ec4820, 0x576c7877, 0xc21211c3, 0x502af3d3]]));
854 fn test_indeo5_scalable() {
855 let mut dmx_reg = RegisteredDemuxers::new();
856 crate::indeo_register_all_demuxers(&mut dmx_reg);
857 let mut dec_reg = RegisteredDecoders::new();
858 indeo_register_all_decoders(&mut dec_reg);
860 // sample is a trailer for Heart of Darkness game
861 test_decoding("ivf", "indeo5s", "assets/Indeo/TRAILERIIE.IVF", Some(31),
862 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
863 [0xd6c5b653, 0x082e25e6, 0x90c0c112, 0xfa7f46c8],
864 [0x75e96cdb, 0x198cdb95, 0xde228898, 0x3cf68cfc],
865 [0xb1bed823, 0xad632d3e, 0x2e509143, 0x5e59e911],
866 [0xe3e7e2f0, 0xb8c7d968, 0xcb0b9273, 0xb7e48207],
867 [0xc6ef6975, 0xe0cc0b05, 0x983f7888, 0x64c9b89f],
868 [0xda936fad, 0xa170c0f2, 0x889a3e0c, 0xfef1a626],
869 [0xa85ccb32, 0x2c6847c4, 0x3259f48d, 0xe7e1b47b],
870 [0xedbb8256, 0x1e889428, 0xbc268e66, 0xf41d15f1],
871 [0xd6869899, 0x5121410d, 0xb12dfc96, 0x7dc67a24],
872 [0x9a594172, 0x3d9269c7, 0x1a7277fd, 0xe597dd01],
873 [0x3af07da6, 0x1968872d, 0xf7fc190e, 0x5c61c184],
874 [0xd8eec91e, 0x1aa55dfe, 0x9703a2ce, 0x1ce30990],
875 [0xea4821ae, 0x44ab9f2f, 0xa882bccb, 0xcae50f58],
876 [0x6ddfb989, 0x1affb8ad, 0x7bb2d74a, 0xc28e1a1d],
877 [0x4c9aa98d, 0xb6b2ddd2, 0xfb533baf, 0xc2d90242],
878 [0x332c8e68, 0x47a942ea, 0x6ced7891, 0x7667ad97],
879 [0x940ad339, 0x448ea27c, 0x3b7d0328, 0x4a4cf19f],
880 [0x08a60746, 0x399949ef, 0xce81ef06, 0xbc1d7d6b],
881 [0x4b5e51d0, 0xe26d32f1, 0xb1872663, 0xa70c6e65],
882 [0x428fb122, 0xf3a55f40, 0xdc4316d7, 0xe2765f76],
883 [0xcce4fa35, 0xb47d9848, 0xcbe7fef4, 0x5285022b],
884 [0xde30af92, 0x28a04fe2, 0x317f6be8, 0xde5c161c],
885 [0xe1f00bf7, 0xab2d4e91, 0x9eb674e6, 0x3b863314],
886 [0xac944130, 0xa5d1171a, 0xe8a0b591, 0x09d7652d],
887 [0x17c17612, 0x7cd40f67, 0x7aec3009, 0x2405b862],
888 [0x1d88eb87, 0x44496fb8, 0x58665011, 0xc545f745],
889 [0x04c32cce, 0x38eca98f, 0xd6227880, 0xc7d0f2bf],
890 [0x76d9dcb8, 0x92a35e1a, 0x2b968e96, 0x2c362e4a],
891 [0xda4904e7, 0x2d9d0a74, 0x63932049, 0x7bf9f0de],
892 [0x4f18931c, 0x61b9046f, 0xf5eac763, 0x0c1826d5],
893 [0x823d8746, 0x17debe43, 0xe256fda4, 0xdd1a6832],
894 [0x0bb4b91d, 0xf66f1c19, 0x166ee91a, 0x69379e27]]));