make all codec crates export just register_all functions and document them
[nihav.git] / nihav-indeo / src / codecs / indeo5.rs
1 use nihav_core::io::bitreader::*;
2 use nihav_core::formats;
3 use nihav_core::frame::*;
4 use nihav_core::codecs::*;
5 use super::ivi::*;
6 use super::ivibr::*;
7
8 fn calc_quant(glob_q: u32, qd: i16) -> usize {
9 let qq = (glob_q as i16) + (qd as i16);
10 if qq < 0 {
11 0
12 } else if qq > 23 {
13 23
14 } else {
15 qq as usize
16 }
17 }
18
19 struct Indeo5Parser {
20 mb_cb: IVICodebook,
21
22 width: usize,
23 height: usize,
24 tile_w: usize,
25 tile_h: usize,
26 luma_bands: usize,
27 chroma_bands: usize,
28
29 is_hpel: [bool; 5],
30 mb_size: [usize; 5],
31 blk_size: [usize; 5],
32 }
33
34 impl Indeo5Parser {
35 fn new() -> Self {
36 Indeo5Parser {
37 mb_cb: IVI_CB_ZERO,
38
39 width: 0,
40 height: 0,
41 tile_w: 0,
42 tile_h: 0,
43 luma_bands: 0,
44 chroma_bands: 0,
45
46 is_hpel: [false; 5],
47 mb_size: [0; 5],
48 blk_size: [0; 5],
49 }
50 }
51 }
52
53 fn skip_extension(br: &mut BitReader) -> DecoderResult<()> {
54 loop {
55 let len = br.read(8)?;
56 if len == 0 { break; }
57 br.skip(len * 8)?;
58 }
59 Ok(())
60 }
61
62 impl IndeoXParser for Indeo5Parser {
63 #[allow(unused_variables)]
64 #[allow(unused_assignments)]
65 fn decode_picture_header(&mut self, br: &mut BitReader) -> DecoderResult<PictureHeader> {
66 let sync = br.read(5)?;
67 validate!(sync == 0x1F);
68 let ftype_idx = br.read(3)?;
69 validate!(ftype_idx < 5);
70 let ftype = INDEO5_FRAME_TYPE[ftype_idx as usize];
71 let fnum = br.read(8)?;
72 if ftype == IVIFrameType::Intra {
73 let gop_flags = br.read(8)?;
74 let hdr_size;
75 if (gop_flags & 0x01) != 0 {
76 hdr_size = br.read(16)?;
77 } else {
78 hdr_size = 0;
79 }
80 if (gop_flags & 0x20) != 0 {
81 br.skip(32)?; // lock word
82 }
83 self.tile_w = 0;
84 self.tile_h = 0;
85 if (gop_flags & 0x40) != 0 {
86 self.tile_w = 64 << br.read(2)?;
87 self.tile_h = self.tile_w;
88 }
89 validate!(self.tile_w < 256);
90 self.luma_bands = (br.read(2)? * 3 + 1) as usize;
91 self.chroma_bands = (br.read(1)? * 3 + 1) as usize;
92 validate!((self.luma_bands == 4) || (self.luma_bands == 1));
93 validate!(self.chroma_bands == 1);
94 let pic_size_idx = br.read(4)? as usize;
95 let w;
96 let h;
97 if pic_size_idx < 15 {
98 w = INDEO5_PICTURE_SIZE_TAB[pic_size_idx][0];
99 h = INDEO5_PICTURE_SIZE_TAB[pic_size_idx][1];
100 } else {
101 h = br.read(13)? as usize;
102 w = br.read(13)? as usize;
103 }
104 validate!((w != 0) && (h != 0));
105 self.width = w;
106 self.height = h;
107
108 validate!((gop_flags & 0x02) == 0);
109 if self.tile_w == 0 {
110 self.tile_w = w;
111 self.tile_h = h;
112 }
113 for b in 0..self.luma_bands+self.chroma_bands {
114 self.is_hpel[b] = br.read_bool()?;
115 let mb_scale = br.read(1)?;
116 self.blk_size[b] = 8 >> br.read(1)?;
117 self.mb_size[b] = self.blk_size[b] << (1 - mb_scale);
118 let ext_tr = br.read_bool()?;
119 validate!(!ext_tr);
120 let end_marker = br.read(2)?;
121 validate!(end_marker == 0);
122 }
123 if (gop_flags & 0x08) != 0 {
124 let align = br.read(3)?;
125 validate!(align == 0);
126 if br.read_bool()? {
127 br.skip(24)?; // transparency color
128 }
129 }
130 br.align();
131 br.skip(23)?;
132 if br.read_bool()? { // gop extension
133 loop {
134 let v = br.read(16)?;
135 if (v & 0x8000) == 0 { break; }
136 }
137 }
138 br.align();
139 }
140 if ftype.is_null() {
141 br.align();
142 return Ok(PictureHeader::new_null(ftype));
143 }
144 let flags = br.read(8)?;
145 let size;
146 if (flags & 0x01) != 0 {
147 size = br.read(24)?;
148 } else {
149 size = 0;
150 }
151 let checksum;
152 if (flags & 0x10) != 0 {
153 checksum = br.read(16)?;
154 } else {
155 checksum = 0;
156 }
157 if (flags & 0x20) != 0 {
158 skip_extension(br)?;
159 }
160 let in_q = (flags & 0x08) != 0;
161 self.mb_cb = br.read_ivi_codebook_desc(true, (flags & 0x40) != 0)?;
162 br.skip(3)?;
163 br.align();
164
165 Ok(PictureHeader::new(ftype, self.width, self.height, self.tile_w, self.tile_h, false, self.luma_bands, self.chroma_bands, in_q))
166 }
167
168 #[allow(unused_variables)]
169 fn decode_band_header(&mut self, br: &mut BitReader, pic_hdr: &PictureHeader, plane_no: usize, band_no: usize) -> DecoderResult<BandHeader> {
170 let band_flags = br.read(8)?;
171
172 if (band_flags & 0x01) != 0 {
173 br.align();
174 return Ok(BandHeader::new_empty(plane_no, band_no));
175 }
176 let inherit_mv = (band_flags & 0x02) != 0;
177 let has_qdelta = (band_flags & 0x04) != 0;
178 let inherit_qd = ((band_flags & 0x08) != 0) || !has_qdelta;
179 let data_size: usize;
180 if (band_flags & 0x80) != 0 {
181 data_size = br.read(24)? as usize;
182 } else {
183 data_size = 0;
184 }
185 validate!(data_size <= ((br.left() / 8) as usize));
186
187 let num_corr: usize;
188 let mut corr_map: [u8; CORR_MAP_SIZE] = [0; CORR_MAP_SIZE];
189 if (band_flags & 0x10) != 0 {
190 num_corr = br.read(8)? as usize;
191 validate!(num_corr*2 <= CORR_MAP_SIZE);
192 for i in 0..num_corr*2 {
193 corr_map[i] = br.read(8)? as u8;
194 }
195 } else {
196 num_corr = 0;
197 }
198 let rvmap_idx;
199 if (band_flags & 0x40) != 0 {
200 rvmap_idx = br.read(3)? as usize;
201 } else {
202 rvmap_idx = 8;
203 }
204 let blk_cb = br.read_ivi_codebook_desc(false, (band_flags & 0x80) != 0)?;
205 if br.read_bool()? {
206 br.skip(16)?; // checksum
207 }
208 let band_q = br.read(5)?;
209 if (band_flags & 0x20) != 0 {
210 skip_extension(br)?;
211 }
212 br.align();
213
214 let tr;
215 let txtype;
216 let band_id = if plane_no == 0 { band_no } else { self.luma_bands };
217 match plane_no {
218 0 => {
219 let scan = INDEO5_SCAN8X8[band_no];
220 let qintra;
221 let qinter;
222 validate!(self.blk_size[band_id] == 8);
223 match band_no {
224 0 => {
225 tr = IVITransformType::Slant(TSize::T8x8, TDir::TwoD);
226 if self.luma_bands == 1 {
227 qintra = INDEO5_Q8_INTRA[0];
228 qinter = INDEO5_Q8_INTER[0];
229 } else {
230 qintra = INDEO5_Q8_INTRA[1];
231 qinter = INDEO5_Q8_INTER[1];
232 }
233 },
234 1 => {
235 tr = IVITransformType::Slant(TSize::T8x8, TDir::Row);
236 qintra = INDEO5_Q8_INTRA[2];
237 qinter = INDEO5_Q8_INTER[2];
238 },
239 2 => {
240 tr = IVITransformType::Slant(TSize::T8x8, TDir::Col);
241 qintra = INDEO5_Q8_INTRA[3];
242 qinter = INDEO5_Q8_INTER[3];
243 },
244 3 => {
245 tr = IVITransformType::None(TSize::T8x8);
246 qintra = INDEO5_Q8_INTRA[4];
247 qinter = INDEO5_Q8_INTER[4];
248 },
249 _ => { unreachable!(); }
250 };
251 txtype = TxType::Transform8(TxParams8x8::new(qintra, qinter, scan));
252 },
253 1 | 2 => {
254 validate!(self.blk_size[band_id] == 4);
255 tr = IVITransformType::Slant(TSize::T4x4, TDir::TwoD);
256 let scan = INDEO5_SCAN4X4;
257 let qintra = INDEO5_Q4_INTRA;
258 let qinter = INDEO5_Q4_INTER;
259 txtype = TxType::Transform4(TxParams4x4::new(qintra, qinter, scan));
260 },
261 _ => { unreachable!(); }
262 };
263
264 Ok(BandHeader::new(plane_no, band_no, self.mb_size[band_id], self.blk_size[band_id], self.is_hpel[band_id], inherit_mv, has_qdelta, inherit_qd, band_q, rvmap_idx, num_corr, corr_map, blk_cb, tr, txtype))
265 }
266
267 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<()> {
268 let mut mv_x = 0;
269 let mut mv_y = 0;
270 let band_id = if pic_hdr.luma_bands == 4 { band.band_no + 1 } else { 0 };
271 let mut mb_idx = 0;
272 for mb_y in 0..tile.mb_h {
273 for mb_x in 0..tile.mb_w {
274 let mut mb = MB::new(tile.pos_x + mb_x * band.mb_size, tile.pos_y + mb_y * band.mb_size);
275 if !br.read_bool()? {
276 if pic_hdr.ftype.is_intra() {
277 mb.mtype = MBType::Intra;
278 } else if band.inherit_mv {
279 if let Some(ref tileref) = ref_tile {
280 mb.mtype = tileref.mb[mb_idx].mtype;
281 } else {
282 return Err(DecoderError::MissingReference);
283 }
284 } else {
285 mb.mtype = if br.read_bool()? { MBType::Inter } else { MBType::Intra };
286 }
287 if band.mb_size == band.blk_size {
288 mb.cbp = br.read(1)? as u8;
289 } else {
290 mb.cbp = br.read(4)? as u8;
291 }
292 let q;
293 if band.has_qdelta {
294 if band.inherit_qd {
295 if let Some(ref tileref) = ref_tile {
296 mb.qd = tileref.mb[mb_idx].qd;
297 q = calc_quant(band.quant, mb.qd);
298 } else {
299 return Err(DecoderError::MissingReference);
300 }
301 } else if (mb.cbp != 0) || ((band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q) {
302 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
303 q = calc_quant(band.quant, mb.qd);
304 } else {
305 q = band.quant as usize;
306 }
307 } else {
308 q = band.quant as usize;
309 }
310
311 if mb.mtype == MBType::Intra {
312 if band.blk_size == 8 {
313 mb.q = INDEO5_QSCALE8_INTRA[band_id][q];
314 } else {
315 mb.q = INDEO5_QSCALE4_INTRA[q];
316 }
317 } else {
318 if band.blk_size == 8 {
319 mb.q = INDEO5_QSCALE8_INTER[band_id][q];
320 } else {
321 mb.q = INDEO5_QSCALE4_INTER[q];
322 }
323 }
324
325 if mb.mtype != MBType::Intra {
326 if band.inherit_mv {
327 if let Some(ref tileref) = ref_tile {
328 let mx = tileref.mb[mb_idx].mv_x;
329 let my = tileref.mb[mb_idx].mv_y;
330 if mv_scale == 0 {
331 mb.mv_x = mx;
332 mb.mv_y = my;
333 } else {
334 mb.mv_x = scale_mv(mx, mv_scale);
335 mb.mv_y = scale_mv(my, mv_scale);
336 }
337 }
338 } else {
339 mv_y += br.read_ivi_cb_s(&self.mb_cb)?;
340 mv_x += br.read_ivi_cb_s(&self.mb_cb)?;
341 mb.mv_x = mv_x;
342 mb.mv_y = mv_y;
343 }
344 }
345 } else {
346 validate!(!pic_hdr.ftype.is_intra());
347 mb.mtype = MBType::Inter;
348 mb.cbp = 0;
349 mb.qd = 0;
350 if (band.plane_no == 0) && (band.band_no == 0) && pic_hdr.in_q {
351 mb.qd = br.read_ivi_cb_s(&self.mb_cb)? as i16;
352 let q = calc_quant(band.quant, mb.qd);
353 if mb.mtype == MBType::Intra {
354 if band.blk_size == 8 {
355 mb.q = INDEO5_QSCALE8_INTRA[band_id][q];
356 } else {
357 mb.q = INDEO5_QSCALE4_INTRA[q];
358 }
359 } else {
360 if band.blk_size == 8 {
361 mb.q = INDEO5_QSCALE8_INTER[band_id][q];
362 } else {
363 mb.q = INDEO5_QSCALE4_INTER[q];
364 }
365 }
366 }
367 if band.inherit_mv {
368 if let Some(ref tileref) = ref_tile {
369 let mx = tileref.mb[mb_idx].mv_x;
370 let my = tileref.mb[mb_idx].mv_y;
371 if mv_scale == 0 {
372 mb.mv_x = mx;
373 mb.mv_y = my;
374 } else {
375 mb.mv_x = scale_mv(mx, mv_scale);
376 mb.mv_y = scale_mv(my, mv_scale);
377 }
378 }
379 }
380 }
381 tile.mb[mb_idx] = mb;
382 mb_idx += 1;
383 }
384 }
385 br.align();
386 Ok(())
387 }
388
389 fn recombine_plane(&mut self, src: &[i16], sstride: usize, dst: &mut [u8], dstride: usize, w: usize, h: usize) {
390 let mut idx0 = 0;
391 let mut idx1 = w / 2;
392 let mut idx2 = (h / 2) * sstride;
393 let mut idx3 = idx2 + idx1;
394 let mut bidx1 = idx1;
395 let mut bidx3 = idx3;
396 let mut oidx0 = 0;
397 let mut oidx1 = dstride;
398 let filt_lo = |a: i16, b: i16| a + b;
399 let filt_hi = |a: i16, b: i16, c: i16| a - b * 6 + c;
400
401 for _ in 0..(h/2) {
402 let mut b0_1 = src[idx0];
403 let mut b0_2 = src[idx0 + sstride];
404 let mut b1_1 = src[bidx1];
405 let mut b1_2 = src[idx1];
406 let mut b1_3 = filt_hi(b1_1, b1_2, src[idx1 + sstride]);
407 let mut b2_1;
408 let mut b2_2 = src[idx2];
409 let mut b2_3 = b2_2;
410 let mut b2_4;
411 let mut b2_5 = src[idx2 + sstride];
412 let mut b2_6 = b2_5;
413 let mut b3_1;
414 let mut b3_2 = src[bidx3];
415 let mut b3_3 = b3_2;
416 let mut b3_4;
417 let mut b3_5 = src[idx3];
418 let mut b3_6 = b3_5;
419 let mut b3_8 = filt_hi(b3_2, b3_5, src[idx3 + sstride]);
420 let mut b3_9 = b3_8;
421 let mut b3_7;
422
423 for x in 0..(w/2) {
424 b2_1 = b2_2;
425 b2_2 = b2_3;
426 b2_4 = b2_5;
427 b2_5 = b2_6;
428 b3_1 = b3_2;
429 b3_2 = b3_3;
430 b3_4 = b3_5;
431 b3_5 = b3_6;
432 b3_7 = b3_8;
433 b3_8 = b3_9;
434
435 let tmp0 = b0_1;
436 let tmp1 = b0_2;
437 b0_1 = src[idx0 + x + 1];
438 b0_2 = src[idx0 + x + 1 + sstride];
439 let mut p0 = tmp0 << 4;
440 let mut p1 = (tmp0 + b0_1) << 3;
441 let mut p2 = (tmp0 + tmp1) << 3;
442 let mut p3 = (tmp0 + tmp1 + b0_1 + b0_2) << 2;
443
444 let tmp0 = b1_1;
445 let tmp1 = b1_2;
446 let tmp2 = filt_lo(tmp0, tmp1);
447 let tmp3 = filt_hi(tmp0, tmp1, b1_3);
448 b1_2 = src[ idx1 + x + 1];
449 b1_1 = src[bidx1 + x + 1];
450 b1_3 = filt_hi(b1_1, b1_2, src[idx1 + x + 1 + sstride]);
451 p0 += tmp2 << 3;
452 p1 += (tmp2 + b1_1 + b1_2) << 2;
453 p2 += tmp3 << 2;
454 p3 += (tmp3 + b1_3) << 1;
455
456 b2_3 = src[idx2 + x + 1];
457 b2_6 = src[idx2 + x + 1 + sstride];
458 let tmp0 = filt_lo(b2_1, b2_2);
459 let tmp1 = filt_hi(b2_1, b2_2, b2_3);
460 p0 += tmp0 << 3;
461 p1 += tmp1 << 2;
462 p2 += (tmp0 + filt_lo(b2_4, b2_5)) << 2;
463 p3 += (tmp1 + filt_hi(b2_4, b2_5, b2_6)) << 1;
464
465 b3_6 = src[idx3 + x + 1];
466 b3_3 = src[bidx3 + x + 1];
467 b3_9 = filt_hi(b3_3, b3_6, src[idx3 + x + 1 + sstride]);
468 let tmp0 = b3_1 + b3_4;
469 let tmp1 = b3_2 + b3_5;
470 let tmp2 = b3_3 + b3_6;
471 p0 += filt_lo(tmp0, tmp1) << 2;
472 p1 += filt_hi(tmp0, tmp1, tmp2) << 1;
473 p2 += filt_lo(b3_7, b3_8) << 1;
474 p3 += filt_hi(b3_7, b3_8, b3_9) << 0;
475
476 dst[oidx0 + x * 2 + 0] = clip8((p0 >> 6) + 128);
477 dst[oidx0 + x * 2 + 1] = clip8((p1 >> 6) + 128);
478 dst[oidx1 + x * 2 + 0] = clip8((p2 >> 6) + 128);
479 dst[oidx1 + x * 2 + 1] = clip8((p3 >> 6) + 128);
480 }
481 bidx1 = idx1;
482 bidx3 = idx3;
483 idx0 += sstride;
484 idx1 += sstride;
485 idx2 += sstride;
486 idx3 += sstride;
487 oidx0 += dstride * 2;
488 oidx1 += dstride * 2;
489 }
490 }
491 }
492
493 struct Indeo5Decoder {
494 info: NACodecInfoRef,
495 dec: IVIDecoder,
496 ip: Indeo5Parser,
497 }
498
499 impl Indeo5Decoder {
500 fn new() -> Self {
501 Indeo5Decoder {
502 info: NACodecInfo::new_dummy(),
503 dec: IVIDecoder::new(),
504 ip: Indeo5Parser::new(),
505 }
506 }
507 }
508
509 impl NADecoder for Indeo5Decoder {
510 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
511 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
512 let w = vinfo.get_width();
513 let h = vinfo.get_height();
514 let f = vinfo.is_flipped();
515 let fmt = formats::YUV410_FORMAT;
516 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, f, fmt));
517 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
518 Ok(())
519 } else {
520 Err(DecoderError::InvalidData)
521 }
522 }
523 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
524 let src = pkt.get_buffer();
525 let mut br = BitReader::new(src.as_slice(), BitReaderMode::LE);
526
527 let bufinfo = self.dec.decode_frame(&mut self.ip, &mut br)?;
528 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
529 frm.set_keyframe(self.dec.is_intra());
530 frm.set_frame_type(self.dec.get_frame_type());
531 Ok(frm.into_ref())
532 }
533 fn flush(&mut self) {
534 self.dec.flush();
535 }
536 }
537
538 const INDEO5_PICTURE_SIZE_TAB: [[usize; 2]; 15] = [
539 [640, 480], [320, 240], [160, 120], [704, 480], [352, 240], [352, 288], [176, 144],
540 [240, 180], [640, 240], [704, 240], [80, 60], [88, 72], [0, 0], [0, 0], [0, 0]
541 ];
542
543 const INDEO5_FRAME_TYPE: [IVIFrameType; 5] = [
544 IVIFrameType::Intra, IVIFrameType::Inter, IVIFrameType::InterScal,
545 IVIFrameType::InterDroppable, IVIFrameType::NULL,
546 ];
547
548 const INDEO5_QUANT8X8_INTRA: [[u16; 64]; 5] = [
549 [
550 0x1a, 0x2e, 0x36, 0x42, 0x46, 0x4a, 0x4e, 0x5a,
551 0x2e, 0x32, 0x3e, 0x42, 0x46, 0x4e, 0x56, 0x6a,
552 0x36, 0x3e, 0x3e, 0x44, 0x4a, 0x54, 0x66, 0x72,
553 0x42, 0x42, 0x44, 0x4a, 0x52, 0x62, 0x6c, 0x7a,
554 0x46, 0x46, 0x4a, 0x52, 0x5e, 0x66, 0x72, 0x8e,
555 0x4a, 0x4e, 0x54, 0x62, 0x66, 0x6e, 0x86, 0xa6,
556 0x4e, 0x56, 0x66, 0x6c, 0x72, 0x86, 0x9a, 0xca,
557 0x5a, 0x6a, 0x72, 0x7a, 0x8e, 0xa6, 0xca, 0xfe,
558 ], [
559 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
560 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
561 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
562 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
563 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
564 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
565 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
566 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
567 ], [
568 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
569 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
570 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
571 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
572 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
573 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
574 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
575 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
576 ], [
577 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
578 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
579 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
580 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
581 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
582 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
583 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
584 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
585 ], [
586 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
587 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
588 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
589 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
590 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
591 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
592 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
593 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
594 ]
595 ];
596 const INDEO5_QUANT8X8_INTER: [[u16; 64]; 5] = [
597 [
598 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
599 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
600 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
601 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
602 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
603 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
604 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
605 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
606 ], [
607 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
608 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
609 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
610 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
611 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
612 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
613 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
614 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
615 ], [
616 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
617 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
618 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
619 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
620 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
621 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
622 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
623 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
624 ], [
625 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
626 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
627 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
628 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
629 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
630 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
631 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
632 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
633 ], [
634 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
635 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
636 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
637 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
638 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
639 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
640 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
641 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
642 ]
643 ];
644 const INDEO5_QUANT4X4_INTRA: [u16; 16] = [
645 0x1e, 0x3e, 0x4a, 0x52,
646 0x3e, 0x4a, 0x52, 0x5e,
647 0x4a, 0x52, 0x5e, 0x7a,
648 0x52, 0x5e, 0x7a, 0x92
649 ];
650 const INDEO5_QUANT4X4_INTER: [u16; 16] = [
651 0x1e, 0x3e, 0x4a, 0x52,
652 0x3e, 0x4a, 0x52, 0x56,
653 0x4a, 0x52, 0x56, 0x5e,
654 0x52, 0x56, 0x5e, 0x66
655 ];
656 const INDEO5_Q8_INTRA: [&[u16; 64]; 5] = [
657 &INDEO5_QUANT8X8_INTRA[0], &INDEO5_QUANT8X8_INTRA[1], &INDEO5_QUANT8X8_INTRA[2],
658 &INDEO5_QUANT8X8_INTRA[3], &INDEO5_QUANT8X8_INTRA[4],
659 ];
660 const INDEO5_Q8_INTER: [&[u16; 64]; 5] = [
661 &INDEO5_QUANT8X8_INTER[0], &INDEO5_QUANT8X8_INTER[1], &INDEO5_QUANT8X8_INTER[2],
662 &INDEO5_QUANT8X8_INTER[3], &INDEO5_QUANT8X8_INTER[4],
663 ];
664 const INDEO5_Q4_INTRA: &[u16; 16] = &INDEO5_QUANT4X4_INTRA;
665 const INDEO5_Q4_INTER: &[u16; 16] = &INDEO5_QUANT4X4_INTER;
666
667 const INDEO5_SCAN8X8: [&[usize; 64]; 4] = [
668 &ZIGZAG, &IVI_SCAN_8X8_VER, &IVI_SCAN_8X8_HOR, &IVI_SCAN_8X8_HOR
669 ];
670 const INDEO5_SCAN4X4: &[usize; 16] = &IVI_SCAN_4X4;
671
672 const INDEO5_QSCALE8_INTRA: [[u8; 24]; 5] = [
673 [
674 0x0b, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
675 0x22, 0x24, 0x27, 0x28, 0x2a, 0x2d, 0x2f, 0x31, 0x34, 0x37, 0x39, 0x3c,
676 ], [
677 0x01, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x28, 0x2c,
678 0x30, 0x34, 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x52, 0x58, 0x5e, 0x65, 0x6c,
679 ], [
680 0x13, 0x22, 0x27, 0x2a, 0x2d, 0x33, 0x36, 0x3c, 0x41, 0x45, 0x49, 0x4e,
681 0x53, 0x58, 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x7c, 0x82, 0x88, 0x8e, 0x95,
682 ], [
683 0x13, 0x1f, 0x21, 0x24, 0x27, 0x29, 0x2d, 0x2f, 0x34, 0x37, 0x3a, 0x3d,
684 0x40, 0x44, 0x48, 0x4c, 0x4f, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6b,
685 ], [
686 0x31, 0x42, 0x47, 0x47, 0x4d, 0x52, 0x58, 0x58, 0x5d, 0x63, 0x67, 0x6b,
687 0x6f, 0x73, 0x78, 0x7c, 0x80, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa4,
688 ]
689 ];
690 const INDEO5_QSCALE8_INTER: [[u8; 24]; 5] = [
691 [
692 0x0b, 0x11, 0x13, 0x14, 0x15, 0x16, 0x18, 0x1a, 0x1b, 0x1d, 0x20, 0x22,
693 0x23, 0x25, 0x28, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x41, 0x44, 0x4a,
694 ], [
695 0x07, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
696 0x3a, 0x3f, 0x44, 0x4a, 0x50, 0x56, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x7e,
697 ], [
698 0x15, 0x25, 0x28, 0x2d, 0x30, 0x34, 0x3a, 0x3d, 0x42, 0x48, 0x4c, 0x51,
699 0x56, 0x5b, 0x60, 0x65, 0x6b, 0x70, 0x76, 0x7c, 0x82, 0x88, 0x8f, 0x97,
700 ], [
701 0x13, 0x1f, 0x20, 0x22, 0x25, 0x28, 0x2b, 0x2d, 0x30, 0x33, 0x36, 0x39,
702 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4b, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62,
703 ], [
704 0x3c, 0x52, 0x58, 0x5d, 0x63, 0x68, 0x68, 0x6d, 0x73, 0x78, 0x7c, 0x80,
705 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa3, 0xa9, 0xad, 0xb1, 0xb5, 0xba
706 ]
707 ];
708 const INDEO5_QSCALE4_INTRA: [u8; 24] = [
709 0x01, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14,
710 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
711 ];
712 const INDEO5_QSCALE4_INTER: [u8; 24] = [
713 0x0b, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
714 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
715 ];
716
717 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
718 Box::new(Indeo5Decoder::new())
719 }
720
721 #[cfg(test)]
722 mod test {
723 use nihav_core::codecs::RegisteredDecoders;
724 use nihav_core::demuxers::RegisteredDemuxers;
725 use nihav_core::test::dec_video::*;
726 use crate::indeo_register_all_codecs;
727 use nihav_commonfmt::generic_register_all_demuxers;
728 #[test]
729 fn test_indeo5() {
730 let mut dmx_reg = RegisteredDemuxers::new();
731 generic_register_all_demuxers(&mut dmx_reg);
732 let mut dec_reg = RegisteredDecoders::new();
733 indeo_register_all_codecs(&mut dec_reg);
734
735 test_decoding("avi", "indeo5", "assets/Indeo/IV5/sample.avi", Some(100),
736 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
737 [0xd73ef6e2, 0x099dc18f, 0x46450af9, 0x1b390a48],
738 [0xbe3295d6, 0xf4afd9fd, 0x820d35e8, 0x4b593c9a],
739 [0x415e5aed, 0x33afb9a2, 0x14ae9308, 0x53e906d3],
740 [0x7fa94dd3, 0x58582fc3, 0xe39977bc, 0xd88036d5],
741 [0x8eef68f7, 0xace88c0c, 0x3f6e4388, 0xfcd82f46],
742 [0xfe22fcc6, 0x8c4666ab, 0xd9888786, 0x7d9adbc8],
743 [0x37f8b6bc, 0xaea9e94a, 0x05a98f2e, 0x2dce51fa],
744 [0x37492cbd, 0x8fd516fa, 0x48a0bcd1, 0x5eb6584f],
745 [0x6f464159, 0xa2af785b, 0xb440493b, 0x86b21911],
746 [0x3a52de08, 0x9f5762b0, 0xe58a6979, 0x0abb295e],
747 [0xe8f56414, 0x36e76d76, 0xd0927365, 0x15dc5327],
748 [0x0fc17e06, 0x8cb6581c, 0x86eb730d, 0x9bedf951],
749 [0x54fb3627, 0xc02bffc6, 0x87748ee5, 0x8b12d57d],
750 [0x8e4fd3a5, 0x3a7b9cd7, 0x0a4ba1a0, 0x48e10237],
751 [0xce87ea8b, 0x1ec40c98, 0x12c9a682, 0x57d02bf0],
752 [0x7024e691, 0x6bc493ba, 0x617a7a91, 0x65997b4c],
753 [0xb8d53b7c, 0x132ffec9, 0x827cf176, 0x68e97292],
754 [0x12ed76a9, 0x11eced60, 0x473a364f, 0x1e197803],
755 [0x6c23ba3a, 0x12e2f7e3, 0x8fc0c2bc, 0x20726bb2],
756 [0x3307e5e6, 0x3e4fa871, 0x55df1d59, 0xbe055301],
757 [0x8198ee6c, 0x82a33414, 0x9fd8c430, 0x1fca7b93],
758 [0x557662c2, 0xeb3226fc, 0x2a125be4, 0xd475ffa9],
759 [0x850c0326, 0x7a0105e5, 0x37799945, 0x927d1237],
760 [0xe770097e, 0xabd460f4, 0x3d9260e0, 0x5a8132e2],
761 [0xdb6644e7, 0xde6986eb, 0x12cc4916, 0x977d2177],
762 [0xd58ced6c, 0x91c0e7b6, 0x8c5926fc, 0x2dbf3117],
763 [0x6e76dd5f, 0x088884f0, 0x8f94451f, 0xc8df4daf],
764 [0x726b2f8f, 0xd44af9ba, 0x1e188962, 0xd37c1a38],
765 [0x84035565, 0xd2370a8c, 0x8ecb4a3f, 0xd6758196],
766 [0xa1e75a16, 0xc9e230ed, 0x23de50f3, 0x2366967a],
767 [0x690a2a91, 0xfa4acef1, 0xd3de6dd0, 0x973031d9],
768 [0xb392e62a, 0x22b0d3f2, 0x0e975a86, 0x14d6dcb3],
769 [0x5e002202, 0xc80e236e, 0x0b484e02, 0x00035f47],
770 [0x4fc0f301, 0x8ec0d33d, 0xe71a12dd, 0xe799731f],
771 [0x278c9096, 0xec7fa833, 0x2094d81f, 0x52e21165],
772 [0xd55238a8, 0xf040101a, 0x1152b6fe, 0x661c9e64],
773 [0x3699d16e, 0x89d9f2d7, 0x9ad59597, 0x7361ee21],
774 [0x1419c93c, 0x91b75784, 0x18f7121d, 0xec2c6b78],
775 [0x07c435da, 0x05f18557, 0xf28ce1e0, 0x43cadcba],
776 [0x2015269d, 0x52cad948, 0xd6485611, 0x06fe33d7],
777 [0x0cea56f3, 0x82c30841, 0x9b2a8cab, 0x8a6f07cb],
778 [0x81f82aa9, 0x233060d5, 0x00f4171e, 0xe14c0c2a],
779 [0x9b2f8b08, 0x7d091eac, 0x09dcb2c3, 0xa7670405],
780 [0x99c97f75, 0xf91c6b12, 0xfbad7705, 0x1c6e6f27],
781 [0xc762b89c, 0xbf44a194, 0xb2a54dc2, 0xae2103e4],
782 [0xba4f52ed, 0xe35aff77, 0x50d8c9d3, 0xeb382d32],
783 [0x9bc9d9a0, 0x7cb4c594, 0xbc1af6f4, 0x1f718229],
784 [0x5f19eea2, 0x6260982e, 0x393fb360, 0x71abe746],
785 [0xd13f2fcc, 0x88a6a714, 0xf4f53d55, 0xf42b11ba],
786 [0x4208b476, 0xaf06ffce, 0x38e59bfe, 0x588567a2],
787 [0xbedfb7b7, 0x8300a39d, 0x964a3c0f, 0x577d52d7],
788 [0x18e5a6f2, 0x7ec85996, 0x27694f30, 0x7717748a],
789 [0xb5e6d70f, 0xc43261bb, 0xd4e6ae7c, 0xcc11f79c],
790 [0xc808cba7, 0xbb042416, 0x2f01ebe1, 0x7d176a38],
791 [0x03353805, 0x4b6e9d66, 0x25933123, 0x4213aaf7],
792 [0x189a6da5, 0x04a4cbe6, 0xea3c9d09, 0x153fdee2],
793 [0x41f8ac6b, 0xb476356b, 0xc70b67d0, 0x28caf359],
794 [0x4514b6a4, 0x788545ff, 0x4ee9139b, 0xa45bedf9],
795 [0x2a39be04, 0xac9921cb, 0x685c1bf9, 0x904bdab2],
796 [0x2c18f3ef, 0x416c0335, 0x0face768, 0x1b9d5cd2],
797 [0x898cd63f, 0x60af727f, 0x6bdf1be6, 0x0df05cfe],
798 [0x8a06787b, 0x7cee2f8b, 0xdc8aac77, 0x2e0e740a],
799 [0x3d340571, 0xbf1c8d4c, 0xddc23f69, 0xd1903942],
800 [0x7d179e85, 0x54048c4d, 0xba047d33, 0x2e9e5edb],
801 [0x65e26600, 0x87c8421d, 0xa77e2c6c, 0x32b4971a],
802 [0x69041052, 0xa4858c7b, 0x904d84f7, 0xb4ad3dcf],
803 [0x3ea0246d, 0x533e752d, 0x1d55798a, 0x30e17e72],
804 [0x4254a700, 0x07365f23, 0x0f9da313, 0xaecd38ce],
805 [0xa5756d9d, 0x79f31387, 0x0ded3654, 0xa7299663],
806 [0x4ef027c9, 0xeebb1383, 0x26a55289, 0x3746969d],
807 [0xdc6acadf, 0x23e1b6e1, 0x07fcdc26, 0x9914b684],
808 [0x52bb8b80, 0x1a5688ae, 0xd429662d, 0x1cc1485d],
809 [0x76b35f59, 0x24b64e5b, 0xbcbeaee7, 0xf568a832],
810 [0x0756d15f, 0x9cc288bf, 0x9f882a3c, 0xfe7c7161],
811 [0x0503113a, 0x95e716ff, 0x304cf65e, 0x490725e8],
812 [0x7db7ba62, 0x08e4e77d, 0xc9db6413, 0xea3f1a39],
813 [0x7cef6d67, 0xc94867e6, 0x5c674de6, 0x5eb74081],
814 [0x7573b799, 0x069d4f03, 0x63b537a1, 0xdfe25db6],
815 [0xc401e705, 0x834828bc, 0xd99da4a1, 0xd0f3bee8],
816 [0x02817844, 0xada6433e, 0x31761e98, 0x901ccf68],
817 [0x8f9432b4, 0x9f860957, 0xcba54c86, 0x8beb8209],
818 [0x6a46e58c, 0x7d299228, 0x5c001d12, 0xd8db2a00],
819 [0x0c12586d, 0x866d8ca9, 0x849bbb17, 0x5af63ea2],
820 [0xe48671b6, 0xc4377063, 0xc4d03c02, 0x621bd894],
821 [0x5f7f82eb, 0xcdb5abf5, 0x325f2d9d, 0x24a5d200],
822 [0xec6b6fe7, 0x347316c4, 0x6241904a, 0x4e2497a5],
823 [0xf661b7fd, 0xa00e2fc7, 0x90e11456, 0x507fef21],
824 [0x77c7addd, 0x67148dce, 0x1cd27059, 0xefbf4abf],
825 [0x11270d9c, 0xb352779d, 0x81f21055, 0xae93a8b6],
826 [0x3d1f0aaf, 0x3b4aa6d8, 0xca1c160c, 0x6fe4f2bd],
827 [0x17c6bec4, 0x54b568cd, 0xd19c78d6, 0x9a3d897a],
828 [0xc4ab4ca6, 0xbf3b2573, 0xb4d837dd, 0x4dfab799],
829 [0x6fd5645d, 0xa34978b2, 0x6696dd1a, 0x665ca09b],
830 [0x87984bb9, 0xd4d3bc30, 0x7f8bb7a8, 0x2d83b303],
831 [0x21fb5d58, 0x1ee47d1a, 0x97200d83, 0x1d596a88],
832 [0x2656f329, 0x497693be, 0xca971ddf, 0x410d4092],
833 [0xd285c512, 0xfc1ed632, 0x63c43ec2, 0xac5766d1],
834 [0x46fb80ee, 0xcfeecdaa, 0x7237a433, 0x5708ff56],
835 [0x4fccd9c8, 0x7b1a4f31, 0x51516a80, 0x27bf3cae],
836 [0xd649d2f5, 0xebadf1f7, 0x6b34e8ce, 0xb87e82f1],
837 [0x6eb0aec6, 0xfbe9cb51, 0x39e695b4, 0xa6e46e70]]));
838 }
839 }