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;
186 validate!(data_size <= ((br.left() / 8) as usize));
189 let mut corr_map: [u8; CORR_MAP_SIZE] = [0; CORR_MAP_SIZE];
190 if (band_flags & 0x10) != 0 {
191 num_corr = br.read(8)? as usize;
192 validate!(num_corr*2 <= CORR_MAP_SIZE);
193 for i in 0..num_corr*2 {
194 corr_map[i] = br.read(8)? as u8;
200 if (band_flags & 0x40) != 0 {
201 rvmap_idx = br.read(3)? as usize;
205 let blk_cb = br.read_ivi_codebook_desc(false, (band_flags & 0x80) != 0)?;
207 br.skip(16)?; // checksum
209 let band_q = br.read(5)?;
210 if (band_flags & 0x20) != 0 {
217 let band_id = if plane_no == 0 { band_no } else { self.luma_bands };
220 let scan = INDEO5_SCAN8X8[band_no];
223 validate!(self.blk_size[band_id] == 8);
226 tr = IVITransformType::Slant(TSize::T8x8, TDir::TwoD);
227 if self.luma_bands == 1 {
228 qintra = INDEO5_Q8_INTRA[0];
229 qinter = INDEO5_Q8_INTER[0];
231 qintra = INDEO5_Q8_INTRA[1];
232 qinter = INDEO5_Q8_INTER[1];
236 tr = IVITransformType::Slant(TSize::T8x8, TDir::Row);
237 qintra = INDEO5_Q8_INTRA[2];
238 qinter = INDEO5_Q8_INTER[2];
241 tr = IVITransformType::Slant(TSize::T8x8, TDir::Col);
242 qintra = INDEO5_Q8_INTRA[3];
243 qinter = INDEO5_Q8_INTER[3];
246 tr = IVITransformType::None(TSize::T8x8);
247 qintra = INDEO5_Q8_INTRA[4];
248 qinter = INDEO5_Q8_INTER[4];
250 _ => { unreachable!(); }
252 txtype = TxType::Transform8(TxParams8x8::new(qintra, qinter, scan));
255 validate!(self.blk_size[band_id] == 4);
256 tr = IVITransformType::Slant(TSize::T4x4, TDir::TwoD);
257 let scan = INDEO5_SCAN4X4;
258 let qintra = INDEO5_Q4_INTRA;
259 let qinter = INDEO5_Q4_INTER;
260 txtype = TxType::Transform4(TxParams4x4::new(qintra, qinter, scan));
262 _ => { unreachable!(); }
265 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))
268 #[allow(clippy::cognitive_complexity)]
269 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<()> {
272 let band_id = if pic_hdr.luma_bands == 4 { band.band_no + 1 } else { 0 };
274 for mb_y in 0..tile.mb_h {
275 for mb_x in 0..tile.mb_w {
276 let mut mb = MB::new(tile.pos_x + mb_x * band.mb_size, tile.pos_y + mb_y * band.mb_size);
277 if !br.read_bool()? {
278 if pic_hdr.ftype.is_intra() {
279 mb.mtype = MBType::Intra;
280 } else if band.inherit_mv {
281 if let Some(tileref) = ref_tile {
282 mb.mtype = tileref.mb[mb_idx].mtype;
284 return Err(DecoderError::MissingReference);
287 mb.mtype = if br.read_bool()? { MBType::Inter } else { MBType::Intra };
289 if band.mb_size == band.blk_size {
290 mb.cbp = br.read(1)? as u8;
292 mb.cbp = br.read(4)? as u8;
297 if let Some(tileref) = ref_tile {
298 mb.qd = tileref.mb[mb_idx].qd;
299 q = calc_quant(band.quant, mb.qd);
301 return Err(DecoderError::MissingReference);
303 } else if (mb.cbp != 0) || ((band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q) {
304 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
305 q = calc_quant(band.quant, mb.qd);
307 q = band.quant as usize;
310 q = band.quant as usize;
313 if mb.mtype == MBType::Intra {
314 if band.blk_size == 8 {
315 mb.q = INDEO5_QSCALE8_INTRA[band_id][q];
317 mb.q = INDEO5_QSCALE4_INTRA[q];
320 if band.blk_size == 8 {
321 mb.q = INDEO5_QSCALE8_INTER[band_id][q];
323 mb.q = INDEO5_QSCALE4_INTER[q];
327 if mb.mtype != MBType::Intra {
329 if let Some(tileref) = ref_tile {
330 let mx = tileref.mb[mb_idx].mv_x;
331 let my = tileref.mb[mb_idx].mv_y;
336 mb.mv_x = scale_mv(mx, mv_scale);
337 mb.mv_y = scale_mv(my, mv_scale);
341 mv_y += br.read_ivi_cb_s(&self.mb_cb)?;
342 mv_x += br.read_ivi_cb_s(&self.mb_cb)?;
348 validate!(!pic_hdr.ftype.is_intra());
349 mb.mtype = MBType::Inter;
352 if (band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q {
353 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
354 let q = calc_quant(band.quant, mb.qd);
355 if mb.mtype == MBType::Intra {
356 if band.blk_size == 8 {
357 mb.q = INDEO5_QSCALE8_INTRA[band_id][q];
359 mb.q = INDEO5_QSCALE4_INTRA[q];
362 if band.blk_size == 8 {
363 mb.q = INDEO5_QSCALE8_INTER[band_id][q];
365 mb.q = INDEO5_QSCALE4_INTER[q];
370 if let Some(tileref) = ref_tile {
371 let mx = tileref.mb[mb_idx].mv_x;
372 let my = tileref.mb[mb_idx].mv_y;
377 mb.mv_x = scale_mv(mx, mv_scale);
378 mb.mv_y = scale_mv(my, mv_scale);
383 tile.mb[mb_idx] = mb;
391 fn recombine_plane(&mut self, src: &[i16], sstride: usize, dst: &mut [u8], dstride: usize, w: usize, h: usize) {
393 let mut idx1 = w / 2;
394 let mut idx2 = (h / 2) * sstride;
395 let mut idx3 = idx2 + idx1;
396 let mut bidx1 = idx1;
397 let mut bidx3 = idx3;
399 let mut oidx1 = dstride;
400 let filt_lo = |a: i16, b: i16| a + b;
401 let filt_hi = |a: i16, b: i16, c: i16| a - b * 6 + c;
404 let mut b0_1 = src[idx0];
405 let mut b0_2 = src[idx0 + sstride];
406 let mut b1_1 = src[bidx1];
407 let mut b1_2 = src[idx1];
408 let mut b1_3 = filt_hi(b1_1, b1_2, src[idx1 + sstride]);
410 let mut b2_2 = src[idx2];
413 let mut b2_5 = src[idx2 + sstride];
416 let mut b3_2 = src[bidx3];
419 let mut b3_5 = src[idx3];
421 let mut b3_8 = filt_hi(b3_2, b3_5, src[idx3 + sstride]);
439 b0_1 = src[idx0 + x + 1];
440 b0_2 = src[idx0 + x + 1 + sstride];
441 let mut p0 = tmp0 << 4;
442 let mut p1 = (tmp0 + b0_1) << 3;
443 let mut p2 = (tmp0 + tmp1) << 3;
444 let mut p3 = (tmp0 + tmp1 + b0_1 + b0_2) << 2;
448 let tmp2 = filt_lo(tmp0, tmp1);
449 let tmp3 = filt_hi(tmp0, tmp1, b1_3);
450 b1_2 = src[ idx1 + x + 1];
451 b1_1 = src[bidx1 + x + 1];
452 b1_3 = filt_hi(b1_1, b1_2, src[idx1 + x + 1 + sstride]);
454 p1 += (tmp2 + b1_1 + b1_2) << 2;
456 p3 += (tmp3 + b1_3) << 1;
458 b2_3 = src[idx2 + x + 1];
459 b2_6 = src[idx2 + x + 1 + sstride];
460 let tmp0 = filt_lo(b2_1, b2_2);
461 let tmp1 = filt_hi(b2_1, b2_2, b2_3);
464 p2 += (tmp0 + filt_lo(b2_4, b2_5)) << 2;
465 p3 += (tmp1 + filt_hi(b2_4, b2_5, b2_6)) << 1;
467 b3_6 = src[idx3 + x + 1];
468 b3_3 = src[bidx3 + x + 1];
469 b3_9 = filt_hi(b3_3, b3_6, src[idx3 + x + 1 + sstride]);
470 let tmp0 = b3_1 + b3_4;
471 let tmp1 = b3_2 + b3_5;
472 let tmp2 = b3_3 + b3_6;
473 p0 += filt_lo(tmp0, tmp1) << 2;
474 p1 += filt_hi(tmp0, tmp1, tmp2) << 1;
475 p2 += filt_lo(b3_7, b3_8) << 1;
476 p3 += filt_hi(b3_7, b3_8, b3_9) << 0;
478 dst[oidx0 + x * 2 + 0] = clip8((p0 >> 6) + 128);
479 dst[oidx0 + x * 2 + 1] = clip8((p1 >> 6) + 128);
480 dst[oidx1 + x * 2 + 0] = clip8((p2 >> 6) + 128);
481 dst[oidx1 + x * 2 + 1] = clip8((p3 >> 6) + 128);
489 oidx0 += dstride * 2;
490 oidx1 += dstride * 2;
495 struct Indeo5Decoder {
496 info: NACodecInfoRef,
502 fn new(scalable: bool) -> Self {
504 info: NACodecInfo::new_dummy(),
505 dec: IVIDecoder::new(scalable),
506 ip: Indeo5Parser::new(),
511 impl NADecoder for Indeo5Decoder {
512 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
513 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
514 let w = vinfo.get_width();
515 let h = vinfo.get_height();
516 let f = vinfo.is_flipped();
517 let fmt = formats::YUV410_FORMAT;
518 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, f, fmt));
519 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
522 Err(DecoderError::InvalidData)
525 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
526 let src = pkt.get_buffer();
527 let mut br = BitReader::new(src.as_slice(), BitReaderMode::LE);
529 let bufinfo = self.dec.decode_frame(&mut self.ip, &mut br)?;
530 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
531 frm.set_keyframe(self.dec.is_intra());
532 frm.set_frame_type(self.dec.get_frame_type());
535 fn flush(&mut self) {
540 impl NAOptionHandler for Indeo5Decoder {
541 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
542 fn set_options(&mut self, _options: &[NAOption]) { }
543 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
546 const INDEO5_PICTURE_SIZE_TAB: [[usize; 2]; 15] = [
547 [640, 480], [320, 240], [160, 120], [704, 480], [352, 240], [352, 288], [176, 144],
548 [240, 180], [640, 240], [704, 240], [80, 60], [88, 72], [0, 0], [0, 0], [0, 0]
551 const INDEO5_FRAME_TYPE: [IVIFrameType; 5] = [
552 IVIFrameType::Intra, IVIFrameType::Inter, IVIFrameType::InterScal,
553 IVIFrameType::InterDroppable, IVIFrameType::NULL,
556 const INDEO5_QUANT8X8_INTRA: [[u16; 64]; 5] = [
558 0x1a, 0x2e, 0x36, 0x42, 0x46, 0x4a, 0x4e, 0x5a,
559 0x2e, 0x32, 0x3e, 0x42, 0x46, 0x4e, 0x56, 0x6a,
560 0x36, 0x3e, 0x3e, 0x44, 0x4a, 0x54, 0x66, 0x72,
561 0x42, 0x42, 0x44, 0x4a, 0x52, 0x62, 0x6c, 0x7a,
562 0x46, 0x46, 0x4a, 0x52, 0x5e, 0x66, 0x72, 0x8e,
563 0x4a, 0x4e, 0x54, 0x62, 0x66, 0x6e, 0x86, 0xa6,
564 0x4e, 0x56, 0x66, 0x6c, 0x72, 0x86, 0x9a, 0xca,
565 0x5a, 0x6a, 0x72, 0x7a, 0x8e, 0xa6, 0xca, 0xfe,
567 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
568 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
569 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
570 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
571 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
572 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
573 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
574 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
576 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
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,
585 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
586 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
587 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
588 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
589 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
590 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
591 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
592 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
594 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
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,
604 const INDEO5_QUANT8X8_INTER: [[u16; 64]; 5] = [
606 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
607 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
608 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
609 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
610 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
611 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
612 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
613 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
615 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
616 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
617 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
618 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
619 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
620 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
621 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
622 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
624 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
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,
633 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
634 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
635 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
636 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
637 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
638 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
639 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
640 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
642 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
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,
652 const INDEO5_QUANT4X4_INTRA: [u16; 16] = [
653 0x1e, 0x3e, 0x4a, 0x52,
654 0x3e, 0x4a, 0x52, 0x5e,
655 0x4a, 0x52, 0x5e, 0x7a,
656 0x52, 0x5e, 0x7a, 0x92
658 const INDEO5_QUANT4X4_INTER: [u16; 16] = [
659 0x1e, 0x3e, 0x4a, 0x52,
660 0x3e, 0x4a, 0x52, 0x56,
661 0x4a, 0x52, 0x56, 0x5e,
662 0x52, 0x56, 0x5e, 0x66
664 const INDEO5_Q8_INTRA: [&[u16; 64]; 5] = [
665 &INDEO5_QUANT8X8_INTRA[0], &INDEO5_QUANT8X8_INTRA[1], &INDEO5_QUANT8X8_INTRA[2],
666 &INDEO5_QUANT8X8_INTRA[3], &INDEO5_QUANT8X8_INTRA[4],
668 const INDEO5_Q8_INTER: [&[u16; 64]; 5] = [
669 &INDEO5_QUANT8X8_INTER[0], &INDEO5_QUANT8X8_INTER[1], &INDEO5_QUANT8X8_INTER[2],
670 &INDEO5_QUANT8X8_INTER[3], &INDEO5_QUANT8X8_INTER[4],
672 const INDEO5_Q4_INTRA: &[u16; 16] = &INDEO5_QUANT4X4_INTRA;
673 const INDEO5_Q4_INTER: &[u16; 16] = &INDEO5_QUANT4X4_INTER;
675 const INDEO5_SCAN8X8: [&[usize; 64]; 4] = [
676 &ZIGZAG, &IVI_SCAN_8X8_VER, &IVI_SCAN_8X8_HOR, &IVI_SCAN_8X8_HOR
678 const INDEO5_SCAN4X4: &[usize; 16] = &IVI_SCAN_4X4;
680 const INDEO5_QSCALE8_INTRA: [[u8; 24]; 5] = [
682 0x0b, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
683 0x22, 0x24, 0x27, 0x28, 0x2a, 0x2d, 0x2f, 0x31, 0x34, 0x37, 0x39, 0x3c,
685 0x01, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x28, 0x2c,
686 0x30, 0x34, 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x52, 0x58, 0x5e, 0x65, 0x6c,
688 0x13, 0x22, 0x27, 0x2a, 0x2d, 0x33, 0x36, 0x3c, 0x41, 0x45, 0x49, 0x4e,
689 0x53, 0x58, 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x7c, 0x82, 0x88, 0x8e, 0x95,
691 0x13, 0x1f, 0x21, 0x24, 0x27, 0x29, 0x2d, 0x2f, 0x34, 0x37, 0x3a, 0x3d,
692 0x40, 0x44, 0x48, 0x4c, 0x4f, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6b,
694 0x31, 0x42, 0x47, 0x47, 0x4d, 0x52, 0x58, 0x58, 0x5d, 0x63, 0x67, 0x6b,
695 0x6f, 0x73, 0x78, 0x7c, 0x80, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa4,
698 const INDEO5_QSCALE8_INTER: [[u8; 24]; 5] = [
700 0x0b, 0x11, 0x13, 0x14, 0x15, 0x16, 0x18, 0x1a, 0x1b, 0x1d, 0x20, 0x22,
701 0x23, 0x25, 0x28, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x41, 0x44, 0x4a,
703 0x07, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
704 0x3a, 0x3f, 0x44, 0x4a, 0x50, 0x56, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x7e,
706 0x15, 0x25, 0x28, 0x2d, 0x30, 0x34, 0x3a, 0x3d, 0x42, 0x48, 0x4c, 0x51,
707 0x56, 0x5b, 0x60, 0x65, 0x6b, 0x70, 0x76, 0x7c, 0x82, 0x88, 0x8f, 0x97,
709 0x13, 0x1f, 0x20, 0x22, 0x25, 0x28, 0x2b, 0x2d, 0x30, 0x33, 0x36, 0x39,
710 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4b, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62,
712 0x3c, 0x52, 0x58, 0x5d, 0x63, 0x68, 0x68, 0x6d, 0x73, 0x78, 0x7c, 0x80,
713 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa3, 0xa9, 0xad, 0xb1, 0xb5, 0xba
716 const INDEO5_QSCALE4_INTRA: [u8; 24] = [
717 0x01, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14,
718 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
720 const INDEO5_QSCALE4_INTER: [u8; 24] = [
721 0x0b, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
722 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
725 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
726 Box::new(Indeo5Decoder::new(false))
729 pub fn get_decoder_scalable() -> Box<dyn NADecoder + Send> {
730 Box::new(Indeo5Decoder::new(true))
735 use nihav_core::codecs::RegisteredDecoders;
736 use nihav_core::demuxers::RegisteredDemuxers;
737 use nihav_codec_support::test::dec_video::*;
738 use crate::indeo_register_all_decoders;
739 use nihav_commonfmt::generic_register_all_demuxers;
742 let mut dmx_reg = RegisteredDemuxers::new();
743 generic_register_all_demuxers(&mut dmx_reg);
744 let mut dec_reg = RegisteredDecoders::new();
745 indeo_register_all_decoders(&mut dec_reg);
747 // sample: https://samples.mplayerhq.hu/V-codecs/IV50/sample.avi
748 test_decoding("avi", "indeo5", "assets/Indeo/IV5/sample.avi", Some(100),
749 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
750 [0xd73ef6e2, 0x099dc18f, 0x46450af9, 0x1b390a48],
751 [0xbe3295d6, 0xf4afd9fd, 0x820d35e8, 0x4b593c9a],
752 [0x415e5aed, 0x33afb9a2, 0x14ae9308, 0x53e906d3],
753 [0x7fa94dd3, 0x58582fc3, 0xe39977bc, 0xd88036d5],
754 [0x8eef68f7, 0xace88c0c, 0x3f6e4388, 0xfcd82f46],
755 [0xfe22fcc6, 0x8c4666ab, 0xd9888786, 0x7d9adbc8],
756 [0x37f8b6bc, 0xaea9e94a, 0x05a98f2e, 0x2dce51fa],
757 [0x37492cbd, 0x8fd516fa, 0x48a0bcd1, 0x5eb6584f],
758 [0x6f464159, 0xa2af785b, 0xb440493b, 0x86b21911],
759 [0x3a52de08, 0x9f5762b0, 0xe58a6979, 0x0abb295e],
760 [0xe8f56414, 0x36e76d76, 0xd0927365, 0x15dc5327],
761 [0x0fc17e06, 0x8cb6581c, 0x86eb730d, 0x9bedf951],
762 [0x54fb3627, 0xc02bffc6, 0x87748ee5, 0x8b12d57d],
763 [0x8e4fd3a5, 0x3a7b9cd7, 0x0a4ba1a0, 0x48e10237],
764 [0xce87ea8b, 0x1ec40c98, 0x12c9a682, 0x57d02bf0],
765 [0x7024e691, 0x6bc493ba, 0x617a7a91, 0x65997b4c],
766 [0xb8d53b7c, 0x132ffec9, 0x827cf176, 0x68e97292],
767 [0x12ed76a9, 0x11eced60, 0x473a364f, 0x1e197803],
768 [0x6c23ba3a, 0x12e2f7e3, 0x8fc0c2bc, 0x20726bb2],
769 [0x3307e5e6, 0x3e4fa871, 0x55df1d59, 0xbe055301],
770 [0x8198ee6c, 0x82a33414, 0x9fd8c430, 0x1fca7b93],
771 [0x557662c2, 0xeb3226fc, 0x2a125be4, 0xd475ffa9],
772 [0x850c0326, 0x7a0105e5, 0x37799945, 0x927d1237],
773 [0xe770097e, 0xabd460f4, 0x3d9260e0, 0x5a8132e2],
774 [0xdb6644e7, 0xde6986eb, 0x12cc4916, 0x977d2177],
775 [0xd58ced6c, 0x91c0e7b6, 0x8c5926fc, 0x2dbf3117],
776 [0x6e76dd5f, 0x088884f0, 0x8f94451f, 0xc8df4daf],
777 [0x726b2f8f, 0xd44af9ba, 0x1e188962, 0xd37c1a38],
778 [0x84035565, 0xd2370a8c, 0x8ecb4a3f, 0xd6758196],
779 [0xa1e75a16, 0xc9e230ed, 0x23de50f3, 0x2366967a],
780 [0x690a2a91, 0xfa4acef1, 0xd3de6dd0, 0x973031d9],
781 [0xb392e62a, 0x22b0d3f2, 0x0e975a86, 0x14d6dcb3],
782 [0x5e002202, 0xc80e236e, 0x0b484e02, 0x00035f47],
783 [0x4fc0f301, 0x8ec0d33d, 0xe71a12dd, 0xe799731f],
784 [0x278c9096, 0xec7fa833, 0x2094d81f, 0x52e21165],
785 [0xd55238a8, 0xf040101a, 0x1152b6fe, 0x661c9e64],
786 [0x3699d16e, 0x89d9f2d7, 0x9ad59597, 0x7361ee21],
787 [0x1419c93c, 0x91b75784, 0x18f7121d, 0xec2c6b78],
788 [0x07c435da, 0x05f18557, 0xf28ce1e0, 0x43cadcba],
789 [0x2015269d, 0x52cad948, 0xd6485611, 0x06fe33d7],
790 [0x0cea56f3, 0x82c30841, 0x9b2a8cab, 0x8a6f07cb],
791 [0x81f82aa9, 0x233060d5, 0x00f4171e, 0xe14c0c2a],
792 [0x9b2f8b08, 0x7d091eac, 0x09dcb2c3, 0xa7670405],
793 [0x99c97f75, 0xf91c6b12, 0xfbad7705, 0x1c6e6f27],
794 [0xc762b89c, 0xbf44a194, 0xb2a54dc2, 0xae2103e4],
795 [0xba4f52ed, 0xe35aff77, 0x50d8c9d3, 0xeb382d32],
796 [0x9bc9d9a0, 0x7cb4c594, 0xbc1af6f4, 0x1f718229],
797 [0x5f19eea2, 0x6260982e, 0x393fb360, 0x71abe746],
798 [0xd13f2fcc, 0x88a6a714, 0xf4f53d55, 0xf42b11ba],
799 [0x4208b476, 0xaf06ffce, 0x38e59bfe, 0x588567a2],
800 [0xbedfb7b7, 0x8300a39d, 0x964a3c0f, 0x577d52d7],
801 [0x18e5a6f2, 0x7ec85996, 0x27694f30, 0x7717748a],
802 [0xb5e6d70f, 0xc43261bb, 0xd4e6ae7c, 0xcc11f79c],
803 [0xc808cba7, 0xbb042416, 0x2f01ebe1, 0x7d176a38],
804 [0x03353805, 0x4b6e9d66, 0x25933123, 0x4213aaf7],
805 [0x189a6da5, 0x04a4cbe6, 0xea3c9d09, 0x153fdee2],
806 [0x41f8ac6b, 0xb476356b, 0xc70b67d0, 0x28caf359],
807 [0x4514b6a4, 0x788545ff, 0x4ee9139b, 0xa45bedf9],
808 [0x2a39be04, 0xac9921cb, 0x685c1bf9, 0x904bdab2],
809 [0x2c18f3ef, 0x416c0335, 0x0face768, 0x1b9d5cd2],
810 [0x898cd63f, 0x60af727f, 0x6bdf1be6, 0x0df05cfe],
811 [0x8a06787b, 0x7cee2f8b, 0xdc8aac77, 0x2e0e740a],
812 [0x3d340571, 0xbf1c8d4c, 0xddc23f69, 0xd1903942],
813 [0x7d179e85, 0x54048c4d, 0xba047d33, 0x2e9e5edb],
814 [0x65e26600, 0x87c8421d, 0xa77e2c6c, 0x32b4971a],
815 [0x69041052, 0xa4858c7b, 0x904d84f7, 0xb4ad3dcf],
816 [0x3ea0246d, 0x533e752d, 0x1d55798a, 0x30e17e72],
817 [0x4254a700, 0x07365f23, 0x0f9da313, 0xaecd38ce],
818 [0xa5756d9d, 0x79f31387, 0x0ded3654, 0xa7299663],
819 [0x4ef027c9, 0xeebb1383, 0x26a55289, 0x3746969d],
820 [0xdc6acadf, 0x23e1b6e1, 0x07fcdc26, 0x9914b684],
821 [0x52bb8b80, 0x1a5688ae, 0xd429662d, 0x1cc1485d],
822 [0x76b35f59, 0x24b64e5b, 0xbcbeaee7, 0xf568a832],
823 [0x0756d15f, 0x9cc288bf, 0x9f882a3c, 0xfe7c7161],
824 [0x0503113a, 0x95e716ff, 0x304cf65e, 0x490725e8],
825 [0x7db7ba62, 0x08e4e77d, 0xc9db6413, 0xea3f1a39],
826 [0x7cef6d67, 0xc94867e6, 0x5c674de6, 0x5eb74081],
827 [0x7573b799, 0x069d4f03, 0x63b537a1, 0xdfe25db6],
828 [0xc401e705, 0x834828bc, 0xd99da4a1, 0xd0f3bee8],
829 [0x02817844, 0xada6433e, 0x31761e98, 0x901ccf68],
830 [0x8f9432b4, 0x9f860957, 0xcba54c86, 0x8beb8209],
831 [0x6a46e58c, 0x7d299228, 0x5c001d12, 0xd8db2a00],
832 [0x0c12586d, 0x866d8ca9, 0x849bbb17, 0x5af63ea2],
833 [0xe48671b6, 0xc4377063, 0xc4d03c02, 0x621bd894],
834 [0x5f7f82eb, 0xcdb5abf5, 0x325f2d9d, 0x24a5d200],
835 [0xec6b6fe7, 0x347316c4, 0x6241904a, 0x4e2497a5],
836 [0xf661b7fd, 0xa00e2fc7, 0x90e11456, 0x507fef21],
837 [0x77c7addd, 0x67148dce, 0x1cd27059, 0xefbf4abf],
838 [0x11270d9c, 0xb352779d, 0x81f21055, 0xae93a8b6],
839 [0x3d1f0aaf, 0x3b4aa6d8, 0xca1c160c, 0x6fe4f2bd],
840 [0x17c6bec4, 0x54b568cd, 0xd19c78d6, 0x9a3d897a],
841 [0xc4ab4ca6, 0xbf3b2573, 0xb4d837dd, 0x4dfab799],
842 [0x6fd5645d, 0xa34978b2, 0x6696dd1a, 0x665ca09b],
843 [0x87984bb9, 0xd4d3bc30, 0x7f8bb7a8, 0x2d83b303],
844 [0x21fb5d58, 0x1ee47d1a, 0x97200d83, 0x1d596a88],
845 [0x2656f329, 0x497693be, 0xca971ddf, 0x410d4092],
846 [0xd285c512, 0xfc1ed632, 0x63c43ec2, 0xac5766d1],
847 [0x46fb80ee, 0xcfeecdaa, 0x7237a433, 0x5708ff56],
848 [0x4fccd9c8, 0x7b1a4f31, 0x51516a80, 0x27bf3cae],
849 [0xd649d2f5, 0xebadf1f7, 0x6b34e8ce, 0xb87e82f1],
850 [0x6eb0aec6, 0xfbe9cb51, 0x39e695b4, 0xa6e46e70]]));