]> git.nihav.org Git - nihav.git/blob - nihav-indeo/src/codecs/indeo5.rs
1f770814c4b5fbb18597cfc4207fabfeb71deaa6
[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<Ref<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, 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, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
524 let src = pkt.get_buffer();
525 let mut br = BitReader::new(src.as_slice(), src.len(), 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(Rc::new(RefCell::new(frm)))
532 }
533 }
534
535 const INDEO5_PICTURE_SIZE_TAB: [[usize; 2]; 15] = [
536 [640, 480], [320, 240], [160, 120], [704, 480], [352, 240], [352, 288], [176, 144],
537 [240, 180], [640, 240], [704, 240], [80, 60], [88, 72], [0, 0], [0, 0], [0, 0]
538 ];
539
540 const INDEO5_FRAME_TYPE: [IVIFrameType; 5] = [
541 IVIFrameType::Intra, IVIFrameType::Inter, IVIFrameType::InterScal,
542 IVIFrameType::InterDroppable, IVIFrameType::NULL,
543 ];
544
545 const INDEO5_QUANT8X8_INTRA: [[u16; 64]; 5] = [
546 [
547 0x1a, 0x2e, 0x36, 0x42, 0x46, 0x4a, 0x4e, 0x5a,
548 0x2e, 0x32, 0x3e, 0x42, 0x46, 0x4e, 0x56, 0x6a,
549 0x36, 0x3e, 0x3e, 0x44, 0x4a, 0x54, 0x66, 0x72,
550 0x42, 0x42, 0x44, 0x4a, 0x52, 0x62, 0x6c, 0x7a,
551 0x46, 0x46, 0x4a, 0x52, 0x5e, 0x66, 0x72, 0x8e,
552 0x4a, 0x4e, 0x54, 0x62, 0x66, 0x6e, 0x86, 0xa6,
553 0x4e, 0x56, 0x66, 0x6c, 0x72, 0x86, 0x9a, 0xca,
554 0x5a, 0x6a, 0x72, 0x7a, 0x8e, 0xa6, 0xca, 0xfe,
555 ], [
556 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
557 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
558 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
559 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
560 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
561 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
562 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
563 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
564 ], [
565 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
566 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
567 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
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 ], [
574 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
575 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
576 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
577 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
578 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
579 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
580 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
581 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
582 ], [
583 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
584 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
585 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
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 ]
592 ];
593 const INDEO5_QUANT8X8_INTER: [[u16; 64]; 5] = [
594 [
595 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
596 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
597 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
598 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
599 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
600 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
601 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
602 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
603 ], [
604 0x26, 0x3a, 0x3e, 0x46, 0x4a, 0x4e, 0x52, 0x5a,
605 0x3a, 0x3e, 0x42, 0x46, 0x4a, 0x4e, 0x56, 0x5e,
606 0x3e, 0x42, 0x46, 0x48, 0x4c, 0x52, 0x5a, 0x62,
607 0x46, 0x46, 0x48, 0x4a, 0x4e, 0x56, 0x5e, 0x66,
608 0x4a, 0x4a, 0x4c, 0x4e, 0x52, 0x5a, 0x62, 0x6a,
609 0x4e, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x66, 0x6e,
610 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x72,
611 0x5a, 0x5e, 0x62, 0x66, 0x6a, 0x6e, 0x72, 0x76,
612 ], [
613 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
614 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
615 0x4e, 0xaa, 0xf2, 0xd4, 0xde, 0xc2, 0xd6, 0xc2,
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 ], [
622 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
623 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
624 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
625 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
626 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde,
627 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
628 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
629 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
630 ], [
631 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
632 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
633 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
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 ]
640 ];
641 const INDEO5_QUANT4X4_INTRA: [u16; 16] = [
642 0x1e, 0x3e, 0x4a, 0x52,
643 0x3e, 0x4a, 0x52, 0x5e,
644 0x4a, 0x52, 0x5e, 0x7a,
645 0x52, 0x5e, 0x7a, 0x92
646 ];
647 const INDEO5_QUANT4X4_INTER: [u16; 16] = [
648 0x1e, 0x3e, 0x4a, 0x52,
649 0x3e, 0x4a, 0x52, 0x56,
650 0x4a, 0x52, 0x56, 0x5e,
651 0x52, 0x56, 0x5e, 0x66
652 ];
653 const INDEO5_Q8_INTRA: [&[u16; 64]; 5] = [
654 &INDEO5_QUANT8X8_INTRA[0], &INDEO5_QUANT8X8_INTRA[1], &INDEO5_QUANT8X8_INTRA[2],
655 &INDEO5_QUANT8X8_INTRA[3], &INDEO5_QUANT8X8_INTRA[4],
656 ];
657 const INDEO5_Q8_INTER: [&[u16; 64]; 5] = [
658 &INDEO5_QUANT8X8_INTER[0], &INDEO5_QUANT8X8_INTER[1], &INDEO5_QUANT8X8_INTER[2],
659 &INDEO5_QUANT8X8_INTER[3], &INDEO5_QUANT8X8_INTER[4],
660 ];
661 const INDEO5_Q4_INTRA: &[u16; 16] = &INDEO5_QUANT4X4_INTRA;
662 const INDEO5_Q4_INTER: &[u16; 16] = &INDEO5_QUANT4X4_INTER;
663
664 const INDEO5_SCAN8X8: [&[usize; 64]; 4] = [
665 &IVI_ZIGZAG, &IVI_SCAN_8X8_VER, &IVI_SCAN_8X8_HOR, &IVI_SCAN_8X8_HOR
666 ];
667 const INDEO5_SCAN4X4: &[usize; 16] = &IVI_SCAN_4X4;
668
669 const INDEO5_QSCALE8_INTRA: [[u8; 24]; 5] = [
670 [
671 0x0b, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
672 0x22, 0x24, 0x27, 0x28, 0x2a, 0x2d, 0x2f, 0x31, 0x34, 0x37, 0x39, 0x3c,
673 ], [
674 0x01, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x28, 0x2c,
675 0x30, 0x34, 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x52, 0x58, 0x5e, 0x65, 0x6c,
676 ], [
677 0x13, 0x22, 0x27, 0x2a, 0x2d, 0x33, 0x36, 0x3c, 0x41, 0x45, 0x49, 0x4e,
678 0x53, 0x58, 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x7c, 0x82, 0x88, 0x8e, 0x95,
679 ], [
680 0x13, 0x1f, 0x21, 0x24, 0x27, 0x29, 0x2d, 0x2f, 0x34, 0x37, 0x3a, 0x3d,
681 0x40, 0x44, 0x48, 0x4c, 0x4f, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6b,
682 ], [
683 0x31, 0x42, 0x47, 0x47, 0x4d, 0x52, 0x58, 0x58, 0x5d, 0x63, 0x67, 0x6b,
684 0x6f, 0x73, 0x78, 0x7c, 0x80, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa4,
685 ]
686 ];
687 const INDEO5_QSCALE8_INTER: [[u8; 24]; 5] = [
688 [
689 0x0b, 0x11, 0x13, 0x14, 0x15, 0x16, 0x18, 0x1a, 0x1b, 0x1d, 0x20, 0x22,
690 0x23, 0x25, 0x28, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x41, 0x44, 0x4a,
691 ], [
692 0x07, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
693 0x3a, 0x3f, 0x44, 0x4a, 0x50, 0x56, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x7e,
694 ], [
695 0x15, 0x25, 0x28, 0x2d, 0x30, 0x34, 0x3a, 0x3d, 0x42, 0x48, 0x4c, 0x51,
696 0x56, 0x5b, 0x60, 0x65, 0x6b, 0x70, 0x76, 0x7c, 0x82, 0x88, 0x8f, 0x97,
697 ], [
698 0x13, 0x1f, 0x20, 0x22, 0x25, 0x28, 0x2b, 0x2d, 0x30, 0x33, 0x36, 0x39,
699 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4b, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62,
700 ], [
701 0x3c, 0x52, 0x58, 0x5d, 0x63, 0x68, 0x68, 0x6d, 0x73, 0x78, 0x7c, 0x80,
702 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa3, 0xa9, 0xad, 0xb1, 0xb5, 0xba
703 ]
704 ];
705 const INDEO5_QSCALE4_INTRA: [u8; 24] = [
706 0x01, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14,
707 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
708 ];
709 const INDEO5_QSCALE4_INTER: [u8; 24] = [
710 0x0b, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
711 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
712 ];
713
714 pub fn get_decoder() -> Box<NADecoder> {
715 Box::new(Indeo5Decoder::new())
716 }
717
718 #[cfg(test)]
719 mod test {
720 use nihav_core::codecs::RegisteredDecoders;
721 use nihav_core::demuxers::RegisteredDemuxers;
722 use nihav_core::test::dec_video::*;
723 use crate::codecs::indeo_register_all_codecs;
724 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
725 #[test]
726 fn test_indeo5() {
727 let mut dmx_reg = RegisteredDemuxers::new();
728 generic_register_all_demuxers(&mut dmx_reg);
729 let mut dec_reg = RegisteredDecoders::new();
730 indeo_register_all_codecs(&mut dec_reg);
731
732 test_file_decoding("avi", "assets/Indeo/IV5/sample.avi", /*None*/Some(2), true, false, None, &dmx_reg, &dec_reg);
733 // test_file_decoding("avi", "assets/Indeo/IV5/W32mdl_1.avi", None/*Some(2)*/, true, false, Some("iv5"));
734 //panic!("the end");
735 }
736 }