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