core/frame: add a function for assigning packets to other streams
[nihav.git] / nihav-core / src / frame.rs
index 145bd2a23dc909c04f4187ba7a0fd37914e9ffc6..5b090bb942841e6006beceec1a94591c07b9389b 100644 (file)
@@ -2,7 +2,7 @@
 use std::cmp::max;
 //use std::collections::HashMap;
 use std::fmt;
-use std::sync::Arc;
+pub use std::sync::Arc;
 pub use crate::formats::*;
 pub use crate::refs::*;
 
@@ -182,6 +182,21 @@ impl<T: Clone> NAVideoBuffer<T> {
     pub fn into_ref(self) -> NABufferRef<Self> {
         NABufferRef::new(self)
     }
+
+    fn print_contents(&self, datatype: &str) {
+        println!("{} video buffer size {}", datatype, self.data.len());
+        println!(" format {}", self.info);
+        print!(" offsets:");
+        for off in self.offs.iter() {
+            print!(" {}", *off);
+        }
+        println!();
+        print!(" strides:");
+        for stride in self.strides.iter() {
+            print!(" {}", *stride);
+        }
+        println!();
+    }
 }
 
 /// A specialised type for reference-counted `NAVideoBuffer`.
@@ -230,6 +245,17 @@ impl<T: Clone> NAAudioBuffer<T> {
     }
     /// Return the length of frame in samples.
     pub fn get_length(&self) -> usize { self.len }
+
+    fn print_contents(&self, datatype: &str) {
+        println!("Audio buffer with {} data, stride {}, step {}", datatype, self.stride, self.step);
+        println!(" format {}", self.info);
+        println!(" channel map {}", self.chmap);
+        print!(" offsets:");
+        for off in self.offs.iter() {
+            print!(" {}", *off);
+        }
+        println!();
+    }
 }
 
 impl NAAudioBuffer<u8> {
@@ -277,6 +303,7 @@ impl NABufferType {
             NABufferType::VideoPacked(ref vb) => vb.get_offset(idx),
             NABufferType::AudioU8(ref ab)     => ab.get_offset(idx),
             NABufferType::AudioI16(ref ab)    => ab.get_offset(idx),
+            NABufferType::AudioI32(ref ab)    => ab.get_offset(idx),
             NABufferType::AudioF32(ref ab)    => ab.get_offset(idx),
             NABufferType::AudioPacked(ref ab) => ab.get_offset(idx),
             _ => 0,
@@ -398,6 +425,22 @@ impl NABufferType {
             _ => None,
         }
     }
+    /// Prints internal buffer layout.
+    pub fn print_buffer_metadata(&self) {
+        match *self {
+            NABufferType::Video(ref buf)        => buf.print_contents("8-bit"),
+            NABufferType::Video16(ref buf)      => buf.print_contents("16-bit"),
+            NABufferType::Video32(ref buf)      => buf.print_contents("32-bit"),
+            NABufferType::VideoPacked(ref buf)  => buf.print_contents("packed"),
+            NABufferType::AudioU8(ref buf)      => buf.print_contents("8-bit unsigned integer"),
+            NABufferType::AudioI16(ref buf)     => buf.print_contents("16-bit integer"),
+            NABufferType::AudioI32(ref buf)     => buf.print_contents("32-bit integer"),
+            NABufferType::AudioF32(ref buf)     => buf.print_contents("32-bit float"),
+            NABufferType::AudioPacked(ref buf)  => buf.print_contents("packed"),
+            NABufferType::Data(ref buf) => { println!("Data buffer, len = {}", buf.len()); },
+            NABufferType::None          => { println!("No buffer"); },
+        };
+    }
 }
 
 const NA_SIMPLE_VFRAME_COMPONENTS: usize = 4;
@@ -1124,6 +1167,18 @@ impl fmt::Display for NAStream {
     }
 }
 
+/// Side data that may accompany demuxed data.
+#[derive(Clone)]
+pub enum NASideData {
+    /// Palette information.
+    ///
+    /// This side data contains a flag signalling that palette has changed since previous time and a reference to the current palette.
+    /// Palette is stored in 8-bit RGBA format.
+    Palette(bool, Arc<[u8; 1024]>),
+    /// Generic user data.
+    UserData(Arc<Vec<u8>>),
+}
+
 /// Packet with compressed data.
 #[allow(dead_code)]
 pub struct NAPacket {
@@ -1134,6 +1189,8 @@ pub struct NAPacket {
     /// Keyframe flag.
     pub keyframe:       bool,
 //    options:        HashMap<String, NAValue<'a>>,
+    /// Packet side data (e.g. palette for paletted formats).
+    pub side_data:      Vec<NASideData>,
 }
 
 impl NAPacket {
@@ -1141,7 +1198,7 @@ impl NAPacket {
     pub fn new(str: NAStreamRef, ts: NATimeInfo, kf: bool, vec: Vec<u8>) -> Self {
 //        let mut vec: Vec<u8> = Vec::new();
 //        vec.resize(size, 0);
-        NAPacket { stream: str, ts, keyframe: kf, buffer: NABufferRef::new(vec) }
+        NAPacket { stream: str, ts, keyframe: kf, buffer: NABufferRef::new(vec), side_data: Vec::new() }
     }
     /// Returns information about the stream packet belongs to.
     pub fn get_stream(&self) -> NAStreamRef { self.stream.clone() }
@@ -1157,6 +1214,13 @@ impl NAPacket {
     pub fn is_keyframe(&self) -> bool { self.keyframe }
     /// Returns a reference to packet data.
     pub fn get_buffer(&self) -> NABufferRef<Vec<u8>> { self.buffer.clone() }
+    /// Adds side data for a packet.
+    pub fn add_side_data(&mut self, side_data: NASideData) { self.side_data.push(side_data); }
+    /// Assigns packet to a new stream.
+    pub fn reassign(&mut self, str: NAStreamRef, ts: NATimeInfo) {
+        self.stream = str;
+        self.ts = ts;
+    }
 }
 
 impl Drop for NAPacket {