switch NACodecInfo to Arc
[nihav.git] / nihav-core / src / frame.rs
index ea9f2031b5b7eacc4e6da36653399a0420bf22b3..bc3216bd2b3a37a9247f4414caf951be723bf64e 100644 (file)
@@ -3,6 +3,7 @@ use std::collections::HashMap;
 use std::fmt;
 pub use std::rc::Rc;
 pub use std::cell::*;
+use std::sync::Arc;
 pub use crate::formats::*;
 pub use crate::refs::*;
 
@@ -256,6 +257,48 @@ impl NABufferType {
     }
 }
 
+const NA_SIMPLE_VFRAME_COMPONENTS: usize = 4;
+pub struct NASimpleVideoFrame<'a, T: Copy> {
+    pub width:      [usize; NA_SIMPLE_VFRAME_COMPONENTS],
+    pub height:     [usize; NA_SIMPLE_VFRAME_COMPONENTS],
+    pub flip:       bool,
+    pub stride:     [usize; NA_SIMPLE_VFRAME_COMPONENTS],
+    pub offset:     [usize; NA_SIMPLE_VFRAME_COMPONENTS],
+    pub components: usize,
+    pub data:       &'a mut Vec<T>,
+}
+
+impl<'a, T:Copy> NASimpleVideoFrame<'a, T> {
+    pub fn from_video_buf(vbuf: &'a mut NAVideoBuffer<T>) -> Option<Self> {
+        let vinfo = vbuf.get_info();
+        let components = vinfo.format.components as usize;
+        if components > NA_SIMPLE_VFRAME_COMPONENTS {
+            return None;
+        }
+        let mut w: [usize; NA_SIMPLE_VFRAME_COMPONENTS] = [0; NA_SIMPLE_VFRAME_COMPONENTS];
+        let mut h: [usize; NA_SIMPLE_VFRAME_COMPONENTS] = [0; NA_SIMPLE_VFRAME_COMPONENTS];
+        let mut s: [usize; NA_SIMPLE_VFRAME_COMPONENTS] = [0; NA_SIMPLE_VFRAME_COMPONENTS];
+        let mut o: [usize; NA_SIMPLE_VFRAME_COMPONENTS] = [0; NA_SIMPLE_VFRAME_COMPONENTS];
+        for comp in 0..components {
+            let (width, height) = vbuf.get_dimensions(comp);
+            w[comp] = width;
+            h[comp] = height;
+            s[comp] = vbuf.get_stride(comp);
+            o[comp] = vbuf.get_offset(comp);
+        }
+        let flip = vinfo.flipped;
+        Some(NASimpleVideoFrame {
+            width:  w,
+            height: h,
+            flip,
+            stride: s,
+            offset: o,
+            components,
+            data: vbuf.data.as_mut().unwrap(),
+            })
+    }
+}
+
 #[derive(Debug,Clone,Copy,PartialEq)]
 pub enum AllocatorError {
     TooLargeDimensions,
@@ -489,22 +532,25 @@ impl NABufferPool {
 pub struct NACodecInfo {
     name:       &'static str,
     properties: NACodecTypeInfo,
-    extradata:  Option<Rc<Vec<u8>>>,
+    extradata:  Option<Arc<Vec<u8>>>,
 }
 
+pub type NACodecInfoRef = Arc<NACodecInfo>;
+
 impl NACodecInfo {
     pub fn new(name: &'static str, p: NACodecTypeInfo, edata: Option<Vec<u8>>) -> Self {
         let extradata = match edata {
             None => None,
-            Some(vec) => Some(Rc::new(vec)),
+            Some(vec) => Some(Arc::new(vec)),
         };
         NACodecInfo { name: name, properties: p, extradata: extradata }
     }
-    pub fn new_ref(name: &'static str, p: NACodecTypeInfo, edata: Option<Rc<Vec<u8>>>) -> Self {
+    pub fn new_ref(name: &'static str, p: NACodecTypeInfo, edata: Option<Arc<Vec<u8>>>) -> Self {
         NACodecInfo { name: name, properties: p, extradata: edata }
     }
+    pub fn into_ref(self) -> NACodecInfoRef { Arc::new(self) }
     pub fn get_properties(&self) -> NACodecTypeInfo { self.properties }
-    pub fn get_extradata(&self) -> Option<Rc<Vec<u8>>> {
+    pub fn get_extradata(&self) -> Option<Arc<Vec<u8>>> {
         if let Some(ref vec) = self.extradata { return Some(vec.clone()); }
         None
     }
@@ -517,11 +563,11 @@ impl NACodecInfo {
         if let NACodecTypeInfo::Audio(_) = self.properties { return true; }
         false
     }
-    pub fn new_dummy() -> Rc<Self> {
-        Rc::new(DUMMY_CODEC_INFO)
+    pub fn new_dummy() -> Arc<Self> {
+        Arc::new(DUMMY_CODEC_INFO)
     }
-    pub fn replace_info(&self, p: NACodecTypeInfo) -> Rc<Self> {
-        Rc::new(NACodecInfo { name: self.name, properties: p, extradata: self.extradata.clone() })
+    pub fn replace_info(&self, p: NACodecTypeInfo) -> Arc<Self> {
+        Arc::new(NACodecInfo { name: self.name, properties: p, extradata: self.extradata.clone() })
     }
 }
 
@@ -550,7 +596,7 @@ pub enum NAValue {
     Int(i32),
     Long(i64),
     String(String),
-    Data(Rc<Vec<u8>>),
+    Data(Arc<Vec<u8>>),
 }
 
 #[derive(Debug,Clone,Copy,PartialEq)]
@@ -601,7 +647,7 @@ impl NATimeInfo {
 pub struct NAFrame {
     ts:             NATimeInfo,
     buffer:         NABufferType,
-    info:           Rc<NACodecInfo>,
+    info:           NACodecInfoRef,
     ftype:          FrameType,
     key:            bool,
     options:        HashMap<String, NAValue>,
@@ -622,12 +668,12 @@ impl NAFrame {
     pub fn new(ts:             NATimeInfo,
                ftype:          FrameType,
                keyframe:       bool,
-               info:           Rc<NACodecInfo>,
+               info:           NACodecInfoRef,
                options:        HashMap<String, NAValue>,
                buffer:         NABufferType) -> Self {
         NAFrame { ts: ts, buffer: buffer, info: info, ftype: ftype, key: keyframe, options: options }
     }
-    pub fn get_info(&self) -> Rc<NACodecInfo> { self.info.clone() }
+    pub fn get_info(&self) -> NACodecInfoRef { self.info.clone() }
     pub fn get_frame_type(&self) -> FrameType { self.ftype }
     pub fn is_keyframe(&self) -> bool { self.key }
     pub fn set_frame_type(&mut self, ftype: FrameType) { self.ftype = ftype; }
@@ -688,7 +734,7 @@ pub struct NAStream {
     media_type:     StreamType,
     id:             u32,
     num:            usize,
-    info:           Rc<NACodecInfo>,
+    info:           NACodecInfoRef,
     tb_num:         u32,
     tb_den:         u32,
 }
@@ -711,12 +757,12 @@ pub fn reduce_timebase(tb_num: u32, tb_den: u32) -> (u32, u32) {
 impl NAStream {
     pub fn new(mt: StreamType, id: u32, info: NACodecInfo, tb_num: u32, tb_den: u32) -> Self {
         let (n, d) = reduce_timebase(tb_num, tb_den);
-        NAStream { media_type: mt, id: id, num: 0, info: Rc::new(info), tb_num: n, tb_den: d }
+        NAStream { media_type: mt, id: id, num: 0, info: info.into_ref(), tb_num: n, tb_den: d }
     }
     pub fn get_id(&self) -> u32 { self.id }
     pub fn get_num(&self) -> usize { self.num }
     pub fn set_num(&mut self, num: usize) { self.num = num; }
-    pub fn get_info(&self) -> Rc<NACodecInfo> { self.info.clone() }
+    pub fn get_info(&self) -> NACodecInfoRef { self.info.clone() }
     pub fn get_timebase(&self) -> (u32, u32) { (self.tb_num, self.tb_den) }
     pub fn set_timebase(&mut self, tb_num: u32, tb_den: u32) {
         let (n, d) = reduce_timebase(tb_num, tb_den);
@@ -772,12 +818,12 @@ impl fmt::Display for NAPacket {
 }
 
 pub trait FrameFromPacket {
-    fn new_from_pkt(pkt: &NAPacket, info: Rc<NACodecInfo>, buf: NABufferType) -> NAFrame;
+    fn new_from_pkt(pkt: &NAPacket, info: NACodecInfoRef, buf: NABufferType) -> NAFrame;
     fn fill_timestamps(&mut self, pkt: &NAPacket);
 }
 
 impl FrameFromPacket for NAFrame {
-    fn new_from_pkt(pkt: &NAPacket, info: Rc<NACodecInfo>, buf: NABufferType) -> NAFrame {
+    fn new_from_pkt(pkt: &NAPacket, info: NACodecInfoRef, buf: NABufferType) -> NAFrame {
         NAFrame::new(pkt.ts, FrameType::Other, pkt.keyframe, info, HashMap::new(), buf)
     }
     fn fill_timestamps(&mut self, pkt: &NAPacket) {