add flush() to decoder interface
[nihav.git] / nihav-indeo / src / codecs / ivibr.rs
index 10581c80a539e55c7a570b09f6b0d5a6eff05338..cfb073f8baad7fe3231e68ab742bb31dc8b6bb99 100644 (file)
@@ -1,16 +1,14 @@
 use std::mem;
 use std::rc::Rc;
-use std::cell::{Ref,RefCell};
+pub use std::cell::{Ref,RefCell};
 use nihav_core::io::bitreader::*;
 //use io::intcode::*;
 use nihav_core::codecs::*;
-use nihav_core::formats::*;
-use nihav_core::frame::*;
 use super::ivi::*;
 use super::ividsp::*;
 
 pub fn scale_mv(val: i32, scale: u8) -> i32 {
-    (val + (if val > 0 { 1 } else { 0 }) + (scale as i32) - 1) >> scale
+    (val + (if val > 0 { 1 } else { 0 }) + i32::from(scale) - 1) >> scale
 }
 
 #[derive(Clone,Copy)]
@@ -105,7 +103,7 @@ impl<'a> IVICodebookReader for BitReader<'a> {
             Ok(base + add)
         } else {
             let nbits = cb.bits[0];
-            return Ok(IVI_REVS[nbits as usize][self.read(nbits)? as usize]);
+            Ok(IVI_REVS[nbits as usize][self.read(nbits)? as usize])
         }
     }
     #[inline(always)]
@@ -148,6 +146,7 @@ pub const IVI_BLK_CB: &[IVICodebook; 8] = &[
 ];
 
 #[allow(unused_variables)]
+#[allow(clippy::many_single_char_names)]
 fn read_trans_band_header(br: &mut BitReader, w: usize, h: usize, dst: &mut [i16], dstride: usize) -> DecoderResult<()> {
     let color_plane     = br.read(2)?;
     let bit_depth       = br.read(3)?;
@@ -261,7 +260,7 @@ fn decode_block8x8(br: &mut BitReader, blk_cb: &IVICodebook, rvmap: &RVMap, tabl
         validate!((idx >= 0) && (idx < 64));
 
         let spos = tables.scan[idx as usize];
-        let q = ((quant_mat[spos] as u32) * (quant as u32)) >> 9;
+        let q = (u32::from(quant_mat[spos]) * u32::from(quant)) >> 9;
         if q > 1 {
             let qq = q as i32;
             let bias = (((q ^ 1) - 1) >> 1) as i32;
@@ -310,7 +309,7 @@ fn decode_block4x4(br: &mut BitReader, blk_cb: &IVICodebook, rvmap: &RVMap, tabl
         validate!((idx >= 0) && (idx < 16));
 
         let spos = tables.scan[idx as usize];
-        let q = ((quant_mat[spos] as u32) * (quant as u32)) >> 9;
+        let q = (u32::from(quant_mat[spos]) * u32::from(quant)) >> 9;
         if q > 1 {
             let qq = q as i32;
             let bias = (((q ^ 1) - 1) >> 1) as i32;
@@ -331,24 +330,24 @@ fn decode_block4x4(br: &mut BitReader, blk_cb: &IVICodebook, rvmap: &RVMap, tabl
 
 fn put_block(frame: &mut [i16], offs: usize, stride: usize, blk: &[i32], blk_size: usize) {
     unsafe {
-        let mut dptr = frame.as_mut_ptr().offset(offs as isize);
+        let mut dptr = frame.as_mut_ptr().add(offs);
         for y in 0..blk_size {
             for x in 0..blk_size {
-                *dptr.offset(x as isize) = blk[x + y * blk_size] as i16;
+                *dptr.add(x) = blk[x + y * blk_size] as i16;
             }
-            dptr = dptr.offset(stride as isize);
+            dptr = dptr.add(stride);
         }
     }
 }
 
 fn add_block(frame: &mut [i16], offs: usize, stride: usize, blk: &[i32], blk_size: usize) {
     unsafe {
-        let mut dptr = frame.as_mut_ptr().offset(offs as isize);
+        let mut dptr = frame.as_mut_ptr().add(offs);
         for y in 0..blk_size {
             for x in 0..blk_size {
-                *dptr.offset(x as isize) = (*dptr.offset(x as isize)).wrapping_add(blk[x + y * blk_size] as i16);
+                *dptr.add(x) = (*dptr.add(x)).wrapping_add(blk[x + y * blk_size] as i16);
             }
-            dptr = dptr.offset(stride as isize);
+            dptr = dptr.add(stride);
         }
     }
 }
@@ -391,10 +390,11 @@ impl FrameData {
         Ok(())
     }
     fn fill_plane(&mut self, vb: &mut NAVideoBuffer<u8>, plane: usize) {
-        let (w, h)   = vb.get_dimensions(plane);
-        let mut didx = vb.get_offset(plane);
-        let dstride  = vb.get_stride(plane);
-        let mut dst  = vb.get_data_mut();
+        let dplane = if (plane == 1) || (plane == 2) { plane ^ 3 } else { plane };
+        let (w, h)   = vb.get_dimensions(dplane);
+        let mut didx = vb.get_offset(dplane);
+        let dstride  = vb.get_stride(dplane);
+        let dst      = vb.get_data_mut().unwrap();
         let src      = &self.plane_buf[plane];
         let mut sidx = 0;
         let sstride  = self.plane_stride[plane];
@@ -408,6 +408,7 @@ impl FrameData {
     }
 }
 
+#[allow(clippy::many_single_char_names)]
 fn do_mc(dst: &mut [i16], dstride: usize, src: &[i16], sstride: usize, x: usize, y: usize, l: usize, r: usize, t: usize, b: usize, mv_x: i32, mv_y: i32, is_hpel: bool, blk_size: usize) {
     let (xoff, yoff, mv_mode) = if is_hpel {
             (mv_x >> 1, mv_y >> 1, ((mv_x & 1) + (mv_y & 1) * 2) as u8)
@@ -429,6 +430,7 @@ fn do_mc(dst: &mut [i16], dstride: usize, src: &[i16], sstride: usize, x: usize,
     }
 }
 
+#[allow(clippy::many_single_char_names)]
 fn do_mc_b(dst: &mut [i16], dstride: usize, src1: &[i16], sstride1: usize, src2: &[i16], sstride2: usize, x: usize, y: usize, l: usize, r: usize, t: usize, b: usize, mv_x: i32, mv_y: i32, mv2_x: i32, mv2_y: i32, is_hpel: bool, blk_size: usize) {
     let (xoff1, yoff1, mv_mode1) = if is_hpel {
             (mv_x >> 1, mv_y >> 1, ((mv_x & 1) + (mv_y & 1) * 2) as u8)
@@ -498,7 +500,7 @@ impl IVIDecoder {
             vinfoa: NAVideoInfo::new(0, 0, false, YUVA410_FORMAT),
             bref: None,
 
-            bands: bands,
+            bands,
             tiles: Vec::new(), tile_start: [[0; 4]; 4], num_tiles: [[0; 4]; 4],
         }
     }
@@ -689,7 +691,7 @@ br.skip(skip_part as u32)?;
                     let mut cbp = mb.cbp;
                     for blk_no in 0..4 {
                         let mut blk: [i32; 64] = [0; 64];
-                        let boff = (blk_no & 1) * 8 + (blk_no & 2) * 4 * stride + mb_x * 16;
+                        let boff = (blk_no & 1) * band.blk_size + (blk_no >> 1) * band.blk_size * stride + mb_x * band.mb_size;
                         if !is_intra {
                             if mb.mtype != MBType::Bidir {
                                 let idx;
@@ -701,18 +703,18 @@ br.skip(skip_part as u32)?;
                                 let pf = self.frames[idx].borrow();
                                 do_mc(&mut dst[dstidx + boff..], stride,
                                       &pf.plane_buf[band.plane_no], pf.plane_stride[band.plane_no],
-                                      pos_x + mb_x * 16 + (blk_no & 1) * 8,
-                                      pos_y + mb_y * 16 + (blk_no & 2) * 4,
+                                      pos_x + mb_x * band.mb_size + (blk_no & 1) * band.blk_size,
+                                      pos_y + mb_y * band.mb_size + (blk_no >> 1) * band.blk_size,
                                       pos_x, pos_x + tile_w, pos_y, pos_y + tile_h,
-                                      mb.mv_x, mb.mv_y, band.halfpel, 8);
+                                      mb.mv_x, mb.mv_y, band.halfpel, band.blk_size);
                             } else {
                                 let pf = self.frames[self.prev_frame].borrow();
                                 let nf = self.frames[self.next_frame].borrow();
                                 do_mc_b(&mut dst[dstidx + boff..], stride,
                                       &pf.plane_buf[band.plane_no], pf.plane_stride[band.plane_no],
                                       &nf.plane_buf[band.plane_no], nf.plane_stride[band.plane_no],
-                                      pos_x + mb_x * 16 + (blk_no & 1) * 8,
-                                      pos_y + mb_y * 16 + (blk_no & 2) * 4,
+                                      pos_x + mb_x * band.mb_size + (blk_no & 1) * band.blk_size,
+                                      pos_y + mb_y * band.mb_size + (blk_no >> 1) * band.blk_size,
                                       pos_x, pos_x + tile_w, pos_y, pos_y + tile_h,
                                       mb.mv_x, mb.mv_y, mb.mv2_x, mb.mv2_y, band.halfpel,
                                       band.blk_size);
@@ -727,10 +729,18 @@ br.skip(skip_part as u32)?;
                                     add_block(&mut dst, dstidx + boff, stride, &blk, 8);
                                 }
                             }
+                            if let TxType::Transform4(ref params) = band.ttype {
+                                decode_block4x4(br, &band.blk_cb, &band.rvmap, params, is_intra, band.tr.is_2d(), &mut prev_dc, mb.q, &mut blk, tr)?;
+                                if is_intra {
+                                    put_block(&mut dst, dstidx + boff, stride, &blk, 4);
+                                } else {
+                                    add_block(&mut dst, dstidx + boff, stride, &blk, 4);
+                                }
+                            }
                         } else {
                             if is_intra {
                                 (transform_dc)(&mut blk, prev_dc);
-                                put_block(&mut dst, dstidx + boff, stride, &blk, 8);
+                                put_block(&mut dst, dstidx + boff, stride, &blk, band.blk_size);
                             }
                         }
                         cbp >>= 1;
@@ -850,12 +860,7 @@ br.skip(skip_part as u32)?;
             _ => {},
         };
 
-        let mut vinfo;
-        if pic_hdr.transparent {
-            vinfo = self.vinfoa.clone();
-        } else {
-            vinfo = self.vinfo.clone();
-        }
+        let mut vinfo = if pic_hdr.transparent { self.vinfoa } else { self.vinfo };
         vinfo.set_width(pic_hdr.width);
         vinfo.set_height(pic_hdr.height);
         let mut buftype = alloc_video_buffer(vinfo, 0)?;
@@ -872,10 +877,11 @@ br.skip(skip_part as u32)?;
                 if num_bands == 1 {
                     frame.fill_plane(vb, plane);
                 } else {
-                    let (w, h)  = vb.get_dimensions(plane);
-                    let dstride = vb.get_stride(plane);
-                    let off     = vb.get_offset(plane);
-                    let mut dst = vb.get_data_mut();
+                    let dplane = if (plane == 1) || (plane == 2) { plane ^ 3 } else { plane };
+                    let (w, h)  = vb.get_dimensions(dplane);
+                    let dstride = vb.get_stride(dplane);
+                    let off     = vb.get_offset(dplane);
+                    let dst = vb.get_data_mut().unwrap();
                     dec.recombine_plane(&frame.plane_buf[plane], frame.plane_stride[plane], &mut dst[off..], dstride, w, h);
                 }
             }
@@ -939,10 +945,18 @@ br.skip(skip_part as u32)?;
         res
     }
 
-    pub fn is_intra(&mut self) -> bool {
+    pub fn flush(&mut self) {
+        self.prev_frame = MISSING_REF;
+        self.next_frame = MISSING_REF;
+        self.iref_0     = MISSING_REF;
+        self.iref_1     = MISSING_REF;
+        self.scal_ref   = MISSING_REF;
+    }
+
+    pub fn is_intra(&self) -> bool {
         self.ftype.is_intra()
     }
-    pub fn get_frame_type(&mut self) -> FrameType {
+    pub fn get_frame_type(&self) -> FrameType {
         match self.ftype {
             IVIFrameType::Intra             => { FrameType::I },
             IVIFrameType::Intra1            => { FrameType::I },
@@ -968,7 +982,7 @@ impl Clone for RVMap {
         let mut valtab: [i8; 256] = [0; 256];
         runtab.copy_from_slice(&self.runtab);
         valtab.copy_from_slice(&self.valtab);
-        RVMap { eob_sym: self.eob_sym, esc_sym: self.esc_sym, runtab: runtab, valtab: valtab }
+        RVMap { eob_sym: self.eob_sym, esc_sym: self.esc_sym, runtab, valtab }
     }
 }