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 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<()> {
271 let band_id = if pic_hdr.luma_bands == 4 { band.band_no + 1 } else { 0 };
273 for mb_y in 0..tile.mb_h {
274 for mb_x in 0..tile.mb_w {
275 let mut mb = MB::new(tile.pos_x + mb_x * band.mb_size, tile.pos_y + mb_y * band.mb_size);
276 if !br.read_bool()? {
277 if pic_hdr.ftype.is_intra() {
278 mb.mtype = MBType::Intra;
279 } else if band.inherit_mv {
280 if let Some(ref tileref) = ref_tile {
281 mb.mtype = tileref.mb[mb_idx].mtype;
283 return Err(DecoderError::MissingReference);
286 mb.mtype = if br.read_bool()? { MBType::Inter } else { MBType::Intra };
288 if band.mb_size == band.blk_size {
289 mb.cbp = br.read(1)? as u8;
291 mb.cbp = br.read(4)? as u8;
296 if let Some(ref tileref) = ref_tile {
297 mb.qd = tileref.mb[mb_idx].qd;
298 q = calc_quant(band.quant, mb.qd);
300 return Err(DecoderError::MissingReference);
302 } else if (mb.cbp != 0) || ((band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q) {
303 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
304 q = calc_quant(band.quant, mb.qd);
306 q = band.quant as usize;
309 q = band.quant as usize;
312 if mb.mtype == MBType::Intra {
313 if band.blk_size == 8 {
314 mb.q = INDEO5_QSCALE8_INTRA[band_id][q];
316 mb.q = INDEO5_QSCALE4_INTRA[q];
319 if band.blk_size == 8 {
320 mb.q = INDEO5_QSCALE8_INTER[band_id][q];
322 mb.q = INDEO5_QSCALE4_INTER[q];
326 if mb.mtype != MBType::Intra {
328 if let Some(ref tileref) = ref_tile {
329 let mx = tileref.mb[mb_idx].mv_x;
330 let my = tileref.mb[mb_idx].mv_y;
335 mb.mv_x = scale_mv(mx, mv_scale);
336 mb.mv_y = scale_mv(my, mv_scale);
340 mv_y += br.read_ivi_cb_s(&self.mb_cb)?;
341 mv_x += br.read_ivi_cb_s(&self.mb_cb)?;
347 validate!(!pic_hdr.ftype.is_intra());
348 mb.mtype = MBType::Inter;
351 if (band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q {
352 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
353 let q = calc_quant(band.quant, mb.qd);
354 if mb.mtype == MBType::Intra {
355 if band.blk_size == 8 {
356 mb.q = INDEO5_QSCALE8_INTRA[band_id][q];
358 mb.q = INDEO5_QSCALE4_INTRA[q];
361 if band.blk_size == 8 {
362 mb.q = INDEO5_QSCALE8_INTER[band_id][q];
364 mb.q = INDEO5_QSCALE4_INTER[q];
369 if let Some(ref tileref) = ref_tile {
370 let mx = tileref.mb[mb_idx].mv_x;
371 let my = tileref.mb[mb_idx].mv_y;
376 mb.mv_x = scale_mv(mx, mv_scale);
377 mb.mv_y = scale_mv(my, mv_scale);
382 tile.mb[mb_idx] = mb;
390 fn recombine_plane(&mut self, src: &[i16], sstride: usize, dst: &mut [u8], dstride: usize, w: usize, h: usize) {
392 let mut idx1 = w / 2;
393 let mut idx2 = (h / 2) * sstride;
394 let mut idx3 = idx2 + idx1;
395 let mut bidx1 = idx1;
396 let mut bidx3 = idx3;
398 let mut oidx1 = dstride;
399 let filt_lo = |a: i16, b: i16| a + b;
400 let filt_hi = |a: i16, b: i16, c: i16| a - b * 6 + c;
403 let mut b0_1 = src[idx0];
404 let mut b0_2 = src[idx0 + sstride];
405 let mut b1_1 = src[bidx1];
406 let mut b1_2 = src[idx1];
407 let mut b1_3 = filt_hi(b1_1, b1_2, src[idx1 + sstride]);
409 let mut b2_2 = src[idx2];
412 let mut b2_5 = src[idx2 + sstride];
415 let mut b3_2 = src[bidx3];
418 let mut b3_5 = src[idx3];
420 let mut b3_8 = filt_hi(b3_2, b3_5, src[idx3 + sstride]);
438 b0_1 = src[idx0 + x + 1];
439 b0_2 = src[idx0 + x + 1 + sstride];
440 let mut p0 = tmp0 << 4;
441 let mut p1 = (tmp0 + b0_1) << 3;
442 let mut p2 = (tmp0 + tmp1) << 3;
443 let mut p3 = (tmp0 + tmp1 + b0_1 + b0_2) << 2;
447 let tmp2 = filt_lo(tmp0, tmp1);
448 let tmp3 = filt_hi(tmp0, tmp1, b1_3);
449 b1_2 = src[ idx1 + x + 1];
450 b1_1 = src[bidx1 + x + 1];
451 b1_3 = filt_hi(b1_1, b1_2, src[idx1 + x + 1 + sstride]);
453 p1 += (tmp2 + b1_1 + b1_2) << 2;
455 p3 += (tmp3 + b1_3) << 1;
457 b2_3 = src[idx2 + x + 1];
458 b2_6 = src[idx2 + x + 1 + sstride];
459 let tmp0 = filt_lo(b2_1, b2_2);
460 let tmp1 = filt_hi(b2_1, b2_2, b2_3);
463 p2 += (tmp0 + filt_lo(b2_4, b2_5)) << 2;
464 p3 += (tmp1 + filt_hi(b2_4, b2_5, b2_6)) << 1;
466 b3_6 = src[idx3 + x + 1];
467 b3_3 = src[bidx3 + x + 1];
468 b3_9 = filt_hi(b3_3, b3_6, src[idx3 + x + 1 + sstride]);
469 let tmp0 = b3_1 + b3_4;
470 let tmp1 = b3_2 + b3_5;
471 let tmp2 = b3_3 + b3_6;
472 p0 += filt_lo(tmp0, tmp1) << 2;
473 p1 += filt_hi(tmp0, tmp1, tmp2) << 1;
474 p2 += filt_lo(b3_7, b3_8) << 1;
475 p3 += filt_hi(b3_7, b3_8, b3_9) << 0;
477 dst[oidx0 + x * 2 + 0] = clip8((p0 >> 6) + 128);
478 dst[oidx0 + x * 2 + 1] = clip8((p1 >> 6) + 128);
479 dst[oidx1 + x * 2 + 0] = clip8((p2 >> 6) + 128);
480 dst[oidx1 + x * 2 + 1] = clip8((p3 >> 6) + 128);
488 oidx0 += dstride * 2;
489 oidx1 += dstride * 2;
494 struct Indeo5Decoder {
495 info: NACodecInfoRef,
503 info: NACodecInfo::new_dummy(),
504 dec: IVIDecoder::new(),
505 ip: Indeo5Parser::new(),
510 impl NADecoder for Indeo5Decoder {
511 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
512 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
513 let w = vinfo.get_width();
514 let h = vinfo.get_height();
515 let f = vinfo.is_flipped();
516 let fmt = formats::YUV410_FORMAT;
517 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, f, fmt));
518 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
521 Err(DecoderError::InvalidData)
524 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
525 let src = pkt.get_buffer();
526 let mut br = BitReader::new(src.as_slice(), BitReaderMode::LE);
528 let bufinfo = self.dec.decode_frame(&mut self.ip, &mut br)?;
529 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
530 frm.set_keyframe(self.dec.is_intra());
531 frm.set_frame_type(self.dec.get_frame_type());
534 fn flush(&mut self) {
539 const INDEO5_PICTURE_SIZE_TAB: [[usize; 2]; 15] = [
540 [640, 480], [320, 240], [160, 120], [704, 480], [352, 240], [352, 288], [176, 144],
541 [240, 180], [640, 240], [704, 240], [80, 60], [88, 72], [0, 0], [0, 0], [0, 0]
544 const INDEO5_FRAME_TYPE: [IVIFrameType; 5] = [
545 IVIFrameType::Intra, IVIFrameType::Inter, IVIFrameType::InterScal,
546 IVIFrameType::InterDroppable, IVIFrameType::NULL,
549 const INDEO5_QUANT8X8_INTRA: [[u16; 64]; 5] = [
551 0x1a, 0x2e, 0x36, 0x42, 0x46, 0x4a, 0x4e, 0x5a,
552 0x2e, 0x32, 0x3e, 0x42, 0x46, 0x4e, 0x56, 0x6a,
553 0x36, 0x3e, 0x3e, 0x44, 0x4a, 0x54, 0x66, 0x72,
554 0x42, 0x42, 0x44, 0x4a, 0x52, 0x62, 0x6c, 0x7a,
555 0x46, 0x46, 0x4a, 0x52, 0x5e, 0x66, 0x72, 0x8e,
556 0x4a, 0x4e, 0x54, 0x62, 0x66, 0x6e, 0x86, 0xa6,
557 0x4e, 0x56, 0x66, 0x6c, 0x72, 0x86, 0x9a, 0xca,
558 0x5a, 0x6a, 0x72, 0x7a, 0x8e, 0xa6, 0xca, 0xfe,
560 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
561 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
562 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
563 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
564 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
565 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
566 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
567 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
569 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
570 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
571 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
572 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
573 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
574 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
575 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
576 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
578 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
579 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
580 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
581 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
582 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
583 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
584 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
585 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
587 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
588 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
589 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
590 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
591 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
592 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
593 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
594 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
597 const INDEO5_QUANT8X8_INTER: [[u16; 64]; 5] = [
599 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
600 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
601 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
602 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
603 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
604 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
605 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
606 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
608 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
609 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
610 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
611 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
612 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
613 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
614 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
615 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
617 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
618 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
619 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
620 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
621 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
622 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
623 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
624 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
626 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
627 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
628 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
629 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
630 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
631 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
632 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
633 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
635 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
636 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
637 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
638 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
639 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
640 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
641 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
642 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
645 const INDEO5_QUANT4X4_INTRA: [u16; 16] = [
646 0x1e, 0x3e, 0x4a, 0x52,
647 0x3e, 0x4a, 0x52, 0x5e,
648 0x4a, 0x52, 0x5e, 0x7a,
649 0x52, 0x5e, 0x7a, 0x92
651 const INDEO5_QUANT4X4_INTER: [u16; 16] = [
652 0x1e, 0x3e, 0x4a, 0x52,
653 0x3e, 0x4a, 0x52, 0x56,
654 0x4a, 0x52, 0x56, 0x5e,
655 0x52, 0x56, 0x5e, 0x66
657 const INDEO5_Q8_INTRA: [&[u16; 64]; 5] = [
658 &INDEO5_QUANT8X8_INTRA[0], &INDEO5_QUANT8X8_INTRA[1], &INDEO5_QUANT8X8_INTRA[2],
659 &INDEO5_QUANT8X8_INTRA[3], &INDEO5_QUANT8X8_INTRA[4],
661 const INDEO5_Q8_INTER: [&[u16; 64]; 5] = [
662 &INDEO5_QUANT8X8_INTER[0], &INDEO5_QUANT8X8_INTER[1], &INDEO5_QUANT8X8_INTER[2],
663 &INDEO5_QUANT8X8_INTER[3], &INDEO5_QUANT8X8_INTER[4],
665 const INDEO5_Q4_INTRA: &[u16; 16] = &INDEO5_QUANT4X4_INTRA;
666 const INDEO5_Q4_INTER: &[u16; 16] = &INDEO5_QUANT4X4_INTER;
668 const INDEO5_SCAN8X8: [&[usize; 64]; 4] = [
669 &ZIGZAG, &IVI_SCAN_8X8_VER, &IVI_SCAN_8X8_HOR, &IVI_SCAN_8X8_HOR
671 const INDEO5_SCAN4X4: &[usize; 16] = &IVI_SCAN_4X4;
673 const INDEO5_QSCALE8_INTRA: [[u8; 24]; 5] = [
675 0x0b, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
676 0x22, 0x24, 0x27, 0x28, 0x2a, 0x2d, 0x2f, 0x31, 0x34, 0x37, 0x39, 0x3c,
678 0x01, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x28, 0x2c,
679 0x30, 0x34, 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x52, 0x58, 0x5e, 0x65, 0x6c,
681 0x13, 0x22, 0x27, 0x2a, 0x2d, 0x33, 0x36, 0x3c, 0x41, 0x45, 0x49, 0x4e,
682 0x53, 0x58, 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x7c, 0x82, 0x88, 0x8e, 0x95,
684 0x13, 0x1f, 0x21, 0x24, 0x27, 0x29, 0x2d, 0x2f, 0x34, 0x37, 0x3a, 0x3d,
685 0x40, 0x44, 0x48, 0x4c, 0x4f, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6b,
687 0x31, 0x42, 0x47, 0x47, 0x4d, 0x52, 0x58, 0x58, 0x5d, 0x63, 0x67, 0x6b,
688 0x6f, 0x73, 0x78, 0x7c, 0x80, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa4,
691 const INDEO5_QSCALE8_INTER: [[u8; 24]; 5] = [
693 0x0b, 0x11, 0x13, 0x14, 0x15, 0x16, 0x18, 0x1a, 0x1b, 0x1d, 0x20, 0x22,
694 0x23, 0x25, 0x28, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x41, 0x44, 0x4a,
696 0x07, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
697 0x3a, 0x3f, 0x44, 0x4a, 0x50, 0x56, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x7e,
699 0x15, 0x25, 0x28, 0x2d, 0x30, 0x34, 0x3a, 0x3d, 0x42, 0x48, 0x4c, 0x51,
700 0x56, 0x5b, 0x60, 0x65, 0x6b, 0x70, 0x76, 0x7c, 0x82, 0x88, 0x8f, 0x97,
702 0x13, 0x1f, 0x20, 0x22, 0x25, 0x28, 0x2b, 0x2d, 0x30, 0x33, 0x36, 0x39,
703 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4b, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62,
705 0x3c, 0x52, 0x58, 0x5d, 0x63, 0x68, 0x68, 0x6d, 0x73, 0x78, 0x7c, 0x80,
706 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa3, 0xa9, 0xad, 0xb1, 0xb5, 0xba
709 const INDEO5_QSCALE4_INTRA: [u8; 24] = [
710 0x01, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14,
711 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
713 const INDEO5_QSCALE4_INTER: [u8; 24] = [
714 0x0b, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
715 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
718 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
719 Box::new(Indeo5Decoder::new())
724 use nihav_core::codecs::RegisteredDecoders;
725 use nihav_core::demuxers::RegisteredDemuxers;
726 use nihav_codec_support::test::dec_video::*;
727 use crate::indeo_register_all_codecs;
728 use nihav_commonfmt::generic_register_all_demuxers;
731 let mut dmx_reg = RegisteredDemuxers::new();
732 generic_register_all_demuxers(&mut dmx_reg);
733 let mut dec_reg = RegisteredDecoders::new();
734 indeo_register_all_codecs(&mut dec_reg);
736 test_decoding("avi", "indeo5", "assets/Indeo/IV5/sample.avi", Some(100),
737 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
738 [0xd73ef6e2, 0x099dc18f, 0x46450af9, 0x1b390a48],
739 [0xbe3295d6, 0xf4afd9fd, 0x820d35e8, 0x4b593c9a],
740 [0x415e5aed, 0x33afb9a2, 0x14ae9308, 0x53e906d3],
741 [0x7fa94dd3, 0x58582fc3, 0xe39977bc, 0xd88036d5],
742 [0x8eef68f7, 0xace88c0c, 0x3f6e4388, 0xfcd82f46],
743 [0xfe22fcc6, 0x8c4666ab, 0xd9888786, 0x7d9adbc8],
744 [0x37f8b6bc, 0xaea9e94a, 0x05a98f2e, 0x2dce51fa],
745 [0x37492cbd, 0x8fd516fa, 0x48a0bcd1, 0x5eb6584f],
746 [0x6f464159, 0xa2af785b, 0xb440493b, 0x86b21911],
747 [0x3a52de08, 0x9f5762b0, 0xe58a6979, 0x0abb295e],
748 [0xe8f56414, 0x36e76d76, 0xd0927365, 0x15dc5327],
749 [0x0fc17e06, 0x8cb6581c, 0x86eb730d, 0x9bedf951],
750 [0x54fb3627, 0xc02bffc6, 0x87748ee5, 0x8b12d57d],
751 [0x8e4fd3a5, 0x3a7b9cd7, 0x0a4ba1a0, 0x48e10237],
752 [0xce87ea8b, 0x1ec40c98, 0x12c9a682, 0x57d02bf0],
753 [0x7024e691, 0x6bc493ba, 0x617a7a91, 0x65997b4c],
754 [0xb8d53b7c, 0x132ffec9, 0x827cf176, 0x68e97292],
755 [0x12ed76a9, 0x11eced60, 0x473a364f, 0x1e197803],
756 [0x6c23ba3a, 0x12e2f7e3, 0x8fc0c2bc, 0x20726bb2],
757 [0x3307e5e6, 0x3e4fa871, 0x55df1d59, 0xbe055301],
758 [0x8198ee6c, 0x82a33414, 0x9fd8c430, 0x1fca7b93],
759 [0x557662c2, 0xeb3226fc, 0x2a125be4, 0xd475ffa9],
760 [0x850c0326, 0x7a0105e5, 0x37799945, 0x927d1237],
761 [0xe770097e, 0xabd460f4, 0x3d9260e0, 0x5a8132e2],
762 [0xdb6644e7, 0xde6986eb, 0x12cc4916, 0x977d2177],
763 [0xd58ced6c, 0x91c0e7b6, 0x8c5926fc, 0x2dbf3117],
764 [0x6e76dd5f, 0x088884f0, 0x8f94451f, 0xc8df4daf],
765 [0x726b2f8f, 0xd44af9ba, 0x1e188962, 0xd37c1a38],
766 [0x84035565, 0xd2370a8c, 0x8ecb4a3f, 0xd6758196],
767 [0xa1e75a16, 0xc9e230ed, 0x23de50f3, 0x2366967a],
768 [0x690a2a91, 0xfa4acef1, 0xd3de6dd0, 0x973031d9],
769 [0xb392e62a, 0x22b0d3f2, 0x0e975a86, 0x14d6dcb3],
770 [0x5e002202, 0xc80e236e, 0x0b484e02, 0x00035f47],
771 [0x4fc0f301, 0x8ec0d33d, 0xe71a12dd, 0xe799731f],
772 [0x278c9096, 0xec7fa833, 0x2094d81f, 0x52e21165],
773 [0xd55238a8, 0xf040101a, 0x1152b6fe, 0x661c9e64],
774 [0x3699d16e, 0x89d9f2d7, 0x9ad59597, 0x7361ee21],
775 [0x1419c93c, 0x91b75784, 0x18f7121d, 0xec2c6b78],
776 [0x07c435da, 0x05f18557, 0xf28ce1e0, 0x43cadcba],
777 [0x2015269d, 0x52cad948, 0xd6485611, 0x06fe33d7],
778 [0x0cea56f3, 0x82c30841, 0x9b2a8cab, 0x8a6f07cb],
779 [0x81f82aa9, 0x233060d5, 0x00f4171e, 0xe14c0c2a],
780 [0x9b2f8b08, 0x7d091eac, 0x09dcb2c3, 0xa7670405],
781 [0x99c97f75, 0xf91c6b12, 0xfbad7705, 0x1c6e6f27],
782 [0xc762b89c, 0xbf44a194, 0xb2a54dc2, 0xae2103e4],
783 [0xba4f52ed, 0xe35aff77, 0x50d8c9d3, 0xeb382d32],
784 [0x9bc9d9a0, 0x7cb4c594, 0xbc1af6f4, 0x1f718229],
785 [0x5f19eea2, 0x6260982e, 0x393fb360, 0x71abe746],
786 [0xd13f2fcc, 0x88a6a714, 0xf4f53d55, 0xf42b11ba],
787 [0x4208b476, 0xaf06ffce, 0x38e59bfe, 0x588567a2],
788 [0xbedfb7b7, 0x8300a39d, 0x964a3c0f, 0x577d52d7],
789 [0x18e5a6f2, 0x7ec85996, 0x27694f30, 0x7717748a],
790 [0xb5e6d70f, 0xc43261bb, 0xd4e6ae7c, 0xcc11f79c],
791 [0xc808cba7, 0xbb042416, 0x2f01ebe1, 0x7d176a38],
792 [0x03353805, 0x4b6e9d66, 0x25933123, 0x4213aaf7],
793 [0x189a6da5, 0x04a4cbe6, 0xea3c9d09, 0x153fdee2],
794 [0x41f8ac6b, 0xb476356b, 0xc70b67d0, 0x28caf359],
795 [0x4514b6a4, 0x788545ff, 0x4ee9139b, 0xa45bedf9],
796 [0x2a39be04, 0xac9921cb, 0x685c1bf9, 0x904bdab2],
797 [0x2c18f3ef, 0x416c0335, 0x0face768, 0x1b9d5cd2],
798 [0x898cd63f, 0x60af727f, 0x6bdf1be6, 0x0df05cfe],
799 [0x8a06787b, 0x7cee2f8b, 0xdc8aac77, 0x2e0e740a],
800 [0x3d340571, 0xbf1c8d4c, 0xddc23f69, 0xd1903942],
801 [0x7d179e85, 0x54048c4d, 0xba047d33, 0x2e9e5edb],
802 [0x65e26600, 0x87c8421d, 0xa77e2c6c, 0x32b4971a],
803 [0x69041052, 0xa4858c7b, 0x904d84f7, 0xb4ad3dcf],
804 [0x3ea0246d, 0x533e752d, 0x1d55798a, 0x30e17e72],
805 [0x4254a700, 0x07365f23, 0x0f9da313, 0xaecd38ce],
806 [0xa5756d9d, 0x79f31387, 0x0ded3654, 0xa7299663],
807 [0x4ef027c9, 0xeebb1383, 0x26a55289, 0x3746969d],
808 [0xdc6acadf, 0x23e1b6e1, 0x07fcdc26, 0x9914b684],
809 [0x52bb8b80, 0x1a5688ae, 0xd429662d, 0x1cc1485d],
810 [0x76b35f59, 0x24b64e5b, 0xbcbeaee7, 0xf568a832],
811 [0x0756d15f, 0x9cc288bf, 0x9f882a3c, 0xfe7c7161],
812 [0x0503113a, 0x95e716ff, 0x304cf65e, 0x490725e8],
813 [0x7db7ba62, 0x08e4e77d, 0xc9db6413, 0xea3f1a39],
814 [0x7cef6d67, 0xc94867e6, 0x5c674de6, 0x5eb74081],
815 [0x7573b799, 0x069d4f03, 0x63b537a1, 0xdfe25db6],
816 [0xc401e705, 0x834828bc, 0xd99da4a1, 0xd0f3bee8],
817 [0x02817844, 0xada6433e, 0x31761e98, 0x901ccf68],
818 [0x8f9432b4, 0x9f860957, 0xcba54c86, 0x8beb8209],
819 [0x6a46e58c, 0x7d299228, 0x5c001d12, 0xd8db2a00],
820 [0x0c12586d, 0x866d8ca9, 0x849bbb17, 0x5af63ea2],
821 [0xe48671b6, 0xc4377063, 0xc4d03c02, 0x621bd894],
822 [0x5f7f82eb, 0xcdb5abf5, 0x325f2d9d, 0x24a5d200],
823 [0xec6b6fe7, 0x347316c4, 0x6241904a, 0x4e2497a5],
824 [0xf661b7fd, 0xa00e2fc7, 0x90e11456, 0x507fef21],
825 [0x77c7addd, 0x67148dce, 0x1cd27059, 0xefbf4abf],
826 [0x11270d9c, 0xb352779d, 0x81f21055, 0xae93a8b6],
827 [0x3d1f0aaf, 0x3b4aa6d8, 0xca1c160c, 0x6fe4f2bd],
828 [0x17c6bec4, 0x54b568cd, 0xd19c78d6, 0x9a3d897a],
829 [0xc4ab4ca6, 0xbf3b2573, 0xb4d837dd, 0x4dfab799],
830 [0x6fd5645d, 0xa34978b2, 0x6696dd1a, 0x665ca09b],
831 [0x87984bb9, 0xd4d3bc30, 0x7f8bb7a8, 0x2d83b303],
832 [0x21fb5d58, 0x1ee47d1a, 0x97200d83, 0x1d596a88],
833 [0x2656f329, 0x497693be, 0xca971ddf, 0x410d4092],
834 [0xd285c512, 0xfc1ed632, 0x63c43ec2, 0xac5766d1],
835 [0x46fb80ee, 0xcfeecdaa, 0x7237a433, 0x5708ff56],
836 [0x4fccd9c8, 0x7b1a4f31, 0x51516a80, 0x27bf3cae],
837 [0xd649d2f5, 0xebadf1f7, 0x6b34e8ce, 0xb87e82f1],
838 [0x6eb0aec6, 0xfbe9cb51, 0x39e695b4, 0xa6e46e70]]));