1 use nihav_core::io::bitreader::*;
2 use nihav_core::formats;
3 use nihav_core::frame::*;
4 use nihav_core::codecs::*;
8 fn calc_quant(glob_q: u32, qd: i16) -> usize {
9 let qq = (glob_q as i16) + (qd as i16);
53 fn skip_extension(br: &mut BitReader) -> DecoderResult<()> {
55 let len = br.read(8)?;
56 if len == 0 { break; }
62 impl IndeoXParser for Indeo5Parser {
63 #[allow(unused_variables)]
64 #[allow(unused_assignments)]
65 fn decode_picture_header(&mut self, br: &mut BitReader) -> DecoderResult<PictureHeader> {
66 let sync = br.read(5)?;
67 validate!(sync == 0x1F);
68 let ftype_idx = br.read(3)?;
69 validate!(ftype_idx < 5);
70 let ftype = INDEO5_FRAME_TYPE[ftype_idx as usize];
71 let fnum = br.read(8)?;
72 if ftype == IVIFrameType::Intra {
73 let gop_flags = br.read(8)?;
75 if (gop_flags & 0x01) != 0 {
76 hdr_size = br.read(16)?;
80 if (gop_flags & 0x20) != 0 {
81 br.skip(32)?; // lock word
85 if (gop_flags & 0x40) != 0 {
86 self.tile_w = 64 << br.read(2)?;
87 self.tile_h = self.tile_w;
89 validate!(self.tile_w < 256);
90 self.luma_bands = (br.read(2)? * 3 + 1) as usize;
91 self.chroma_bands = (br.read(1)? * 3 + 1) as usize;
92 validate!((self.luma_bands == 4) || (self.luma_bands == 1));
93 validate!(self.chroma_bands == 1);
94 let pic_size_idx = br.read(4)? as usize;
97 if pic_size_idx < 15 {
98 w = INDEO5_PICTURE_SIZE_TAB[pic_size_idx][0];
99 h = INDEO5_PICTURE_SIZE_TAB[pic_size_idx][1];
101 h = br.read(13)? as usize;
102 w = br.read(13)? as usize;
104 validate!((w != 0) && (h != 0));
108 validate!((gop_flags & 0x02) == 0);
109 if self.tile_w == 0 {
113 for b in 0..self.luma_bands+self.chroma_bands {
114 self.is_hpel[b] = br.read_bool()?;
115 let mb_scale = br.read(1)?;
116 self.blk_size[b] = 8 >> br.read(1)?;
117 self.mb_size[b] = self.blk_size[b] << (1 - mb_scale);
118 let ext_tr = br.read_bool()?;
120 let end_marker = br.read(2)?;
121 validate!(end_marker == 0);
123 if (gop_flags & 0x08) != 0 {
124 let align = br.read(3)?;
125 validate!(align == 0);
127 br.skip(24)?; // transparency color
132 if br.read_bool()? { // gop extension
134 let v = br.read(16)?;
135 if (v & 0x8000) == 0 { break; }
142 return Ok(PictureHeader::new_null(ftype));
144 let flags = br.read(8)?;
146 if (flags & 0x01) != 0 {
152 if (flags & 0x10) != 0 {
153 checksum = br.read(16)?;
157 if (flags & 0x20) != 0 {
160 let in_q = (flags & 0x08) != 0;
161 self.mb_cb = br.read_ivi_codebook_desc(true, (flags & 0x40) != 0)?;
165 Ok(PictureHeader::new(ftype, self.width, self.height, self.tile_w, self.tile_h, false, self.luma_bands, self.chroma_bands, in_q))
168 #[allow(unused_variables)]
169 fn decode_band_header(&mut self, br: &mut BitReader, pic_hdr: &PictureHeader, plane_no: usize, band_no: usize) -> DecoderResult<BandHeader> {
170 let band_flags = br.read(8)?;
172 if (band_flags & 0x01) != 0 {
174 return Ok(BandHeader::new_empty(plane_no, band_no));
176 let inherit_mv = (band_flags & 0x02) != 0;
177 let has_qdelta = (band_flags & 0x04) != 0;
178 let inherit_qd = ((band_flags & 0x08) != 0) || !has_qdelta;
179 let data_size: usize;
180 if (band_flags & 0x80) != 0 {
181 data_size = br.read(24)? as usize;
185 validate!(data_size <= ((br.left() / 8) as usize));
188 let mut corr_map: [u8; CORR_MAP_SIZE] = [0; CORR_MAP_SIZE];
189 if (band_flags & 0x10) != 0 {
190 num_corr = br.read(8)? as usize;
191 validate!(num_corr*2 <= CORR_MAP_SIZE);
192 for i in 0..num_corr*2 {
193 corr_map[i] = br.read(8)? as u8;
199 if (band_flags & 0x40) != 0 {
200 rvmap_idx = br.read(3)? as usize;
204 let blk_cb = br.read_ivi_codebook_desc(false, (band_flags & 0x80) != 0)?;
206 br.skip(16)?; // checksum
208 let band_q = br.read(5)?;
209 if (band_flags & 0x20) != 0 {
216 let band_id = if plane_no == 0 { band_no } else { self.luma_bands };
219 let scan = INDEO5_SCAN8X8[band_no];
222 validate!(self.blk_size[band_id] == 8);
225 tr = IVITransformType::Slant(TSize::T8x8, TDir::TwoD);
226 if self.luma_bands == 1 {
227 qintra = INDEO5_Q8_INTRA[0];
228 qinter = INDEO5_Q8_INTER[0];
230 qintra = INDEO5_Q8_INTRA[1];
231 qinter = INDEO5_Q8_INTER[1];
235 tr = IVITransformType::Slant(TSize::T8x8, TDir::Row);
236 qintra = INDEO5_Q8_INTRA[2];
237 qinter = INDEO5_Q8_INTER[2];
240 tr = IVITransformType::Slant(TSize::T8x8, TDir::Col);
241 qintra = INDEO5_Q8_INTRA[3];
242 qinter = INDEO5_Q8_INTER[3];
245 tr = IVITransformType::None(TSize::T8x8);
246 qintra = INDEO5_Q8_INTRA[4];
247 qinter = INDEO5_Q8_INTER[4];
249 _ => { unreachable!(); }
251 txtype = TxType::Transform8(TxParams8x8::new(qintra, qinter, scan));
254 validate!(self.blk_size[band_id] == 4);
255 tr = IVITransformType::Slant(TSize::T4x4, TDir::TwoD);
256 let scan = INDEO5_SCAN4X4;
257 let qintra = INDEO5_Q4_INTRA;
258 let qinter = INDEO5_Q4_INTER;
259 txtype = TxType::Transform4(TxParams4x4::new(qintra, qinter, scan));
261 _ => { unreachable!(); }
264 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))
267 fn decode_mb_info(&mut self, br: &mut BitReader, pic_hdr: &PictureHeader, band: &BandHeader, tile: &mut IVITile, ref_tile: Option<Ref<IVITile>>, mv_scale: u8) -> DecoderResult<()> {
270 let band_id = if pic_hdr.luma_bands == 4 { band.band_no + 1 } else { 0 };
272 for mb_y in 0..tile.mb_h {
273 for mb_x in 0..tile.mb_w {
274 let mut mb = MB::new(tile.pos_x + mb_x * band.mb_size, tile.pos_y + mb_y * band.mb_size);
275 if !br.read_bool()? {
276 if pic_hdr.ftype.is_intra() {
277 mb.mtype = MBType::Intra;
278 } else if band.inherit_mv {
279 if let Some(ref tileref) = ref_tile {
280 mb.mtype = tileref.mb[mb_idx].mtype;
282 return Err(DecoderError::MissingReference);
285 mb.mtype = if br.read_bool()? { MBType::Inter } else { MBType::Intra };
287 if band.mb_size == band.blk_size {
288 mb.cbp = br.read(1)? as u8;
290 mb.cbp = br.read(4)? as u8;
295 if let Some(ref tileref) = ref_tile {
296 mb.qd = tileref.mb[mb_idx].qd;
297 q = calc_quant(band.quant, mb.qd);
299 return Err(DecoderError::MissingReference);
301 } else if (mb.cbp != 0) || ((band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q) {
302 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
303 q = calc_quant(band.quant, mb.qd);
305 q = band.quant as usize;
308 q = band.quant as usize;
311 if mb.mtype == MBType::Intra {
312 if band.blk_size == 8 {
313 mb.q = INDEO5_QSCALE8_INTRA[band_id][q];
315 mb.q = INDEO5_QSCALE4_INTRA[q];
318 if band.blk_size == 8 {
319 mb.q = INDEO5_QSCALE8_INTER[band_id][q];
321 mb.q = INDEO5_QSCALE4_INTER[q];
325 if mb.mtype != MBType::Intra {
327 if let Some(ref tileref) = ref_tile {
328 let mx = tileref.mb[mb_idx].mv_x;
329 let my = tileref.mb[mb_idx].mv_y;
334 mb.mv_x = scale_mv(mx, mv_scale);
335 mb.mv_y = scale_mv(my, mv_scale);
339 mv_y += br.read_ivi_cb_s(&self.mb_cb)?;
340 mv_x += br.read_ivi_cb_s(&self.mb_cb)?;
346 validate!(!pic_hdr.ftype.is_intra());
347 mb.mtype = MBType::Inter;
350 if (band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q {
351 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
352 let q = calc_quant(band.quant, mb.qd);
353 if mb.mtype == MBType::Intra {
354 if band.blk_size == 8 {
355 mb.q = INDEO5_QSCALE8_INTRA[band_id][q];
357 mb.q = INDEO5_QSCALE4_INTRA[q];
360 if band.blk_size == 8 {
361 mb.q = INDEO5_QSCALE8_INTER[band_id][q];
363 mb.q = INDEO5_QSCALE4_INTER[q];
368 if let Some(ref tileref) = ref_tile {
369 let mx = tileref.mb[mb_idx].mv_x;
370 let my = tileref.mb[mb_idx].mv_y;
375 mb.mv_x = scale_mv(mx, mv_scale);
376 mb.mv_y = scale_mv(my, mv_scale);
381 tile.mb[mb_idx] = mb;
389 fn recombine_plane(&mut self, src: &[i16], sstride: usize, dst: &mut [u8], dstride: usize, w: usize, h: usize) {
391 let mut idx1 = w / 2;
392 let mut idx2 = (h / 2) * sstride;
393 let mut idx3 = idx2 + idx1;
394 let mut bidx1 = idx1;
395 let mut bidx3 = idx3;
397 let mut oidx1 = dstride;
398 let filt_lo = |a: i16, b: i16| a + b;
399 let filt_hi = |a: i16, b: i16, c: i16| a - b * 6 + c;
402 let mut b0_1 = src[idx0];
403 let mut b0_2 = src[idx0 + sstride];
404 let mut b1_1 = src[bidx1];
405 let mut b1_2 = src[idx1];
406 let mut b1_3 = filt_hi(b1_1, b1_2, src[idx1 + sstride]);
408 let mut b2_2 = src[idx2];
411 let mut b2_5 = src[idx2 + sstride];
414 let mut b3_2 = src[bidx3];
417 let mut b3_5 = src[idx3];
419 let mut b3_8 = filt_hi(b3_2, b3_5, src[idx3 + sstride]);
437 b0_1 = src[idx0 + x + 1];
438 b0_2 = src[idx0 + x + 1 + sstride];
439 let mut p0 = tmp0 << 4;
440 let mut p1 = (tmp0 + b0_1) << 3;
441 let mut p2 = (tmp0 + tmp1) << 3;
442 let mut p3 = (tmp0 + tmp1 + b0_1 + b0_2) << 2;
446 let tmp2 = filt_lo(tmp0, tmp1);
447 let tmp3 = filt_hi(tmp0, tmp1, b1_3);
448 b1_2 = src[ idx1 + x + 1];
449 b1_1 = src[bidx1 + x + 1];
450 b1_3 = filt_hi(b1_1, b1_2, src[idx1 + x + 1 + sstride]);
452 p1 += (tmp2 + b1_1 + b1_2) << 2;
454 p3 += (tmp3 + b1_3) << 1;
456 b2_3 = src[idx2 + x + 1];
457 b2_6 = src[idx2 + x + 1 + sstride];
458 let tmp0 = filt_lo(b2_1, b2_2);
459 let tmp1 = filt_hi(b2_1, b2_2, b2_3);
462 p2 += (tmp0 + filt_lo(b2_4, b2_5)) << 2;
463 p3 += (tmp1 + filt_hi(b2_4, b2_5, b2_6)) << 1;
465 b3_6 = src[idx3 + x + 1];
466 b3_3 = src[bidx3 + x + 1];
467 b3_9 = filt_hi(b3_3, b3_6, src[idx3 + x + 1 + sstride]);
468 let tmp0 = b3_1 + b3_4;
469 let tmp1 = b3_2 + b3_5;
470 let tmp2 = b3_3 + b3_6;
471 p0 += filt_lo(tmp0, tmp1) << 2;
472 p1 += filt_hi(tmp0, tmp1, tmp2) << 1;
473 p2 += filt_lo(b3_7, b3_8) << 1;
474 p3 += filt_hi(b3_7, b3_8, b3_9) << 0;
476 dst[oidx0 + x * 2 + 0] = clip8((p0 >> 6) + 128);
477 dst[oidx0 + x * 2 + 1] = clip8((p1 >> 6) + 128);
478 dst[oidx1 + x * 2 + 0] = clip8((p2 >> 6) + 128);
479 dst[oidx1 + x * 2 + 1] = clip8((p3 >> 6) + 128);
487 oidx0 += dstride * 2;
488 oidx1 += dstride * 2;
493 struct Indeo5Decoder {
494 info: NACodecInfoRef,
502 info: NACodecInfo::new_dummy(),
503 dec: IVIDecoder::new(),
504 ip: Indeo5Parser::new(),
509 impl NADecoder for Indeo5Decoder {
510 fn init(&mut self, info: NACodecInfoRef) -> DecoderResult<()> {
511 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
512 let w = vinfo.get_width();
513 let h = vinfo.get_height();
514 let f = vinfo.is_flipped();
515 let fmt = formats::YUV410_FORMAT;
516 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, f, fmt));
517 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
520 Err(DecoderError::InvalidData)
523 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
524 let src = pkt.get_buffer();
525 let mut br = BitReader::new(src.as_slice(), src.len(), BitReaderMode::LE);
527 let bufinfo = self.dec.decode_frame(&mut self.ip, &mut br)?;
528 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
529 frm.set_keyframe(self.dec.is_intra());
530 frm.set_frame_type(self.dec.get_frame_type());
531 Ok(Rc::new(RefCell::new(frm)))
535 const INDEO5_PICTURE_SIZE_TAB: [[usize; 2]; 15] = [
536 [640, 480], [320, 240], [160, 120], [704, 480], [352, 240], [352, 288], [176, 144],
537 [240, 180], [640, 240], [704, 240], [80, 60], [88, 72], [0, 0], [0, 0], [0, 0]
540 const INDEO5_FRAME_TYPE: [IVIFrameType; 5] = [
541 IVIFrameType::Intra, IVIFrameType::Inter, IVIFrameType::InterScal,
542 IVIFrameType::InterDroppable, IVIFrameType::NULL,
545 const INDEO5_QUANT8X8_INTRA: [[u16; 64]; 5] = [
547 0x1a, 0x2e, 0x36, 0x42, 0x46, 0x4a, 0x4e, 0x5a,
548 0x2e, 0x32, 0x3e, 0x42, 0x46, 0x4e, 0x56, 0x6a,
549 0x36, 0x3e, 0x3e, 0x44, 0x4a, 0x54, 0x66, 0x72,
550 0x42, 0x42, 0x44, 0x4a, 0x52, 0x62, 0x6c, 0x7a,
551 0x46, 0x46, 0x4a, 0x52, 0x5e, 0x66, 0x72, 0x8e,
552 0x4a, 0x4e, 0x54, 0x62, 0x66, 0x6e, 0x86, 0xa6,
553 0x4e, 0x56, 0x66, 0x6c, 0x72, 0x86, 0x9a, 0xca,
554 0x5a, 0x6a, 0x72, 0x7a, 0x8e, 0xa6, 0xca, 0xfe,
556 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
557 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
558 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
559 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
560 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
561 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
562 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
563 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
565 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
566 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
567 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
568 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
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,
574 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
575 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
576 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
577 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
578 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
579 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
580 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
581 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
583 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
584 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
585 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
586 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
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,
593 const INDEO5_QUANT8X8_INTER: [[u16; 64]; 5] = [
595 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
596 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
597 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
598 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
599 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
600 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
601 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
602 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
604 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
605 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
606 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
607 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
608 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
609 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
610 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
611 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
613 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
614 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
615 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
616 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
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,
622 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
623 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
624 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
625 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
626 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
627 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
628 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
629 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
631 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
632 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
633 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
634 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
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,
641 const INDEO5_QUANT4X4_INTRA: [u16; 16] = [
642 0x1e, 0x3e, 0x4a, 0x52,
643 0x3e, 0x4a, 0x52, 0x5e,
644 0x4a, 0x52, 0x5e, 0x7a,
645 0x52, 0x5e, 0x7a, 0x92
647 const INDEO5_QUANT4X4_INTER: [u16; 16] = [
648 0x1e, 0x3e, 0x4a, 0x52,
649 0x3e, 0x4a, 0x52, 0x56,
650 0x4a, 0x52, 0x56, 0x5e,
651 0x52, 0x56, 0x5e, 0x66
653 const INDEO5_Q8_INTRA: [&[u16; 64]; 5] = [
654 &INDEO5_QUANT8X8_INTRA[0], &INDEO5_QUANT8X8_INTRA[1], &INDEO5_QUANT8X8_INTRA[2],
655 &INDEO5_QUANT8X8_INTRA[3], &INDEO5_QUANT8X8_INTRA[4],
657 const INDEO5_Q8_INTER: [&[u16; 64]; 5] = [
658 &INDEO5_QUANT8X8_INTER[0], &INDEO5_QUANT8X8_INTER[1], &INDEO5_QUANT8X8_INTER[2],
659 &INDEO5_QUANT8X8_INTER[3], &INDEO5_QUANT8X8_INTER[4],
661 const INDEO5_Q4_INTRA: &[u16; 16] = &INDEO5_QUANT4X4_INTRA;
662 const INDEO5_Q4_INTER: &[u16; 16] = &INDEO5_QUANT4X4_INTER;
664 const INDEO5_SCAN8X8: [&[usize; 64]; 4] = [
665 &IVI_ZIGZAG, &IVI_SCAN_8X8_VER, &IVI_SCAN_8X8_HOR, &IVI_SCAN_8X8_HOR
667 const INDEO5_SCAN4X4: &[usize; 16] = &IVI_SCAN_4X4;
669 const INDEO5_QSCALE8_INTRA: [[u8; 24]; 5] = [
671 0x0b, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
672 0x22, 0x24, 0x27, 0x28, 0x2a, 0x2d, 0x2f, 0x31, 0x34, 0x37, 0x39, 0x3c,
674 0x01, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x28, 0x2c,
675 0x30, 0x34, 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x52, 0x58, 0x5e, 0x65, 0x6c,
677 0x13, 0x22, 0x27, 0x2a, 0x2d, 0x33, 0x36, 0x3c, 0x41, 0x45, 0x49, 0x4e,
678 0x53, 0x58, 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x7c, 0x82, 0x88, 0x8e, 0x95,
680 0x13, 0x1f, 0x21, 0x24, 0x27, 0x29, 0x2d, 0x2f, 0x34, 0x37, 0x3a, 0x3d,
681 0x40, 0x44, 0x48, 0x4c, 0x4f, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6b,
683 0x31, 0x42, 0x47, 0x47, 0x4d, 0x52, 0x58, 0x58, 0x5d, 0x63, 0x67, 0x6b,
684 0x6f, 0x73, 0x78, 0x7c, 0x80, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa4,
687 const INDEO5_QSCALE8_INTER: [[u8; 24]; 5] = [
689 0x0b, 0x11, 0x13, 0x14, 0x15, 0x16, 0x18, 0x1a, 0x1b, 0x1d, 0x20, 0x22,
690 0x23, 0x25, 0x28, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x41, 0x44, 0x4a,
692 0x07, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
693 0x3a, 0x3f, 0x44, 0x4a, 0x50, 0x56, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x7e,
695 0x15, 0x25, 0x28, 0x2d, 0x30, 0x34, 0x3a, 0x3d, 0x42, 0x48, 0x4c, 0x51,
696 0x56, 0x5b, 0x60, 0x65, 0x6b, 0x70, 0x76, 0x7c, 0x82, 0x88, 0x8f, 0x97,
698 0x13, 0x1f, 0x20, 0x22, 0x25, 0x28, 0x2b, 0x2d, 0x30, 0x33, 0x36, 0x39,
699 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4b, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62,
701 0x3c, 0x52, 0x58, 0x5d, 0x63, 0x68, 0x68, 0x6d, 0x73, 0x78, 0x7c, 0x80,
702 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa3, 0xa9, 0xad, 0xb1, 0xb5, 0xba
705 const INDEO5_QSCALE4_INTRA: [u8; 24] = [
706 0x01, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14,
707 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
709 const INDEO5_QSCALE4_INTER: [u8; 24] = [
710 0x0b, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
711 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
714 pub fn get_decoder() -> Box<NADecoder> {
715 Box::new(Indeo5Decoder::new())
720 use nihav_core::codecs::RegisteredDecoders;
721 use nihav_core::demuxers::RegisteredDemuxers;
722 use nihav_core::test::dec_video::*;
723 use crate::codecs::indeo_register_all_codecs;
724 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
727 let mut dmx_reg = RegisteredDemuxers::new();
728 generic_register_all_demuxers(&mut dmx_reg);
729 let mut dec_reg = RegisteredDecoders::new();
730 indeo_register_all_codecs(&mut dec_reg);
732 test_file_decoding("avi", "assets/Indeo/IV5/sample.avi", /*None*/Some(2), true, false, None, &dmx_reg, &dec_reg);
733 // test_file_decoding("avi", "assets/Indeo/IV5/W32mdl_1.avi", None/*Some(2)*/, true, false, Some("iv5"));