X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-core%2Fsrc%2Fframe.rs;h=145bd2a23dc909c04f4187ba7a0fd37914e9ffc6;hb=98c6f2f05967e79b7d946c908d1198c108704293;hp=f08d1a10eb30dc73b41ad4d635df138a3aa9880f;hpb=7673d49ae4752f68a4e78c7bb861bc73d8182407;p=nihav.git diff --git a/nihav-core/src/frame.rs b/nihav-core/src/frame.rs index f08d1a1..145bd2a 100644 --- a/nihav-core/src/frame.rs +++ b/nihav-core/src/frame.rs @@ -1,6 +1,6 @@ //! Packets and decoded frames functionality. use std::cmp::max; -use std::collections::HashMap; +//use std::collections::HashMap; use std::fmt; use std::sync::Arc; pub use crate::formats::*; @@ -46,13 +46,13 @@ impl fmt::Display for NAAudioInfo { #[derive(Clone,Copy,PartialEq)] pub struct NAVideoInfo { /// Picture width. - width: usize, + pub width: usize, /// Picture height. - height: usize, + pub height: usize, /// Picture is stored downside up. - flipped: bool, + pub flipped: bool, /// Picture pixel format. - format: NAPixelFormaton, + pub format: NAPixelFormaton, } impl NAVideoInfo { @@ -197,6 +197,7 @@ pub struct NAAudioBuffer { data: NABufferRef>, offs: Vec, stride: usize, + step: usize, chmap: NAChannelMap, len: usize, } @@ -209,6 +210,8 @@ impl NAAudioBuffer { } /// Returns the distance between the start of one channel and the next one. pub fn get_stride(&self) -> usize { self.stride } + /// Returns the distance between the samples in one channel. + pub fn get_step(&self) -> usize { self.step } /// Returns audio format information. pub fn get_info(&self) -> NAAudioInfo { self.info } /// Returns channel map. @@ -223,7 +226,7 @@ impl NAAudioBuffer { data.clone_from(self.data.as_ref()); let mut offs: Vec = Vec::with_capacity(self.offs.len()); offs.clone_from(&self.offs); - NAAudioBuffer { info: self.info, data: NABufferRef::new(data), offs, chmap: self.get_chmap().clone(), len: self.len, stride: self.stride } + NAAudioBuffer { info: self.info, data: NABufferRef::new(data), offs, chmap: self.get_chmap().clone(), len: self.len, stride: self.stride, step: self.step } } /// Return the length of frame in samples. pub fn get_length(&self) -> usize { self.len } @@ -233,7 +236,7 @@ impl NAAudioBuffer { /// Constructs a new `NAAudioBuffer` instance. pub fn new_from_buf(info: NAAudioInfo, data: NABufferRef>, chmap: NAChannelMap) -> Self { let len = data.len(); - NAAudioBuffer { info, data, chmap, offs: Vec::new(), len, stride: 0 } + NAAudioBuffer { info, data, chmap, offs: Vec::new(), len, stride: 0, step: 0 } } } @@ -355,6 +358,17 @@ impl NABufferType { _ => 0, } } + /// Returns the distance between two samples in one channel. + pub fn get_audio_step(&self) -> usize { + match *self { + NABufferType::AudioU8(ref ab) => ab.get_step(), + NABufferType::AudioI16(ref ab) => ab.get_step(), + NABufferType::AudioI32(ref ab) => ab.get_step(), + NABufferType::AudioF32(ref ab) => ab.get_step(), + NABufferType::AudioPacked(ref ab) => ab.get_step(), + _ => 0, + } + } /// Returns reference to 8-bit (or packed) audio buffer. pub fn get_abuf_u8(&self) -> Option> { match *self { @@ -562,18 +576,29 @@ pub fn alloc_video_buffer(vinfo: NAVideoInfo, align: u8) -> Result Result { let mut offs: Vec = Vec::new(); - if ainfo.format.is_planar() || (ainfo.channels == 1 && (ainfo.format.get_bits() % 8) == 0) { + if ainfo.format.is_planar() || ((ainfo.format.get_bits() % 8) == 0) { let len = nsamples.checked_mul(ainfo.channels as usize); if len == None { return Err(AllocatorError::TooLargeDimensions); } let length = len.unwrap(); - let stride = nsamples; - for i in 0..ainfo.channels { - offs.push((i as usize) * stride); + let stride; + let step; + if ainfo.format.is_planar() { + stride = nsamples; + step = 1; + for i in 0..ainfo.channels { + offs.push((i as usize) * stride); + } + } else { + stride = 1; + step = ainfo.channels as usize; + for i in 0..ainfo.channels { + offs.push(i as usize); + } } if ainfo.format.is_float() { if ainfo.format.get_bits() == 32 { let data: Vec = vec![0.0; length]; - let buf: NAAudioBuffer = NAAudioBuffer { data: NABufferRef::new(data), info: ainfo, offs, chmap, len: nsamples, stride }; + let buf: NAAudioBuffer = NAAudioBuffer { data: NABufferRef::new(data), info: ainfo, offs, chmap, len: nsamples, stride, step }; Ok(NABufferType::AudioF32(buf)) } else { Err(AllocatorError::TooLargeDimensions) @@ -581,11 +606,11 @@ pub fn alloc_audio_buffer(ainfo: NAAudioInfo, nsamples: usize, chmap: NAChannelM } else { if ainfo.format.get_bits() == 8 && !ainfo.format.is_signed() { let data: Vec = vec![0; length]; - let buf: NAAudioBuffer = NAAudioBuffer { data: NABufferRef::new(data), info: ainfo, offs, chmap, len: nsamples, stride }; + let buf: NAAudioBuffer = NAAudioBuffer { data: NABufferRef::new(data), info: ainfo, offs, chmap, len: nsamples, stride, step }; Ok(NABufferType::AudioU8(buf)) } else if ainfo.format.get_bits() == 16 && ainfo.format.is_signed() { let data: Vec = vec![0; length]; - let buf: NAAudioBuffer = NAAudioBuffer { data: NABufferRef::new(data), info: ainfo, offs, chmap, len: nsamples, stride }; + let buf: NAAudioBuffer = NAAudioBuffer { data: NABufferRef::new(data), info: ainfo, offs, chmap, len: nsamples, stride, step }; Ok(NABufferType::AudioI16(buf)) } else { Err(AllocatorError::TooLargeDimensions) @@ -596,7 +621,7 @@ pub fn alloc_audio_buffer(ainfo: NAAudioInfo, nsamples: usize, chmap: NAChannelM if len == None { return Err(AllocatorError::TooLargeDimensions); } let length = ainfo.format.get_audio_size(len.unwrap() as u64); let data: Vec = vec![0; length]; - let buf: NAAudioBuffer = NAAudioBuffer { data: NABufferRef::new(data), info: ainfo, offs, chmap, len: nsamples, stride: 0 }; + let buf: NAAudioBuffer = NAAudioBuffer { data: NABufferRef::new(data), info: ainfo, offs, chmap, len: nsamples, stride: 0, step: 0 }; Ok(NABufferType::AudioPacked(buf)) } } @@ -837,11 +862,16 @@ impl fmt::Display for FrameType { /// Timestamp information. #[derive(Debug,Clone,Copy)] pub struct NATimeInfo { - pts: Option, - dts: Option, - duration: Option, - tb_num: u32, - tb_den: u32, + /// Presentation timestamp. + pub pts: Option, + /// Decode timestamp. + pub dts: Option, + /// Duration (in timebase units). + pub duration: Option, + /// Timebase numerator. + pub tb_num: u32, + /// Timebase denominator. + pub tb_den: u32, } impl NATimeInfo { @@ -911,13 +941,17 @@ impl NATimeInfo { #[allow(dead_code)] #[derive(Clone)] pub struct NAFrame { - ts: NATimeInfo, - id: i64, - buffer: NABufferType, - info: NACodecInfoRef, - ftype: FrameType, - key: bool, - options: HashMap, + /// Frame timestamp. + pub ts: NATimeInfo, + /// Frame ID. + pub id: i64, + buffer: NABufferType, + info: NACodecInfoRef, + /// Frame type. + pub frame_type: FrameType, + /// Keyframe flag. + pub key: bool, +// options: HashMap, } /// A specialised type for reference-counted `NAFrame`. @@ -938,18 +972,18 @@ impl NAFrame { ftype: FrameType, keyframe: bool, info: NACodecInfoRef, - options: HashMap, + /*options: HashMap,*/ buffer: NABufferType) -> Self { - NAFrame { ts, id: 0, buffer, info, ftype, key: keyframe, options } + NAFrame { ts, id: 0, buffer, info, frame_type: ftype, key: keyframe/*, options*/ } } /// Returns frame format information. pub fn get_info(&self) -> NACodecInfoRef { self.info.clone() } /// Returns frame type. - pub fn get_frame_type(&self) -> FrameType { self.ftype } + pub fn get_frame_type(&self) -> FrameType { self.frame_type } /// Reports whether the frame is a keyframe. pub fn is_keyframe(&self) -> bool { self.key } /// Sets new frame type. - pub fn set_frame_type(&mut self, ftype: FrameType) { self.ftype = ftype; } + pub fn set_frame_type(&mut self, ftype: FrameType) { self.frame_type = ftype; } /// Sets keyframe flag. pub fn set_keyframe(&mut self, key: bool) { self.key = key; } /// Returns frame timestamp. @@ -976,11 +1010,16 @@ impl NAFrame { /// Converts current instance into a reference-counted one. pub fn into_ref(self) -> NAFrameRef { Arc::new(self) } + + /// Creates new frame with metadata from `NAPacket`. + pub fn new_from_pkt(pkt: &NAPacket, info: NACodecInfoRef, buf: NABufferType) -> NAFrame { + NAFrame::new(pkt.ts, FrameType::Other, pkt.keyframe, info, /*HashMap::new(),*/ buf) + } } impl fmt::Display for NAFrame { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut ostr = format!("frame type {}", self.ftype); + let mut ostr = format!("frame type {}", self.frame_type); if let Some(pts) = self.ts.pts { ostr = format!("{} pts {}", ostr, pts); } if let Some(dts) = self.ts.dts { ostr = format!("{} dts {}", ostr, dts); } if let Some(dur) = self.ts.duration { ostr = format!("{} duration {}", ostr, dur); } @@ -1021,12 +1060,15 @@ impl fmt::Display for StreamType { #[allow(dead_code)] #[derive(Clone)] pub struct NAStream { - media_type: StreamType, - id: u32, - num: usize, - info: NACodecInfoRef, - tb_num: u32, - tb_den: u32, + media_type: StreamType, + /// Stream ID. + pub id: u32, + num: usize, + info: NACodecInfoRef, + /// Timebase numerator. + pub tb_num: u32, + /// Timebase denominator. + pub tb_den: u32, } /// A specialised reference-counted `NAStream` type. @@ -1085,10 +1127,12 @@ impl fmt::Display for NAStream { /// Packet with compressed data. #[allow(dead_code)] pub struct NAPacket { - stream: NAStreamRef, - ts: NATimeInfo, - buffer: NABufferRef>, - keyframe: bool, + stream: NAStreamRef, + /// Packet timestamp. + pub ts: NATimeInfo, + buffer: NABufferRef>, + /// Keyframe flag. + pub keyframe: bool, // options: HashMap>, } @@ -1130,21 +1174,3 @@ impl fmt::Display for NAPacket { write!(f, "{}", ostr) } } - -/// A trait for creating `NAFrame` using information from `NAPacket`. -pub trait FrameFromPacket { - /// Creates new frame with metadata from `NAPacket`. - fn new_from_pkt(pkt: &NAPacket, info: NACodecInfoRef, buf: NABufferType) -> NAFrame; - /// Sets frame timestamp from `NAPacket`. - fn fill_timestamps(&mut self, pkt: &NAPacket); -} - -impl FrameFromPacket for 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) { - self.ts = pkt.get_time_information(); - } -} -