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