add flush() to decoder interface
[nihav.git] / nihav-realmedia / src / codecs / rv60.rs
index 4adbe394406c2b25be546fbcfb153a453998d9b4..bf89a5151361423cddb78f8b979c18417a7aec14 100644 (file)
@@ -1,6 +1,6 @@
 use nihav_core::formats::YUV420_FORMAT;
 use nihav_core::frame::*;
-use nihav_core::codecs::{NADecoder, MV, ZERO_MV, DecoderError, DecoderResult, IPBShuffler};
+use nihav_core::codecs::{NADecoder, NADecoderSupport, MV, ZERO_MV, DecoderError, DecoderResult, IPBShuffler};
 use nihav_core::io::byteio::{MemoryReader,ByteReader};
 use nihav_core::io::bitreader::{BitReader,BitReaderMode};
 use nihav_core::io::intcode::*;
@@ -21,7 +21,7 @@ impl<A:Copy+Default+PartialEq> UniqueList<A> {
     fn add(&mut self, cand: A) {
         if self.fill == self.max_size { return; }
         let mut unique = true;
-        for el in self.list.into_iter().take(self.fill) {
+        for el in self.list.iter().take(self.fill) {
             if *el == cand {
                 unique = false;
                 break;
@@ -257,58 +257,58 @@ const RV60_PU_TYPES: [PUType; 8] = [
 ];
 
 impl PUType {
-    fn get_num_mvs(&self) -> usize {
-        match *self {
+    fn get_num_mvs(self) -> usize {
+        match self {
             PUType::Full        => 1,
             PUType::Quarters    => 4,
             _                   => 2,
         }
     }
-    fn get_mv_size(&self, part_no: usize, size: usize) -> (usize, usize) {
+    fn get_mv_size(self, part_no: usize, size: usize) -> (usize, usize) {
         let mv_size = size >> 2;
-        match *self {
+        match self {
             PUType::Full        => (mv_size, mv_size),
             PUType::N2Hor       => (mv_size, mv_size >> 1),
             PUType::N2Ver       => (mv_size >> 1, mv_size),
             PUType::Quarters    => (mv_size >> 1, mv_size >> 1),
             PUType::N4Hor       => {
                     if part_no == 0 {
-                        (mv_size,     mv_size >> 2)
+                        (mv_size,      mv_size  >> 2)
                     } else {
-                        (mv_size, 3 * mv_size >> 2)
+                        (mv_size, (3 * mv_size) >> 2)
                     }
                 },
             PUType::N34Hor      => {
                     if part_no == 0 {
-                        (mv_size, 3 * mv_size >> 2)
+                        (mv_size, (3 * mv_size) >> 2)
                     } else {
-                        (mv_size,     mv_size >> 2)
+                        (mv_size,      mv_size  >> 2)
                     }
                 },
             PUType::N4Ver       => {
                     if part_no == 0 {
-                        (    mv_size >> 2, mv_size)
+                        (     mv_size  >> 2, mv_size)
                     } else {
-                        (3 * mv_size >> 2, mv_size)
+                        ((3 * mv_size) >> 2, mv_size)
                     }
                 },
             PUType::N34Ver      => {
                     if part_no == 0 {
-                        (3 * mv_size >> 2, mv_size)
+                        ((3 * mv_size) >> 2, mv_size)
                     } else {
-                        (    mv_size >> 2, mv_size)
+                        (     mv_size  >> 2, mv_size)
                     }
                 },
         }
     }
-    fn has_hor_split(&self) -> bool {
-        match *self {
+    fn has_hor_split(self) -> bool {
+        match self {
             PUType::N2Hor | PUType::N4Hor | PUType::N34Hor | PUType::Quarters => true,
             _ => false,
         }
     }
-    fn has_ver_split(&self) -> bool {
-        match *self {
+    fn has_ver_split(self) -> bool {
+        match self {
             PUType::N2Ver | PUType::N4Ver | PUType::N34Ver | PUType::Quarters => true,
             _ => false,
         }
@@ -355,28 +355,28 @@ enum MVRef {
 const SKIP_MV_REF: [MVRef; 4] = [ MVRef::Skip0,  MVRef::Skip1, MVRef::Skip2,  MVRef::Skip3 ];
 
 impl MVRef {
-    fn get_skip_mv_num(&self) -> usize {
-        match *self {
+    fn get_skip_mv_num(self) -> usize {
+        match self {
             MVRef::Skip1    => 1,
             MVRef::Skip2    => 2,
             MVRef::Skip3    => 3,
             _               => 0,
         }
     }
-    fn is_ref0(&self) -> bool {
-        match *self {
+    fn is_ref0(self) -> bool {
+        match self {
             MVRef::Ref0 | MVRef::Ref0AndBRef => true,
             _ => false,
         }
     }
-    fn is_fwd(&self) -> bool {
-        match *self {
+    fn is_fwd(self) -> bool {
+        match self {
             MVRef::Ref0 | MVRef::Ref1 | MVRef::Ref0AndBRef => true,
             _ => false,
         }
     }
-    fn is_bwd(&self) -> bool {
-        match *self {
+    fn is_bwd(self) -> bool {
+        match self {
             MVRef::BRef | MVRef::Ref0AndBRef => true,
             _ => false,
         }
@@ -550,7 +550,7 @@ struct PUInfo {
 }
 
 impl PUInfo {
-    fn is_intra(&self) -> bool { self.cu_type == CUType::Intra }
+    fn is_intra(self) -> bool { self.cu_type == CUType::Intra }
 }
 
 const RV60_CANDIDATE_INTRA_ANGLES: [u8; 6] = [ 0, 1, 10, 26, 18, 2 ];
@@ -614,7 +614,7 @@ struct RealVideo60Decoder {
     dsp:        RV60DSP,
     ipred:      IntraPredContext,
 
-    avg_buf:    NAVideoBuffer<u8>,
+    avg_buf:    NAVideoBufferRef<u8>,
 
     y_coeffs:   [i16; 16 * 16],
     u_coeffs:   [i16; 8 * 8],
@@ -650,7 +650,7 @@ impl RealVideo60Decoder {
             ipbs:       IPBShuffler::new(),
             ipred:      IntraPredContext::new(),
             dsp:        RV60DSP::new(),
-            avg_buf:    avg_buf,
+            avg_buf,
             y_coeffs:   [0; 16 * 16],
             u_coeffs:   [0; 8 * 8],
             v_coeffs:   [0; 8 * 8],
@@ -1117,7 +1117,7 @@ println!(" left {} bits", br.left());
                 }
             }
         }
-        for el in RV60_CANDIDATE_INTRA_ANGLES.into_iter() {
+        for el in RV60_CANDIDATE_INTRA_ANGLES.iter() {
             ipm_cand.add(*el);
         }
         // actually decode prediction mode
@@ -1129,7 +1129,7 @@ println!(" left {} bits", br.left());
                     let mut imode = mode;
                     let mut ipm_cs: [u8; 3] = [ipm_cand.list[0], ipm_cand.list[1], ipm_cand.list[2]];
                     ipm_cs.sort();
-                    for ic in ipm_cs.into_iter() {
+                    for ic in ipm_cs.iter() {
                         if imode >= *ic {
                             imode += 1;
                         }
@@ -1391,8 +1391,8 @@ println!(" left {} bits", br.left());
 }
 
 impl NADecoder for RealVideo60Decoder {
-    fn init(&mut self, info: NACodecInfoRef) -> DecoderResult<()> {
-        if let NACodecTypeInfo::Video(_vinfo) = info.get_properties() {
+    fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
+        if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
             let fmt = YUV420_FORMAT;
             let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, false, fmt));
             self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
@@ -1412,13 +1412,17 @@ impl NADecoder for RealVideo60Decoder {
             //self.bd.width  = vinfo.get_width();
             //self.bd.height = vinfo.get_height();
             //self.frmmgr.clear();
+
+            supp.pool_u8.set_dec_bufs(3);
+            supp.pool_u8.prealloc_video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, fmt), 6)?;
+
             Ok(())
         } else {
 println!("???");
             Err(DecoderError::InvalidData)
         }
     }
-    fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
+    fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
         let src = pkt.get_buffer();
 
         validate!(src.len() > 9);
@@ -1429,10 +1433,21 @@ println!("???");
         hdr.parse_slice_sizes(&mut br, &mut slices)?;
 
         let tmp_vinfo = NAVideoInfo::new(hdr.width, hdr.height, false, YUV420_FORMAT);
-        let res = alloc_video_buffer(tmp_vinfo, 6);
-        if !res.is_ok() { return Err(DecoderError::InvalidData); }
-        let bufinfo = res.unwrap();
-        let mut buf = bufinfo.get_vbuf().unwrap();
+        let ret = supp.pool_u8.get_free();
+        if ret.is_none() {
+            return Err(DecoderError::AllocError);
+        }
+        let mut buf = ret.unwrap();
+        if buf.get_info() != tmp_vinfo {
+            self.ipbs.clear();
+            supp.pool_u8.reset();
+            supp.pool_u8.prealloc_video(tmp_vinfo, 6)?;
+            let ret = supp.pool_u8.get_free();
+            if ret.is_none() {
+                return Err(DecoderError::AllocError);
+            }
+            buf = ret.unwrap();
+        }
 
         let cu_w = hdr.get_width_cu();
         let cu_h = hdr.get_height_cu();
@@ -1451,18 +1466,21 @@ println!("???");
             off += size;
         }
         if (hdr.ftype == FrameType::I) || (hdr.ftype == FrameType::P) {
-            self.ipbs.add_frame(buf);
+            self.ipbs.add_frame(buf.clone());
         }
 
-        let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
+        let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
         frm.set_keyframe(hdr.ftype == FrameType::I);
         frm.set_pts(Some(hdr.ts as u64));
         frm.set_frame_type(hdr.ftype);
-        Ok(Rc::new(RefCell::new(frm)))
+        Ok(frm.into_ref())
+    }
+    fn flush(&mut self) {
+        self.ipbs.clear();
     }
 }
 
-pub fn get_decoder() -> Box<NADecoder> {
+pub fn get_decoder() -> Box<dyn NADecoder> {
     Box::new(RealVideo60Decoder::new())
 }