rename register_all_codecs to register_all_decoders
[nihav.git] / nihav-indeo / src / codecs / indeo4.rs
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;
6 use super::ivi::*;
7 use super::ivibr::*;
8
9 #[inline(always)]
10 fn mclip8(a: i32) -> u8 {
11 if (a as u16) > 255 { !(a >> 16) as u8 }
12 else { a as u8 }
13 }
14
15 struct Indeo4Parser {
16 mb_cb: IVICodebook,
17 blk_cb: IVICodebook,
18 }
19
20 fn calc_quant(glob_q: u32, qd: i16) -> u8 {
21 let q = (glob_q as i16) + qd;
22 if q < 0 {
23 0
24 } else if q > 31 {
25 31
26 } else {
27 q as u8
28 }
29 }
30
31 impl Indeo4Parser {
32 fn new() -> Self {
33 Indeo4Parser {
34 mb_cb: IVI_CB_ZERO,
35 blk_cb: IVI_CB_ZERO,
36 }
37 }
38 }
39
40 impl IndeoXParser for Indeo4Parser {
41 #[allow(unused_variables,unused_assignments)]
42 fn decode_picture_header(&mut self, br: &mut BitReader) -> DecoderResult<PictureHeader> {
43 let sync = br.read(18)?;
44 validate!(sync == 0x3FFF8);
45 let ftype_idx = br.read(3)?;
46 validate!(ftype_idx < 7);
47 let ftype = INDEO4_FRAME_TYPE[ftype_idx as usize];
48 let transparent = br.read_bool()?;
49 br.skip(1)?;
50 let data_size;
51 if br.read_bool()? {
52 data_size = br.read(24)? as usize;
53 } else {
54 data_size = 0;
55 }
56 if ftype.is_null() {
57 return Ok(PictureHeader::new_null(ftype));
58 }
59 if br.read_bool()? {
60 br.skip(32)?; // key lock
61 }
62 let width;
63 let height;
64 let pic_size_idx = br.read(3)?;
65 if pic_size_idx < 7 {
66 width = INDEO4_PICTURE_SIZE_TAB[pic_size_idx as usize][0];
67 height = INDEO4_PICTURE_SIZE_TAB[pic_size_idx as usize][1];
68 } else {
69 height = br.read(16)? as usize;
70 width = br.read(16)? as usize;
71 validate!((width > 0) && ((width & 3) == 0));
72 validate!((height > 0) && ((height & 3) == 0));
73 }
74
75 let slice_w;
76 let slice_h;
77 if br.read_bool()? {
78 let idx = br.read(4)? as usize;
79 if idx < 15 {
80 slice_w = INDEO4_SLICE_SIZE_TAB[idx];
81 slice_h = INDEO4_SLICE_SIZE_TAB[idx];
82 } else {
83 slice_w = width;
84 slice_h = height;
85 }
86 } else {
87 slice_w = width;
88 slice_h = height;
89 }
90 let subsampling = br.read(2)?;
91 validate!(subsampling == 0);
92 let sc_idx = br.read(2)?;
93 match sc_idx {
94 3 => { },
95 2 => { validate!(br.read(2*4)? == 0xFF); }
96 _ => { return Err(DecoderError::InvalidData); }
97 };
98 let luma_bands = if sc_idx == 2 { 4 } else { 1 };
99 let sc_idx = br.read(2)?;
100 match sc_idx {
101 3 => { },
102 2 => { validate!(br.read(2*4)? == 0xFF); }
103 _ => { return Err(DecoderError::InvalidData); }
104 };
105 let chroma_bands = if sc_idx == 2 { 4 } else { 1 };
106 let frame_no;
107 if br.read_bool()? {
108 frame_no = br.read(20)?;
109 } else {
110 frame_no = 0;
111 }
112 if br.read_bool()? {
113 br.skip(8)?; // decTimeEst
114 }
115 let desc_coded = br.read_bool()?;
116 self.mb_cb = br.read_ivi_codebook_desc(true, desc_coded)?;
117 let desc_coded = br.read_bool()?;
118 self.blk_cb = br.read_ivi_codebook_desc(false, desc_coded)?;
119 let rvmap = if br.read_bool()? { br.read(3)? as usize } else { 8 };
120 let in_imf = br.read_bool()?;
121 let in_q = br.read_bool()?;
122 let glob_q = br.read(5)? as u8;
123 if br.read_bool()? {
124 br.skip(3)?;
125 }
126 let checksum = if br.read_bool()? { br.read(16)? } else { 0 };
127 if br.read_bool()? {
128 br.skip(8)?; // pic hdr extension
129 }
130 if br.read_bool()? {
131 println!("bad blocks bits!");
132 }
133 br.align();
134
135 Ok(PictureHeader::new(ftype, width, height, slice_w, slice_h, transparent, luma_bands, chroma_bands, in_q))
136 }
137
138 #[allow(unused_variables,unused_assignments)]
139 fn decode_band_header(&mut self, br: &mut BitReader, pic_hdr: &PictureHeader, plane: usize, band: usize) -> DecoderResult<BandHeader> {
140 let plane_no = br.read(2)? as usize;
141 let band_no = br.read(4)? as usize;
142 validate!(plane_no == plane);
143 validate!(band_no == band);
144 if br.read_bool()? {
145 br.align();
146 return Ok(BandHeader::new_empty(plane_no, band_no));
147 }
148 let hdr_size;
149 if br.read_bool()? {
150 hdr_size = br.read(16)? as usize;
151 } else {
152 hdr_size = 32;
153 }
154 let mv_mode = br.read(2)?;
155 validate!(mv_mode < 2);
156 if br.read_bool()? {
157 br.skip(16)?; //checksum
158 }
159
160 let scale = br.read(2)?;
161 validate!(scale != 3);
162 let mb_size = 16 >> scale;
163 let blk_size = 8 >> (scale >> 1);
164 let inherit_mv = br.read_bool()?;
165 let inherit_qd = br.read_bool()?;
166 let quant = br.read(5)?;
167
168 let tr: IVITransformType;
169 let txtype: TxType;
170 if !br.read_bool()? || pic_hdr.ftype == IVIFrameType::Intra {
171 let tr_id = br.read(5)?;
172 validate!(tr_id < 18);
173 let scan_idx = br.read(4)? as usize;
174 validate!(scan_idx != 15);
175 let qmat_idx = br.read(5)? as usize;
176
177 tr = INDEO4_TRANSFORMS[tr_id as usize];
178 if (scan_idx < 5) || (scan_idx >= 10) {
179 validate!(tr.is_8x8());
180 validate!(qmat_idx < 15);
181 let scan = if scan_idx < 5 { INDEO4_SCANS_8X8[scan_idx] }
182 else { INDEO4_SCANS_8X8[4] };
183 let qidx = INDEO4_Q8X8_IDX[qmat_idx];
184 let qintra = INDEO4_Q8_INTRA[qidx];
185 let qinter = INDEO4_Q8_INTER[qidx];
186 txtype = TxType::Transform8(TxParams8x8::new(qintra, qinter, scan));
187 } else if scan_idx < 10 {
188 validate!(!tr.is_8x8());
189 validate!((qmat_idx >= 15) && (qmat_idx < 22));
190 let scan = INDEO4_SCANS_4X4[scan_idx - 5];
191 let qidx = INDEO4_Q4X4_IDX[qmat_idx - 15];
192 let qintra = INDEO4_Q4_INTRA[qidx];
193 let qinter = INDEO4_Q4_INTER[qidx];
194 txtype = TxType::Transform4(TxParams4x4::new(qintra, qinter, scan));
195 } else {
196 unreachable!();
197 }
198 } else {
199 tr = IVITransformType::None(TSize::T8x8);
200 txtype = TxType::None;
201 }
202
203 let blk_cb;
204 if br.read_bool()? {
205 blk_cb = br.read_ivi_codebook_desc(false, true)?;
206 } else {
207 blk_cb = self.blk_cb;
208 }
209 let rvmap_idx;
210 if br.read_bool()? {
211 rvmap_idx = br.read(3)? as usize;
212 } else {
213 rvmap_idx = 8;
214 }
215 let num_corr;
216 let mut corr_map: [u8; CORR_MAP_SIZE] = [0; CORR_MAP_SIZE];
217 if br.read_bool()? {
218 num_corr = br.read(8)? as usize;
219 validate!(num_corr*2 <= CORR_MAP_SIZE);
220 for i in 0..num_corr*2 {
221 corr_map[i] = br.read(8)? as u8;
222 }
223 } else {
224 num_corr = 0;
225 }
226
227 br.align();
228 Ok(BandHeader::new(plane_no, band_no, mb_size, blk_size, mv_mode == 1, inherit_mv, false, inherit_qd, quant, rvmap_idx, num_corr, corr_map, blk_cb, tr, txtype))
229 }
230
231 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<()> {
232 let mut mv_x = 0;
233 let mut mv_y = 0;
234 let mut mb_idx = 0;
235
236 for mb_y in 0..tile.mb_h {
237 for mb_x in 0..tile.mb_w {
238 let mut mb = MB::new(tile.pos_x + mb_x * band.mb_size, tile.pos_y + mb_y * band.mb_size);
239 if !br.read_bool()? {
240 if pic_hdr.ftype.is_intra() {
241 mb.mtype = MBType::Intra;
242 } else if band.inherit_mv {
243 if let Some(ref tileref) = ref_tile {
244 mb.mtype = tileref.mb[mb_idx].mtype;
245 } else {
246 return Err(DecoderError::MissingReference);
247 }
248 } else {
249 if !pic_hdr.ftype.is_bidir() {
250 mb.mtype = if br.read_bool()? { MBType::Inter } else { MBType::Intra };
251 } else {
252 mb.mtype = match br.read(2)? {
253 0 => { MBType::Intra },
254 1 => { MBType::Inter },
255 2 => { MBType::Backward },
256 _ => { MBType::Bidir },
257 };
258 }
259 }
260 if band.mb_size == band.blk_size {
261 mb.cbp = br.read(1)? as u8;
262 } else {
263 mb.cbp = br.read(4)? as u8;
264 }
265 if band.inherit_qd {
266 if let Some(ref tileref) = ref_tile {
267 mb.qd = tileref.mb[mb_idx].qd;
268 mb.q = calc_quant(band.quant, mb.qd);
269 } else {
270 mb.q = band.quant as u8;
271 }
272 } else if (mb.cbp != 0) || ((band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q) {
273 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
274 mb.q = calc_quant(band.quant, mb.qd);
275 } else {
276 mb.q = band.quant as u8;
277 }
278
279 if mb.mtype != MBType::Intra {
280 if band.inherit_mv {
281 if let Some(ref tileref) = ref_tile {
282 let mx = tileref.mb[mb_idx].mv_x;
283 let my = tileref.mb[mb_idx].mv_y;
284 if mv_scale == 0 {
285 mb.mv_x = mx;
286 mb.mv_y = my;
287 } else {
288 mb.mv_x = scale_mv(mx, mv_scale);
289 mb.mv_y = scale_mv(my, mv_scale);
290 }
291 }
292 } else {
293 mv_y += br.read_ivi_cb_s(&self.mb_cb)?;
294 mv_x += br.read_ivi_cb_s(&self.mb_cb)?;
295 mb.mv_x = mv_x;
296 mb.mv_y = mv_y;
297 if mb.mtype == MBType::Backward {
298 mb.mv_x = -mb.mv_x;
299 mb.mv_y = -mb.mv_y;
300 } else if mb.mtype == MBType::Bidir {
301 mv_y += br.read_ivi_cb_s(&self.mb_cb)?;
302 mv_x += br.read_ivi_cb_s(&self.mb_cb)?;
303 mb.mv2_x = -mv_x;
304 mb.mv2_y = -mv_y;
305 }
306 }
307 }
308 } else {
309 validate!(!pic_hdr.ftype.is_intra());
310 mb.mtype = MBType::Inter;
311 mb.cbp = 0;
312 mb.qd = 0;
313 if (band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q {
314 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
315 mb.q = calc_quant(band.quant, mb.qd);
316 }
317 if band.inherit_mv {
318 if let Some(ref tileref) = ref_tile {
319 let mx = tileref.mb[mb_idx].mv_x;
320 let my = tileref.mb[mb_idx].mv_y;
321 if mv_scale == 0 {
322 mb.mv_x = mx;
323 mb.mv_y = my;
324 } else {
325 mb.mv_x = scale_mv(mx, mv_scale);
326 mb.mv_y = scale_mv(my, mv_scale);
327 }
328 }
329 }
330 }
331 tile.mb[mb_idx] = mb;
332 mb_idx += 1;
333 }
334 }
335 br.align();
336 Ok(())
337 }
338
339 fn recombine_plane(&mut self, src: &[i16], sstride: usize, dst: &mut [u8], dstride: usize, w: usize, h: usize) {
340 /* let mut idx0 = 0;
341 let mut idx1 = w / 2;
342 let mut idx2 = (h / 2) * sstride;
343 let mut idx3 = idx2 + idx1;
344 let mut oidx0 = 0;
345 let mut oidx1 = dstride;
346
347 for _ in 0..(h/2) {
348 for x in 0..(w/2) {
349 let p0 = src[idx0 + x];
350 let p1 = src[idx1 + x];
351 let p2 = src[idx2 + x];
352 let p3 = src[idx3 + x];
353 let s0 = p0 + p2;
354 let d0 = p0 - p2;
355 let s1 = p1 + p3;
356 let d1 = p1 - p3;
357 dst[oidx0 + x * 2 + 0] = clip8(((s0 + s1 + 2) >> 2) + 128);
358 dst[oidx0 + x * 2 + 1] = clip8(((d0 + d1 + 2) >> 2) + 128);
359 dst[oidx1 + x * 2 + 0] = clip8(((s0 - s1 + 2) >> 2) + 128);
360 dst[oidx1 + x * 2 + 1] = clip8(((d0 - d1 + 2) >> 2) + 128);
361 }
362 idx0 += sstride;
363 idx1 += sstride;
364 idx2 += sstride;
365 idx3 += sstride;
366 oidx0 += dstride * 2;
367 oidx1 += dstride * 2;
368 }*/
369 unsafe {
370 let hw = (w / 2) as isize;
371 let hh = (h / 2) as isize;
372 let mut band0 = src.as_ptr();
373 let mut band1 = band0.offset(hw);
374 let mut band2 = band0.add((h / 2) * sstride);
375 let mut band3 = band2.offset(hw);
376 let mut dst0 = dst.as_mut_ptr();
377 let mut dst1 = dst0.add(dstride);
378 for _ in 0..hh {
379 let mut b0_ptr = band0;
380 let mut b1_ptr = band1;
381 let mut b2_ptr = band2;
382 let mut b3_ptr = band3;
383 let mut d0_ptr = dst0;
384 let mut d1_ptr = dst1;
385 for _ in 0..hw {
386 let p0 = i32::from(*b0_ptr);
387 let p1 = i32::from(*b1_ptr);
388 let p2 = i32::from(*b2_ptr);
389 let p3 = i32::from(*b3_ptr);
390 let s0 = p0.wrapping_add(p2);
391 let s1 = p1.wrapping_add(p3);
392 let d0 = p0.wrapping_sub(p2);
393 let d1 = p1.wrapping_sub(p3);
394 let o0 = s0.wrapping_add(s1).wrapping_add(2);
395 let o1 = d0.wrapping_add(d1).wrapping_add(2);
396 let o2 = s0.wrapping_sub(s1).wrapping_add(2);
397 let o3 = d0.wrapping_sub(d1).wrapping_add(2);
398 *d0_ptr.offset(0) = mclip8((o0 >> 2).wrapping_add(128));
399 *d0_ptr.offset(1) = mclip8((o1 >> 2).wrapping_add(128));
400 *d1_ptr.offset(0) = mclip8((o2 >> 2).wrapping_add(128));
401 *d1_ptr.offset(1) = mclip8((o3 >> 2).wrapping_add(128));
402 b0_ptr = b0_ptr.offset(1);
403 b1_ptr = b1_ptr.offset(1);
404 b2_ptr = b2_ptr.offset(1);
405 b3_ptr = b3_ptr.offset(1);
406 d0_ptr = d0_ptr.offset(2);
407 d1_ptr = d1_ptr.offset(2);
408 }
409 band0 = band0.add(sstride);
410 band1 = band1.add(sstride);
411 band2 = band2.add(sstride);
412 band3 = band3.add(sstride);
413 dst0 = dst0.add(dstride * 2);
414 dst1 = dst1.add(dstride * 2);
415 }
416 }
417 }
418 }
419
420 struct Indeo4Decoder {
421 info: NACodecInfoRef,
422 dec: IVIDecoder,
423 }
424
425 impl Indeo4Decoder {
426 fn new() -> Self {
427 Indeo4Decoder {
428 info: NACodecInfo::new_dummy(),
429 dec: IVIDecoder::new(),
430 }
431 }
432 }
433
434 impl NADecoder for Indeo4Decoder {
435 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
436 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
437 let w = vinfo.get_width();
438 let h = vinfo.get_height();
439 let f = vinfo.is_flipped();
440 let fmt = formats::YUV410_FORMAT;
441 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, f, fmt));
442 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
443 Ok(())
444 } else {
445 Err(DecoderError::InvalidData)
446 }
447 }
448 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
449 let src = pkt.get_buffer();
450 let mut br = BitReader::new(src.as_slice(), BitReaderMode::LE);
451
452 let mut ip = Indeo4Parser::new();
453 let bufinfo = self.dec.decode_frame(&mut ip, &mut br)?;
454 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
455 frm.set_keyframe(self.dec.is_intra());
456 frm.set_frame_type(self.dec.get_frame_type());
457 Ok(frm.into_ref())
458 }
459 fn flush(&mut self) {
460 self.dec.flush();
461 }
462 }
463
464 impl NAOptionHandler for Indeo4Decoder {
465 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
466 fn set_options(&mut self, _options: &[NAOption]) { }
467 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
468 }
469
470 const INDEO4_PICTURE_SIZE_TAB: [[usize; 2]; 7] = [
471 [640, 480], [320, 240], [160, 120], [704, 480], [352, 240], [352, 288], [176, 144]
472 ];
473
474 const INDEO4_SLICE_SIZE_TAB: [usize; 15] = [
475 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480
476 ];
477
478 const INDEO4_FRAME_TYPE: [IVIFrameType; 7] = [
479 IVIFrameType::Intra, IVIFrameType::Intra1, IVIFrameType::Inter, IVIFrameType::Bidir,
480 IVIFrameType::InterDroppable, IVIFrameType::NULL, IVIFrameType::NULL2
481 ];
482
483 const INDEO4_TRANSFORMS: [IVITransformType; 18] = [
484 IVITransformType::Haar(TSize::T8x8, TDir::TwoD),
485 IVITransformType::Haar(TSize::T8x8, TDir::Row),
486 IVITransformType::Haar(TSize::T8x8, TDir::Col),
487 IVITransformType::None(TSize::T8x8),
488 IVITransformType::Slant(TSize::T8x8, TDir::TwoD),
489 IVITransformType::Slant(TSize::T8x8, TDir::Row),
490 IVITransformType::Slant(TSize::T8x8, TDir::Col),
491 IVITransformType::DCT(TSize::T8x8, TDir::TwoD),
492 IVITransformType::DCT(TSize::T8x8, TDir::Row),
493 IVITransformType::DCT(TSize::T8x8, TDir::Col),
494 IVITransformType::Haar(TSize::T4x4, TDir::TwoD),
495 IVITransformType::Slant(TSize::T4x4, TDir::TwoD),
496 IVITransformType::None(TSize::T4x4),
497 IVITransformType::Haar(TSize::T4x4, TDir::Row),
498 IVITransformType::Haar(TSize::T4x4, TDir::Col),
499 IVITransformType::Slant(TSize::T4x4, TDir::Row),
500 IVITransformType::Slant(TSize::T4x4, TDir::Col),
501 IVITransformType::DCT(TSize::T4x4, TDir::TwoD),
502 ];
503
504 const INDEO4_SCAN_8X8_ALT: [usize; 64] = [
505 0, 8, 1, 9, 16, 24, 2, 3,
506 17, 25, 10, 11, 32, 40, 48, 56,
507 4, 5, 6, 7, 33, 41, 49, 57,
508 18, 19, 26, 27, 12, 13, 14, 15,
509 34, 35, 43, 42, 50, 51, 59, 58,
510 20, 21, 22, 23, 31, 30, 29, 28,
511 36, 37, 38, 39, 47, 46, 45, 44,
512 52, 53, 54, 55, 63, 62, 61, 60
513 ];
514 const INDEO4_SCAN_4X4_ALT: [usize; 16] = [ 0, 1, 4, 5, 8, 12, 2, 3, 9, 13, 6, 7, 10, 11, 14, 15 ];
515 const INDEO4_SCAN_4X4_VER: [usize; 16] = [ 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 ];
516 const INDEO4_SCAN_4X4_HOR: [usize; 16] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ];
517
518 const INDEO4_SCANS_8X8: [&[usize; 64]; 5] = [
519 &ZIGZAG, &INDEO4_SCAN_8X8_ALT, &IVI_SCAN_8X8_HOR, &IVI_SCAN_8X8_VER, &ZIGZAG
520 ];
521 const INDEO4_SCANS_4X4: [&[usize; 16]; 5] = [
522 &IVI_SCAN_4X4, &INDEO4_SCAN_4X4_ALT, &INDEO4_SCAN_4X4_VER, &INDEO4_SCAN_4X4_HOR, &IVI_SCAN_4X4
523 ];
524
525 const INDEO4_Q8X8_IDX: [usize; 15] = [ 0, 1, 0, 2, 1, 3, 0, 4, 1, 5, 0, 1, 6, 7, 8 ];
526 const INDEO4_Q4X4_IDX: [usize; 7] = [ 0, 1, 2, 2, 3, 3, 4 ];
527
528 const INDEO4_QUANT8X8_INTRA: [[u16; 64]; 9] = [
529 [
530 43, 342, 385, 470, 555, 555, 598, 726,
531 342, 342, 470, 513, 555, 598, 726, 769,
532 385, 470, 555, 555, 598, 726, 726, 811,
533 470, 470, 555, 555, 598, 726, 769, 854,
534 470, 555, 555, 598, 683, 726, 854, 1025,
535 555, 555, 598, 683, 726, 854, 1025, 1153,
536 555, 555, 598, 726, 811, 982, 1195, 1451,
537 555, 598, 726, 811, 982, 1195, 1451, 1793
538 ], [
539 86, 1195, 2390, 2390, 4865, 4865, 4865, 4865,
540 1195, 1195, 2390, 2390, 4865, 4865, 4865, 4865,
541 2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827,
542 2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827,
543 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
544 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
545 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
546 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827
547 ], [
548 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
549 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
550 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
551 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
552 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
553 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
554 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
555 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835
556 ], [
557 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
558 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
559 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
560 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
561 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
562 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
563 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
564 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414
565 ], [
566 897, 897, 897, 897, 897, 897, 897, 897,
567 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067,
568 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
569 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409,
570 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579,
571 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750,
572 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921,
573 2091, 2091, 2091, 2091, 2091, 2091, 2091, 2091
574 ], [
575 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
576 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
577 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
578 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
579 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
580 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
581 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
582 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414
583 ], [
584 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
585 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
586 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
587 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
588 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
589 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
590 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
591 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390
592 ], [
593 22, 171, 214, 257, 257, 299, 299, 342,
594 171, 171, 257, 257, 299, 299, 342, 385,
595 214, 257, 257, 299, 299, 342, 342, 385,
596 257, 257, 257, 299, 299, 342, 385, 427,
597 257, 257, 299, 299, 342, 385, 427, 513,
598 257, 299, 299, 342, 385, 427, 513, 598,
599 299, 299, 299, 385, 385, 470, 598, 726,
600 299, 299, 385, 385, 470, 598, 726, 897
601 ], [
602 86, 598, 1195, 1195, 2390, 2390, 2390, 2390,
603 598, 598, 1195, 1195, 2390, 2390, 2390, 2390,
604 1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414,
605 1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414,
606 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
607 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
608 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
609 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414
610 ]
611 ];
612 const INDEO4_QUANT8X8_INTER: [[u16; 64]; 9] = [
613 [
614 427, 427, 470, 427, 427, 427, 470, 470,
615 427, 427, 470, 427, 427, 427, 470, 470,
616 470, 470, 470, 470, 470, 470, 470, 470,
617 427, 427, 470, 470, 427, 427, 470, 470,
618 427, 427, 470, 427, 427, 427, 470, 470,
619 427, 427, 470, 427, 427, 427, 470, 470,
620 470, 470, 470, 470, 470, 470, 470, 470,
621 470, 470, 470, 470, 470, 470, 470, 470
622 ], [
623 1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414,
624 1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414,
625 2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822,
626 2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822,
627 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
628 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
629 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
630 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414
631 ], [
632 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
633 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
634 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
635 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
636 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
637 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
638 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
639 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281
640 ], [
641 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
642 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
643 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
644 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
645 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
646 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
647 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
648 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433
649 ], [
650 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
651 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
652 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
653 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
654 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
655 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
656 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
657 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281
658 ], [
659 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
660 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
661 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
662 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
663 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
664 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
665 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
666 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433
667 ], [
668 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
669 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
670 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
671 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
672 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
673 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
674 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
675 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707
676 ], [
677 86, 171, 171, 214, 214, 214, 214, 257,
678 171, 171, 214, 214, 214, 214, 257, 257,
679 171, 214, 214, 214, 214, 257, 257, 257,
680 214, 214, 214, 214, 257, 257, 257, 299,
681 214, 214, 214, 257, 257, 257, 299, 299,
682 214, 214, 257, 257, 257, 299, 299, 299,
683 214, 257, 257, 257, 299, 299, 299, 342,
684 257, 257, 257, 299, 299, 299, 342, 342
685 ], [
686 854, 854, 1195, 1195, 1707, 1707, 1707, 1707,
687 854, 854, 1195, 1195, 1707, 1707, 1707, 1707,
688 1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390,
689 1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390,
690 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
691 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
692 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
693 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707
694 ]
695 ];
696 const INDEO4_QUANT4X4_INTRA: [[u16; 16]; 5] = [
697 [
698 22, 214, 257, 299,
699 214, 257, 299, 342,
700 257, 299, 342, 427,
701 299, 342, 427, 513
702 ], [
703 129, 1025, 1451, 1451,
704 1025, 1025, 1451, 1451,
705 1451, 1451, 2049, 2049,
706 1451, 1451, 2049, 2049
707 ], [
708 43, 171, 171, 171,
709 43, 171, 171, 171,
710 43, 171, 171, 171,
711 43, 171, 171, 171
712 ], [
713 43, 43, 43, 43,
714 171, 171, 171, 171,
715 171, 171, 171, 171,
716 171, 171, 171, 171
717 ], [
718 43, 43, 43, 43,
719 43, 43, 43, 43,
720 43, 43, 43, 43,
721 43, 43, 43, 43
722 ]
723 ];
724 const INDEO4_QUANT4X4_INTER: [[u16; 16]; 5] = [
725 [
726 107, 214, 257, 299,
727 214, 257, 299, 299,
728 257, 299, 299, 342,
729 299, 299, 342, 342
730 ], [
731 513, 1025, 1238, 1238,
732 1025, 1025, 1238, 1238,
733 1238, 1238, 1451, 1451,
734 1238, 1238, 1451, 1451
735 ], [
736 43, 171, 171, 171,
737 43, 171, 171, 171,
738 43, 171, 171, 171,
739 43, 171, 171, 171
740 ], [
741 43, 43, 43, 43,
742 171, 171, 171, 171,
743 171, 171, 171, 171,
744 171, 171, 171, 171
745 ], [
746 43, 43, 43, 43,
747 43, 43, 43, 43,
748 43, 43, 43, 43,
749 43, 43, 43, 43
750 ]
751 ];
752 const INDEO4_Q8_INTRA: [&[u16; 64]; 9] = [
753 &INDEO4_QUANT8X8_INTRA[0], &INDEO4_QUANT8X8_INTRA[1], &INDEO4_QUANT8X8_INTRA[2],
754 &INDEO4_QUANT8X8_INTRA[3], &INDEO4_QUANT8X8_INTRA[4], &INDEO4_QUANT8X8_INTRA[5],
755 &INDEO4_QUANT8X8_INTRA[6], &INDEO4_QUANT8X8_INTRA[7], &INDEO4_QUANT8X8_INTRA[8],
756 ];
757 const INDEO4_Q8_INTER: [&[u16; 64]; 9] = [
758 &INDEO4_QUANT8X8_INTER[0], &INDEO4_QUANT8X8_INTER[1], &INDEO4_QUANT8X8_INTER[2],
759 &INDEO4_QUANT8X8_INTER[3], &INDEO4_QUANT8X8_INTER[4], &INDEO4_QUANT8X8_INTER[5],
760 &INDEO4_QUANT8X8_INTER[6], &INDEO4_QUANT8X8_INTER[7], &INDEO4_QUANT8X8_INTER[8],
761 ];
762 const INDEO4_Q4_INTRA: [&[u16; 16]; 5] = [
763 &INDEO4_QUANT4X4_INTRA[0], &INDEO4_QUANT4X4_INTRA[1], &INDEO4_QUANT4X4_INTRA[2],
764 &INDEO4_QUANT4X4_INTRA[3], &INDEO4_QUANT4X4_INTRA[4]
765 ];
766 const INDEO4_Q4_INTER: [&[u16; 16]; 5] = [
767 &INDEO4_QUANT4X4_INTER[0], &INDEO4_QUANT4X4_INTER[1], &INDEO4_QUANT4X4_INTER[2],
768 &INDEO4_QUANT4X4_INTER[3], &INDEO4_QUANT4X4_INTER[4]
769 ];
770
771 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
772 Box::new(Indeo4Decoder::new())
773 }
774
775 #[cfg(test)]
776 mod test {
777 use nihav_core::codecs::RegisteredDecoders;
778 use nihav_core::demuxers::RegisteredDemuxers;
779 use nihav_codec_support::test::dec_video::*;
780 use crate::indeo_register_all_decoders;
781 use nihav_commonfmt::generic_register_all_demuxers;
782 #[test]
783 fn test_indeo4() {
784 let mut dmx_reg = RegisteredDemuxers::new();
785 generic_register_all_demuxers(&mut dmx_reg);
786 let mut dec_reg = RegisteredDecoders::new();
787 indeo_register_all_decoders(&mut dec_reg);
788
789 test_decoding("avi", "indeo4", "assets/Indeo/IV4/volcano.avi", Some(16),
790 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
791 [0x194f626b, 0x023fdfd0, 0x9809665a, 0xd68f6f47],
792 [0x194f626b, 0x023fdfd0, 0x9809665a, 0xd68f6f47],
793 [0x194f626b, 0x023fdfd0, 0x9809665a, 0xd68f6f47],
794 [0x194f626b, 0x023fdfd0, 0x9809665a, 0xd68f6f47],
795 [0x46c6719d, 0xe6415ac0, 0x3e4d9799, 0xd2f5747d],
796 [0xe0278b0f, 0x3e4763d5, 0x88033344, 0xc9c2e6de],
797 [0xd962be7f, 0xafc1ac64, 0x0647cdcc, 0xd06465c6],
798 [0xedef0e19, 0xec75eed2, 0x955a2ae2, 0xd6145b4c],
799 [0x89ec8d4b, 0x3d446d74, 0xbd3d681d, 0x2d219dca],
800 [0x89e81643, 0x77fb2f1b, 0x2aa0782f, 0xb1b9b7ef],
801 [0xea283aec, 0x94d7cdf9, 0x961bbb69, 0x2b38162a],
802 [0x1d1b315c, 0x6613c5fa, 0xeff36485, 0x5025fbf2],
803 [0x4145c6a8, 0xd8d513b1, 0x34a5d353, 0x07750cd5],
804 [0xace12feb, 0x468754f3, 0xa72327f5, 0x1a6f6350],
805 [0x4b04dc0e, 0x684533a7, 0x6a4e4b16, 0x0b8a5e68],
806 [0xa3eb64fc, 0x5e02a31b, 0x6b484eae, 0xbb6e6c49],
807 [0x7d4ef46e, 0x6761c447, 0x02e002f5, 0x02d0231c]]));
808 test_decoding("avi", "indeo4", "assets/Indeo/IV4/HRLDVIK.AVI", Some(8),
809 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
810 [0x239b8b87, 0x6dbec08c, 0x82bae1f0, 0x868e00c2],
811 [0xe2298beb, 0x4e08866d, 0x00cb6201, 0x6b0a6df3],
812 [0x9d7f4cf0, 0xed33df12, 0x2677be16, 0xce7e99b0],
813 [0x0c8d7489, 0x2b3ac56e, 0x36d75559, 0x70550903],
814 [0xc32b4b78, 0x2fc81737, 0xe4d7722b, 0xbcbbb35e],
815 [0x20bfd5e8, 0x6cfad540, 0xfc6c6b6c, 0xa4f39a7d],
816 [0xc327428d, 0x4e817b56, 0x4376eba2, 0xebafd04a],
817 [0x6a53a6ec, 0x7477a471, 0xd55bc98e, 0x7498de0f],
818 [0x398eba3a, 0x3cf3cce1, 0x90211dfe, 0x82c906f0]]));
819 }
820 }