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