use frame refs everywhere
authorKostya Shishkov <kostya.shishkov@gmail.com>
Sat, 20 May 2017 14:45:01 +0000 (16:45 +0200)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Sat, 20 May 2017 14:45:01 +0000 (16:45 +0200)
src/codecs/indeo2.rs
src/codecs/mod.rs
src/frame.rs

index 39143098ade6679c4876b67da0b95ebef0f18ab4..5036f16f13dfc441ee001a21c905ead9106f8b4b 100644 (file)
@@ -186,7 +186,7 @@ impl CodebookDescReader<u8> for IR2CodeReader {
 struct Indeo2Decoder {
     info:    Rc<NACodecInfo>,
     cb:      Codebook<u8>,
-    lastfrm: Option<Rc<NAFrame>>,
+    frmmgr:  HAMShuffler,
 }
 
 impl Indeo2Decoder {
@@ -194,7 +194,7 @@ impl Indeo2Decoder {
         let dummy_info = Rc::new(DUMMY_CODEC_INFO);
         let mut coderead = IR2CodeReader{};
         let cb = Codebook::new(&mut coderead, CodebookMode::LSB).unwrap();
-        Indeo2Decoder { info: dummy_info, cb: cb, lastfrm: None }
+        Indeo2Decoder { info: dummy_info, cb: cb, frmmgr: HAMShuffler::new() }
     }
 
     fn decode_plane_intra(&self, br: &mut BitReader,
@@ -205,8 +205,8 @@ impl Indeo2Decoder {
         let stride = frm.get_stride(planeno);
         let cb = &self.cb;
 
-        let mut buffer = frm.get_buffer_mut().unwrap();
-        let mut data = buffer.get_data_mut().unwrap();
+        let mut buffer = frm.get_buffer_mut();
+        let mut data = buffer.get_data_mut();
         let mut framebuf: &mut [u8] = data.as_mut_slice();
 
         let table = &INDEO2_DELTA_TABLE[tableno];
@@ -269,8 +269,8 @@ impl Indeo2Decoder {
         let stride = frm.get_stride(planeno);
         let cb = &self.cb;
 
-        let mut buffer = frm.get_buffer_mut().unwrap();
-        let mut data = buffer.get_data_mut().unwrap();
+        let mut buffer = frm.get_buffer_mut();
+        let mut data = buffer.get_data_mut();
         let mut framebuf: &mut [u8] = data.as_mut_slice();
 
         let table = &INDEO2_DELTA_TABLE[tableno];
@@ -318,12 +318,13 @@ impl NADecoder for Indeo2Decoder {
             let fmt = formats::YUV410_FORMAT;
             let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, f, fmt));
             self.info = Rc::new(NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()));
+            self.frmmgr.clear();
             Ok(())
         } else {
             Err(DecoderError::InvalidData)
         }
     }
-    fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<Rc<NAFrame>> {
+    fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
         let src = pkt.get_buffer();
         if src.len() <= IR2_START { return Err(DecoderError::ShortData); }
         let interframe = src[18];
@@ -333,27 +334,27 @@ impl NADecoder for Indeo2Decoder {
         let chroma_tab = (tabs >> 2) & 3;
         if interframe != 0 {
             let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone());
+            frm.set_keyframe(true);
+            frm.set_frame_type(FrameType::I);
             for plane in 0..3 {
                 let tabidx = (if plane == 0 { luma_tab } else { chroma_tab }) as usize;
                 self.decode_plane_intra(&mut br, &mut frm, plane, tabidx)?;
             }
-            let rcf = Rc::new(frm);
-            self.lastfrm = Some(rcf.clone());
-            Ok(rcf)
+            self.frmmgr.add_frame(frm);
         } else {
-            let lf = self.lastfrm.clone();
-            if let None = lf { return Err(DecoderError::MissingReference); }
-            let lastfr = lf.unwrap();
-            let mut frm = NAFrame::from_copy(lastfr.as_ref());
+            let frmref = self.frmmgr.clone_ref();
+            if let None = frmref { return Err(DecoderError::MissingReference); }
+            let ffrmref = frmref.unwrap();
+            let mut frm = ffrmref.borrow_mut();
+            frm.set_keyframe(false);
+            frm.set_frame_type(FrameType::P);
             frm.fill_timestamps(pkt);
             for plane in 0..3 {
                 let tabidx = (if plane == 0 { luma_tab } else { chroma_tab }) as usize;
                 self.decode_plane_inter(&mut br, &mut frm, plane, tabidx)?;
             }
-            let rcf = Rc::new(frm);
-            self.lastfrm = Some(rcf.clone());
-            Ok(rcf)
         }
+        Ok(self.frmmgr.get_output_frame().unwrap())
     }
 }
 
@@ -365,7 +366,7 @@ pub fn get_decoder() -> Box<NADecoder> {
 mod test {
     use codecs;
     use demuxers::*;
-    use frame::NAFrame;
+    use frame::NAFrameRef;
     use io::byteio::*;
     use std::fs::File;
     use std::io::prelude::*;
@@ -400,12 +401,13 @@ mod test {
             let pkt = pktres.unwrap();
             if pkt.get_stream().get_id() == str {
                 let frm = dec.decode(&pkt).unwrap();
-                write_pgmyuv(pkt.get_pts().unwrap(), &frm);
+                write_pgmyuv(pkt.get_pts().unwrap(), frm);
             }
         }
     }
 
-    fn write_pgmyuv(num: u64, frm: &NAFrame) {
+    fn write_pgmyuv(num: u64, frmref: NAFrameRef) {
+        let frm = frmref.borrow();
         let name = format!("assets/out{:04}.pgm", num);
         let mut ofile = File::create(name).unwrap();
         let (w, h) = frm.get_dimensions(0);
index 7edcf9eb2e6cdb60ea3292f269505eca78908ea3..426cb049f9dffea322999b8b66265594403cf13e 100644 (file)
@@ -1,8 +1,9 @@
 #[cfg(feature="decoder_indeo2")]
 pub mod indeo2;
 
-use std::rc::Rc;
 use frame::*;
+use std::rc::Rc;
+use std::cell::RefCell;
 use io::byteio::ByteIOError;
 use io::bitreader::BitReaderError;
 use io::codebook::CodebookError;
@@ -36,9 +37,39 @@ impl From<CodebookError> for DecoderError {
     fn from(_: CodebookError) -> Self { DecoderError::InvalidData }
 }
 
+#[allow(dead_code)]
+struct HAMShuffler {
+    lastframe: Option<NAFrameRef>,
+}
+
+impl HAMShuffler {
+    #[allow(dead_code)]
+    fn new() -> Self { HAMShuffler { lastframe: None } }
+    #[allow(dead_code)]
+    fn clear(&mut self) { self.lastframe = None; }
+    #[allow(dead_code)]
+    fn add_frame(&mut self, frm: NAFrame) {
+        self.lastframe = Some(Rc::new(RefCell::new(frm)));
+    }
+    #[allow(dead_code)]
+    fn clone_ref(&mut self) -> Option<NAFrameRef> {
+        match self.lastframe {
+            Some(ref frm) => Some(Rc::new(RefCell::new(NAFrame::from_copy(&frm.borrow())))),
+            None => None,
+        }
+    }
+    #[allow(dead_code)]
+    fn get_output_frame(&mut self) -> Option<NAFrameRef> {
+        match self.lastframe {
+            Some(ref frm) => Some(frm.clone()),
+            None => None,
+        }
+    }
+}
+
 pub trait NADecoder {
     fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()>;
-    fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<Rc<NAFrame>>;
+    fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef>;
 }
 
 #[derive(Clone,Copy)]
index 449512c2a10e027dd488898caf2a1263e6e81d4a..c086339bf3dd0299f7696cadd3a09798f0711010 100644 (file)
@@ -1,6 +1,7 @@
 use std::collections::HashMap;
 use std::fmt;
 use std::rc::Rc;
+use std::cell::*;
 use formats::*;
 
 #[allow(dead_code)]
@@ -71,12 +72,13 @@ impl fmt::Display for NACodecTypeInfo {
     }
 }
 
+pub type BufferRef = Rc<RefCell<Vec<u8>>>;
 
 #[allow(dead_code)]
 #[derive(Clone)]
 pub struct NABuffer {
     id:   u64,
-    data: Rc<Vec<u8>>,
+    data: BufferRef,
 }
 
 impl Drop for NABuffer {
@@ -84,10 +86,12 @@ impl Drop for NABuffer {
 }
 
 impl NABuffer {
-    pub fn get_data(&self) -> Rc<Vec<u8>> { self.data.clone() }
-    pub fn get_data_mut(&mut self) -> Option<&mut Vec<u8>> { Rc::get_mut(&mut self.data) }
+    pub fn get_data(&self) -> Ref<Vec<u8>> { self.data.borrow() }
+    pub fn get_data_mut(&mut self) -> RefMut<Vec<u8>> { self.data.borrow_mut() }
 }
 
+pub type NABufferRef = Rc<RefCell<NABuffer>>;
+
 #[allow(dead_code)]
 #[derive(Clone)]
 pub struct NACodecInfo {
@@ -171,7 +175,7 @@ fn alloc_audio_buf(ainfo: NAAudioInfo, data: &mut Vec<u8>, offs: &mut Vec<usize>
     }
 }
 
-pub fn alloc_buf(info: &NACodecInfo) -> (Rc<NABuffer>, Vec<usize>) {
+pub fn alloc_buf(info: &NACodecInfo) -> (NABufferRef, Vec<usize>) {
     let mut data: Vec<u8> = Vec::new();
     let mut offs: Vec<usize> = Vec::new();
     match info.properties {
@@ -179,13 +183,13 @@ pub fn alloc_buf(info: &NACodecInfo) -> (Rc<NABuffer>, Vec<usize>) {
         NACodecTypeInfo::Video(vinfo) => alloc_video_buf(vinfo, &mut data, &mut offs),
         _ => (),
     }
-    (Rc::new(NABuffer { id: 0, data: Rc::new(data) }), offs)
+    (Rc::new(RefCell::new(NABuffer { id: 0, data: Rc::new(RefCell::new(data)) })), offs)
 }
 
-pub fn copy_buf(buf: &NABuffer) -> Rc<NABuffer> {
+pub fn copy_buf(buf: &NABuffer) -> NABufferRef {
     let mut data: Vec<u8> = Vec::new();
     data.clone_from(buf.get_data().as_ref());
-    Rc::new(NABuffer { id: 0, data: Rc::new(data) })
+    Rc::new(RefCell::new(NABuffer { id: 0, data: Rc::new(RefCell::new(data)) }))
 }
 
 #[derive(Debug,Clone)]
@@ -197,14 +201,36 @@ pub enum NAValue {
     Data(Rc<Vec<u8>>),
 }
 
+#[derive(Debug,Clone,Copy,PartialEq)]
+#[allow(dead_code)]
+pub enum FrameType {
+    I,
+    P,
+    B,
+    Other,
+}
+
+impl fmt::Display for FrameType {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            FrameType::I => write!(f, "I"),
+            FrameType::P => write!(f, "P"),
+            FrameType::B => write!(f, "B"),
+            FrameType::Other => write!(f, "x"),
+        }
+    }
+}
+
 #[allow(dead_code)]
 #[derive(Clone)]
 pub struct NAFrame {
     pts:            Option<u64>,
     dts:            Option<u64>,
     duration:       Option<u64>,
-    buffer:         Rc<NABuffer>,
+    buffer:         NABufferRef,
     info:           Rc<NACodecInfo>,
+    ftype:          FrameType,
+    key:            bool,
     offsets:        Vec<usize>,
     options:        HashMap<String, NAValue>,
 }
@@ -222,27 +248,33 @@ impl NAFrame {
     pub fn new(pts:            Option<u64>,
                dts:            Option<u64>,
                duration:       Option<u64>,
+               ftype:          FrameType,
+               keyframe:       bool,
                info:           Rc<NACodecInfo>,
                options:        HashMap<String, NAValue>) -> Self {
         let (buf, offs) = alloc_buf(&info);
-        NAFrame { pts: pts, dts: dts, duration: duration, buffer: buf, offsets: offs, info: info, options: options }
+        NAFrame { pts: pts, dts: dts, duration: duration, buffer: buf, offsets: offs, info: info, ftype: ftype, key: keyframe, options: options }
     }
     pub fn from_copy(src: &NAFrame) -> Self {
-        let buf = copy_buf(src.get_buffer().as_ref());
+        let buf = copy_buf(&src.get_buffer());
         let mut offs: Vec<usize> = Vec::new();
         offs.clone_from(&src.offsets);
-        NAFrame { pts: None, dts: None, duration: None, buffer: buf, offsets: offs, info: src.info.clone(), options: src.options.clone() }
+        NAFrame { pts: None, dts: None, duration: None, buffer: buf, offsets: offs, info: src.info.clone(), ftype: src.ftype, key: src.key, options: src.options.clone() }
     }
     pub fn get_pts(&self) -> Option<u64> { self.pts }
     pub fn get_dts(&self) -> Option<u64> { self.dts }
     pub fn get_duration(&self) -> Option<u64> { self.duration }
+    pub fn get_frame_type(&self) -> FrameType { self.ftype }
+    pub fn is_keyframe(&self) -> bool { self.key }
     pub fn set_pts(&mut self, pts: Option<u64>) { self.pts = pts; }
     pub fn set_dts(&mut self, dts: Option<u64>) { self.dts = dts; }
     pub fn set_duration(&mut self, dur: Option<u64>) { self.duration = dur; }
+    pub fn set_frame_type(&mut self, ftype: FrameType) { self.ftype = ftype; }
+    pub fn set_keyframe(&mut self, key: bool) { self.key = key; }
 
     pub fn get_offset(&self, idx: usize) -> usize { self.offsets[idx] }
-    pub fn get_buffer(&self) -> Rc<NABuffer> { self.buffer.clone() }
-    pub fn get_buffer_mut(&mut self) -> Option<&mut NABuffer> { Rc::get_mut(&mut self.buffer) }
+    pub fn get_buffer(&self) -> Ref<NABuffer> { self.buffer.borrow() }
+    pub fn get_buffer_mut(&mut self) -> RefMut<NABuffer> { self.buffer.borrow_mut() }
     pub fn get_stride(&self, idx: usize) -> usize {
         if let NACodecTypeInfo::Video(vinfo) = self.info.get_properties() {
             if idx >= vinfo.get_format().get_num_comp() { return 0; }
@@ -259,6 +291,8 @@ impl NAFrame {
     }
 }
 
+pub type NAFrameRef = Rc<RefCell<NAFrame>>;
+
 /// Possible stream types.
 #[derive(Debug,Clone,Copy)]
 #[allow(dead_code)]
@@ -360,7 +394,7 @@ pub trait FrameFromPacket {
 
 impl FrameFromPacket for NAFrame {
     fn new_from_pkt(pkt: &NAPacket, info: Rc<NACodecInfo>) -> NAFrame {
-        NAFrame::new(pkt.pts, pkt.dts, pkt.duration, info, HashMap::new())
+        NAFrame::new(pkt.pts, pkt.dts, pkt.duration, FrameType::Other, pkt.keyframe, info, HashMap::new())
     }
     fn fill_timestamps(&mut self, pkt: &NAPacket) {
         self.set_pts(pkt.pts);