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