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 impl NAOptionHandler for Indeo5Decoder {
540 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
541 fn set_options(&mut self, _options: &[NAOption]) { }
542 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
545 const INDEO5_PICTURE_SIZE_TAB: [[usize; 2]; 15] = [
546 [640, 480], [320, 240], [160, 120], [704, 480], [352, 240], [352, 288], [176, 144],
547 [240, 180], [640, 240], [704, 240], [80, 60], [88, 72], [0, 0], [0, 0], [0, 0]
550 const INDEO5_FRAME_TYPE: [IVIFrameType; 5] = [
551 IVIFrameType::Intra, IVIFrameType::Inter, IVIFrameType::InterScal,
552 IVIFrameType::InterDroppable, IVIFrameType::NULL,
555 const INDEO5_QUANT8X8_INTRA: [[u16; 64]; 5] = [
557 0x1a, 0x2e, 0x36, 0x42, 0x46, 0x4a, 0x4e, 0x5a,
558 0x2e, 0x32, 0x3e, 0x42, 0x46, 0x4e, 0x56, 0x6a,
559 0x36, 0x3e, 0x3e, 0x44, 0x4a, 0x54, 0x66, 0x72,
560 0x42, 0x42, 0x44, 0x4a, 0x52, 0x62, 0x6c, 0x7a,
561 0x46, 0x46, 0x4a, 0x52, 0x5e, 0x66, 0x72, 0x8e,
562 0x4a, 0x4e, 0x54, 0x62, 0x66, 0x6e, 0x86, 0xa6,
563 0x4e, 0x56, 0x66, 0x6c, 0x72, 0x86, 0x9a, 0xca,
564 0x5a, 0x6a, 0x72, 0x7a, 0x8e, 0xa6, 0xca, 0xfe,
566 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
567 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
568 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
569 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
570 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
571 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
572 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
573 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
575 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
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,
584 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
585 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
586 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
587 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
588 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
589 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
590 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
591 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
593 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
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,
603 const INDEO5_QUANT8X8_INTER: [[u16; 64]; 5] = [
605 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
606 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
607 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
608 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
609 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
610 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
611 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
612 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
614 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
615 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
616 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
617 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
618 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
619 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
620 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
621 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
623 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
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,
632 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
633 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
634 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
635 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
636 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
637 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
638 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
639 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
641 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
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,
651 const INDEO5_QUANT4X4_INTRA: [u16; 16] = [
652 0x1e, 0x3e, 0x4a, 0x52,
653 0x3e, 0x4a, 0x52, 0x5e,
654 0x4a, 0x52, 0x5e, 0x7a,
655 0x52, 0x5e, 0x7a, 0x92
657 const INDEO5_QUANT4X4_INTER: [u16; 16] = [
658 0x1e, 0x3e, 0x4a, 0x52,
659 0x3e, 0x4a, 0x52, 0x56,
660 0x4a, 0x52, 0x56, 0x5e,
661 0x52, 0x56, 0x5e, 0x66
663 const INDEO5_Q8_INTRA: [&[u16; 64]; 5] = [
664 &INDEO5_QUANT8X8_INTRA[0], &INDEO5_QUANT8X8_INTRA[1], &INDEO5_QUANT8X8_INTRA[2],
665 &INDEO5_QUANT8X8_INTRA[3], &INDEO5_QUANT8X8_INTRA[4],
667 const INDEO5_Q8_INTER: [&[u16; 64]; 5] = [
668 &INDEO5_QUANT8X8_INTER[0], &INDEO5_QUANT8X8_INTER[1], &INDEO5_QUANT8X8_INTER[2],
669 &INDEO5_QUANT8X8_INTER[3], &INDEO5_QUANT8X8_INTER[4],
671 const INDEO5_Q4_INTRA: &[u16; 16] = &INDEO5_QUANT4X4_INTRA;
672 const INDEO5_Q4_INTER: &[u16; 16] = &INDEO5_QUANT4X4_INTER;
674 const INDEO5_SCAN8X8: [&[usize; 64]; 4] = [
675 &ZIGZAG, &IVI_SCAN_8X8_VER, &IVI_SCAN_8X8_HOR, &IVI_SCAN_8X8_HOR
677 const INDEO5_SCAN4X4: &[usize; 16] = &IVI_SCAN_4X4;
679 const INDEO5_QSCALE8_INTRA: [[u8; 24]; 5] = [
681 0x0b, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
682 0x22, 0x24, 0x27, 0x28, 0x2a, 0x2d, 0x2f, 0x31, 0x34, 0x37, 0x39, 0x3c,
684 0x01, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x28, 0x2c,
685 0x30, 0x34, 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x52, 0x58, 0x5e, 0x65, 0x6c,
687 0x13, 0x22, 0x27, 0x2a, 0x2d, 0x33, 0x36, 0x3c, 0x41, 0x45, 0x49, 0x4e,
688 0x53, 0x58, 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x7c, 0x82, 0x88, 0x8e, 0x95,
690 0x13, 0x1f, 0x21, 0x24, 0x27, 0x29, 0x2d, 0x2f, 0x34, 0x37, 0x3a, 0x3d,
691 0x40, 0x44, 0x48, 0x4c, 0x4f, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6b,
693 0x31, 0x42, 0x47, 0x47, 0x4d, 0x52, 0x58, 0x58, 0x5d, 0x63, 0x67, 0x6b,
694 0x6f, 0x73, 0x78, 0x7c, 0x80, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa4,
697 const INDEO5_QSCALE8_INTER: [[u8; 24]; 5] = [
699 0x0b, 0x11, 0x13, 0x14, 0x15, 0x16, 0x18, 0x1a, 0x1b, 0x1d, 0x20, 0x22,
700 0x23, 0x25, 0x28, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x41, 0x44, 0x4a,
702 0x07, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
703 0x3a, 0x3f, 0x44, 0x4a, 0x50, 0x56, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x7e,
705 0x15, 0x25, 0x28, 0x2d, 0x30, 0x34, 0x3a, 0x3d, 0x42, 0x48, 0x4c, 0x51,
706 0x56, 0x5b, 0x60, 0x65, 0x6b, 0x70, 0x76, 0x7c, 0x82, 0x88, 0x8f, 0x97,
708 0x13, 0x1f, 0x20, 0x22, 0x25, 0x28, 0x2b, 0x2d, 0x30, 0x33, 0x36, 0x39,
709 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4b, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62,
711 0x3c, 0x52, 0x58, 0x5d, 0x63, 0x68, 0x68, 0x6d, 0x73, 0x78, 0x7c, 0x80,
712 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa3, 0xa9, 0xad, 0xb1, 0xb5, 0xba
715 const INDEO5_QSCALE4_INTRA: [u8; 24] = [
716 0x01, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14,
717 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
719 const INDEO5_QSCALE4_INTER: [u8; 24] = [
720 0x0b, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
721 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
724 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
725 Box::new(Indeo5Decoder::new())
730 use nihav_core::codecs::RegisteredDecoders;
731 use nihav_core::demuxers::RegisteredDemuxers;
732 use nihav_codec_support::test::dec_video::*;
733 use crate::indeo_register_all_codecs;
734 use nihav_commonfmt::generic_register_all_demuxers;
737 let mut dmx_reg = RegisteredDemuxers::new();
738 generic_register_all_demuxers(&mut dmx_reg);
739 let mut dec_reg = RegisteredDecoders::new();
740 indeo_register_all_codecs(&mut dec_reg);
742 test_decoding("avi", "indeo5", "assets/Indeo/IV5/sample.avi", Some(100),
743 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
744 [0xd73ef6e2, 0x099dc18f, 0x46450af9, 0x1b390a48],
745 [0xbe3295d6, 0xf4afd9fd, 0x820d35e8, 0x4b593c9a],
746 [0x415e5aed, 0x33afb9a2, 0x14ae9308, 0x53e906d3],
747 [0x7fa94dd3, 0x58582fc3, 0xe39977bc, 0xd88036d5],
748 [0x8eef68f7, 0xace88c0c, 0x3f6e4388, 0xfcd82f46],
749 [0xfe22fcc6, 0x8c4666ab, 0xd9888786, 0x7d9adbc8],
750 [0x37f8b6bc, 0xaea9e94a, 0x05a98f2e, 0x2dce51fa],
751 [0x37492cbd, 0x8fd516fa, 0x48a0bcd1, 0x5eb6584f],
752 [0x6f464159, 0xa2af785b, 0xb440493b, 0x86b21911],
753 [0x3a52de08, 0x9f5762b0, 0xe58a6979, 0x0abb295e],
754 [0xe8f56414, 0x36e76d76, 0xd0927365, 0x15dc5327],
755 [0x0fc17e06, 0x8cb6581c, 0x86eb730d, 0x9bedf951],
756 [0x54fb3627, 0xc02bffc6, 0x87748ee5, 0x8b12d57d],
757 [0x8e4fd3a5, 0x3a7b9cd7, 0x0a4ba1a0, 0x48e10237],
758 [0xce87ea8b, 0x1ec40c98, 0x12c9a682, 0x57d02bf0],
759 [0x7024e691, 0x6bc493ba, 0x617a7a91, 0x65997b4c],
760 [0xb8d53b7c, 0x132ffec9, 0x827cf176, 0x68e97292],
761 [0x12ed76a9, 0x11eced60, 0x473a364f, 0x1e197803],
762 [0x6c23ba3a, 0x12e2f7e3, 0x8fc0c2bc, 0x20726bb2],
763 [0x3307e5e6, 0x3e4fa871, 0x55df1d59, 0xbe055301],
764 [0x8198ee6c, 0x82a33414, 0x9fd8c430, 0x1fca7b93],
765 [0x557662c2, 0xeb3226fc, 0x2a125be4, 0xd475ffa9],
766 [0x850c0326, 0x7a0105e5, 0x37799945, 0x927d1237],
767 [0xe770097e, 0xabd460f4, 0x3d9260e0, 0x5a8132e2],
768 [0xdb6644e7, 0xde6986eb, 0x12cc4916, 0x977d2177],
769 [0xd58ced6c, 0x91c0e7b6, 0x8c5926fc, 0x2dbf3117],
770 [0x6e76dd5f, 0x088884f0, 0x8f94451f, 0xc8df4daf],
771 [0x726b2f8f, 0xd44af9ba, 0x1e188962, 0xd37c1a38],
772 [0x84035565, 0xd2370a8c, 0x8ecb4a3f, 0xd6758196],
773 [0xa1e75a16, 0xc9e230ed, 0x23de50f3, 0x2366967a],
774 [0x690a2a91, 0xfa4acef1, 0xd3de6dd0, 0x973031d9],
775 [0xb392e62a, 0x22b0d3f2, 0x0e975a86, 0x14d6dcb3],
776 [0x5e002202, 0xc80e236e, 0x0b484e02, 0x00035f47],
777 [0x4fc0f301, 0x8ec0d33d, 0xe71a12dd, 0xe799731f],
778 [0x278c9096, 0xec7fa833, 0x2094d81f, 0x52e21165],
779 [0xd55238a8, 0xf040101a, 0x1152b6fe, 0x661c9e64],
780 [0x3699d16e, 0x89d9f2d7, 0x9ad59597, 0x7361ee21],
781 [0x1419c93c, 0x91b75784, 0x18f7121d, 0xec2c6b78],
782 [0x07c435da, 0x05f18557, 0xf28ce1e0, 0x43cadcba],
783 [0x2015269d, 0x52cad948, 0xd6485611, 0x06fe33d7],
784 [0x0cea56f3, 0x82c30841, 0x9b2a8cab, 0x8a6f07cb],
785 [0x81f82aa9, 0x233060d5, 0x00f4171e, 0xe14c0c2a],
786 [0x9b2f8b08, 0x7d091eac, 0x09dcb2c3, 0xa7670405],
787 [0x99c97f75, 0xf91c6b12, 0xfbad7705, 0x1c6e6f27],
788 [0xc762b89c, 0xbf44a194, 0xb2a54dc2, 0xae2103e4],
789 [0xba4f52ed, 0xe35aff77, 0x50d8c9d3, 0xeb382d32],
790 [0x9bc9d9a0, 0x7cb4c594, 0xbc1af6f4, 0x1f718229],
791 [0x5f19eea2, 0x6260982e, 0x393fb360, 0x71abe746],
792 [0xd13f2fcc, 0x88a6a714, 0xf4f53d55, 0xf42b11ba],
793 [0x4208b476, 0xaf06ffce, 0x38e59bfe, 0x588567a2],
794 [0xbedfb7b7, 0x8300a39d, 0x964a3c0f, 0x577d52d7],
795 [0x18e5a6f2, 0x7ec85996, 0x27694f30, 0x7717748a],
796 [0xb5e6d70f, 0xc43261bb, 0xd4e6ae7c, 0xcc11f79c],
797 [0xc808cba7, 0xbb042416, 0x2f01ebe1, 0x7d176a38],
798 [0x03353805, 0x4b6e9d66, 0x25933123, 0x4213aaf7],
799 [0x189a6da5, 0x04a4cbe6, 0xea3c9d09, 0x153fdee2],
800 [0x41f8ac6b, 0xb476356b, 0xc70b67d0, 0x28caf359],
801 [0x4514b6a4, 0x788545ff, 0x4ee9139b, 0xa45bedf9],
802 [0x2a39be04, 0xac9921cb, 0x685c1bf9, 0x904bdab2],
803 [0x2c18f3ef, 0x416c0335, 0x0face768, 0x1b9d5cd2],
804 [0x898cd63f, 0x60af727f, 0x6bdf1be6, 0x0df05cfe],
805 [0x8a06787b, 0x7cee2f8b, 0xdc8aac77, 0x2e0e740a],
806 [0x3d340571, 0xbf1c8d4c, 0xddc23f69, 0xd1903942],
807 [0x7d179e85, 0x54048c4d, 0xba047d33, 0x2e9e5edb],
808 [0x65e26600, 0x87c8421d, 0xa77e2c6c, 0x32b4971a],
809 [0x69041052, 0xa4858c7b, 0x904d84f7, 0xb4ad3dcf],
810 [0x3ea0246d, 0x533e752d, 0x1d55798a, 0x30e17e72],
811 [0x4254a700, 0x07365f23, 0x0f9da313, 0xaecd38ce],
812 [0xa5756d9d, 0x79f31387, 0x0ded3654, 0xa7299663],
813 [0x4ef027c9, 0xeebb1383, 0x26a55289, 0x3746969d],
814 [0xdc6acadf, 0x23e1b6e1, 0x07fcdc26, 0x9914b684],
815 [0x52bb8b80, 0x1a5688ae, 0xd429662d, 0x1cc1485d],
816 [0x76b35f59, 0x24b64e5b, 0xbcbeaee7, 0xf568a832],
817 [0x0756d15f, 0x9cc288bf, 0x9f882a3c, 0xfe7c7161],
818 [0x0503113a, 0x95e716ff, 0x304cf65e, 0x490725e8],
819 [0x7db7ba62, 0x08e4e77d, 0xc9db6413, 0xea3f1a39],
820 [0x7cef6d67, 0xc94867e6, 0x5c674de6, 0x5eb74081],
821 [0x7573b799, 0x069d4f03, 0x63b537a1, 0xdfe25db6],
822 [0xc401e705, 0x834828bc, 0xd99da4a1, 0xd0f3bee8],
823 [0x02817844, 0xada6433e, 0x31761e98, 0x901ccf68],
824 [0x8f9432b4, 0x9f860957, 0xcba54c86, 0x8beb8209],
825 [0x6a46e58c, 0x7d299228, 0x5c001d12, 0xd8db2a00],
826 [0x0c12586d, 0x866d8ca9, 0x849bbb17, 0x5af63ea2],
827 [0xe48671b6, 0xc4377063, 0xc4d03c02, 0x621bd894],
828 [0x5f7f82eb, 0xcdb5abf5, 0x325f2d9d, 0x24a5d200],
829 [0xec6b6fe7, 0x347316c4, 0x6241904a, 0x4e2497a5],
830 [0xf661b7fd, 0xa00e2fc7, 0x90e11456, 0x507fef21],
831 [0x77c7addd, 0x67148dce, 0x1cd27059, 0xefbf4abf],
832 [0x11270d9c, 0xb352779d, 0x81f21055, 0xae93a8b6],
833 [0x3d1f0aaf, 0x3b4aa6d8, 0xca1c160c, 0x6fe4f2bd],
834 [0x17c6bec4, 0x54b568cd, 0xd19c78d6, 0x9a3d897a],
835 [0xc4ab4ca6, 0xbf3b2573, 0xb4d837dd, 0x4dfab799],
836 [0x6fd5645d, 0xa34978b2, 0x6696dd1a, 0x665ca09b],
837 [0x87984bb9, 0xd4d3bc30, 0x7f8bb7a8, 0x2d83b303],
838 [0x21fb5d58, 0x1ee47d1a, 0x97200d83, 0x1d596a88],
839 [0x2656f329, 0x497693be, 0xca971ddf, 0x410d4092],
840 [0xd285c512, 0xfc1ed632, 0x63c43ec2, 0xac5766d1],
841 [0x46fb80ee, 0xcfeecdaa, 0x7237a433, 0x5708ff56],
842 [0x4fccd9c8, 0x7b1a4f31, 0x51516a80, 0x27bf3cae],
843 [0xd649d2f5, 0xebadf1f7, 0x6b34e8ce, 0xb87e82f1],
844 [0x6eb0aec6, 0xfbe9cb51, 0x39e695b4, 0xa6e46e70]]));