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