}
impl<T: Clone> NAVideoBuffer<T> {
+ /// Constructs video buffer from the provided components.
+ pub fn from_raw_parts(info: NAVideoInfo, data: NABufferRef<Vec<T>>, offs: Vec<usize>, strides: Vec<usize>) -> Self {
+ Self { info, data, offs, strides }
+ }
/// Returns the component offset (0 for all unavailable offsets).
pub fn get_offset(&self, idx: usize) -> usize {
if idx >= self.offs.len() { 0 }
}
/// Return the length of frame in samples.
pub fn get_length(&self) -> usize { self.len }
+ /// Truncates buffer length if possible.
+ ///
+ /// In case when new length is larger than old length nothing is done.
+ pub fn truncate(&mut self, new_len: usize) {
+ self.len = self.len.min(new_len);
+ }
fn print_contents(&self, datatype: &str) {
println!("Audio buffer with {} data, stride {}, step {}", datatype, self.stride, self.step);
let data: Vec<i16> = vec![0; length];
let buf: NAAudioBuffer<i16> = NAAudioBuffer { data: NABufferRef::new(data), info: ainfo, offs, chmap, len: nsamples, stride, step };
Ok(NABufferType::AudioI16(buf))
+ } else if ainfo.format.get_bits() == 32 && ainfo.format.is_signed() {
+ let data: Vec<i32> = vec![0; length];
+ let buf: NAAudioBuffer<i32> = NAAudioBuffer { data: NABufferRef::new(data), info: ainfo, offs, chmap, len: nsamples, stride, step };
+ Ok(NABufferType::AudioI32(buf))
} else {
Err(AllocatorError::TooLargeDimensions)
}
}
/// Creates a clone of current buffer.
-pub fn copy_buffer(buf: NABufferType) -> NABufferType {
+pub fn copy_buffer(buf: &NABufferType) -> NABufferType {
buf.clone()
}
pub fn set_duration(&mut self, dur: Option<u64>) { self.duration = dur; }
/// Converts time in given scale into timestamp in given base.
+ #[allow(clippy::collapsible_if)]
pub fn time_to_ts(time: u64, base: u64, tb_num: u32, tb_den: u32) -> u64 {
let tb_num = u64::from(tb_num);
let tb_den = u64::from(tb_den);
- let tmp = time.checked_mul(tb_num);
+ let tmp = time.checked_mul(tb_den);
if let Some(tmp) = tmp {
- tmp / base / tb_den
+ tmp / base / tb_num
} else {
- let tmp = time.checked_mul(tb_num);
- if let Some(tmp) = tmp {
- tmp / base / tb_den
+ if tb_num < base {
+ let coarse = time / tb_num;
+ if let Some(tmp) = coarse.checked_mul(tb_den) {
+ tmp / base
+ } else {
+ (coarse / base) * tb_den
+ }
} else {
let coarse = time / base;
- let tmp = coarse.checked_mul(tb_num);
- if let Some(tmp) = tmp {
- tmp / tb_den
+ if let Some(tmp) = coarse.checked_mul(tb_den) {
+ tmp / tb_num
} else {
- (coarse / tb_den) * tb_num
+ (coarse / tb_num) * tb_den
}
}
}
}
}
}
+ fn get_cur_ts(&self) -> u64 { self.pts.unwrap_or_else(|| self.dts.unwrap_or(0)) }
+ fn get_cur_millis(&self) -> u64 {
+ let ts = self.get_cur_ts();
+ Self::ts_to_time(ts, 1000, self.tb_num, self.tb_den)
+ }
+ /// Checks whether the current time information is earler than provided reference time.
+ pub fn less_than(&self, time: NATimePoint) -> bool {
+ if self.pts.is_none() && self.dts.is_none() {
+ return true;
+ }
+ match time {
+ NATimePoint::PTS(rpts) => self.get_cur_ts() < rpts,
+ NATimePoint::Milliseconds(ms) => self.get_cur_millis() < ms,
+ NATimePoint::None => false,
+ }
+ }
+ /// Checks whether the current time information is the same as provided reference time.
+ pub fn equal(&self, time: NATimePoint) -> bool {
+ if self.pts.is_none() && self.dts.is_none() {
+ return time == NATimePoint::None;
+ }
+ match time {
+ NATimePoint::PTS(rpts) => self.get_cur_ts() == rpts,
+ NATimePoint::Milliseconds(ms) => self.get_cur_millis() == ms,
+ NATimePoint::None => false,
+ }
+ }
}
/// Time information for specifying durations or seek positions.
Milliseconds(u64),
/// Stream timestamp.
PTS(u64),
+ /// No time information present.
+ None,
+}
+
+impl Default for NATimePoint {
+ fn default() -> Self {
+ NATimePoint::None
+ }
}
impl fmt::Display for NATimePoint {
NATimePoint::PTS(pts) => {
write!(f, "{}pts", pts)
},
+ NATimePoint::None => {
+ write!(f, "none")
+ },
}
}
}
let ret = parts.next().unwrap().parse::<u64>();
if ret.is_err() { return Err(FormatParseError {}); }
let seconds = ret.unwrap();
- if seconds >= 60 { return Err(FormatParseError {}); }
+ if mins.is_some() && seconds >= 60 { return Err(FormatParseError {}); }
let millis = if let Some(val) = parts.next() {
let mut mval = 0;
let mut base = 0;
pub tb_num: u32,
/// Timebase denominator.
pub tb_den: u32,
+ /// Duration in timebase units (zero if not available).
+ pub duration: u64,
}
/// A specialised reference-counted `NAStream` type.
pub type NAStreamRef = Arc<NAStream>;
/// Downscales the timebase by its greatest common denominator.
+#[allow(clippy::comparison_chain)]
pub fn reduce_timebase(tb_num: u32, tb_den: u32) -> (u32, u32) {
if tb_num == 0 { return (tb_num, tb_den); }
if (tb_den % tb_num) == 0 { return (1, tb_den / tb_num); }
impl NAStream {
/// Constructs a new `NAStream` instance.
- pub fn new(mt: StreamType, id: u32, info: NACodecInfo, tb_num: u32, tb_den: u32) -> Self {
+ pub fn new(mt: StreamType, id: u32, info: NACodecInfo, tb_num: u32, tb_den: u32, duration: u64) -> Self {
let (n, d) = reduce_timebase(tb_num, tb_den);
- NAStream { media_type: mt, id, num: 0, info: info.into_ref(), tb_num: n, tb_den: d }
+ NAStream { media_type: mt, id, num: 0, info: info.into_ref(), tb_num: n, tb_den: d, duration }
}
/// Returns stream id.
pub fn get_id(&self) -> u32 { self.id }
self.tb_num = n;
self.tb_den = d;
}
+ /// Returns stream duration.
+ pub fn get_duration(&self) -> usize { self.num }
/// Converts current instance into a reference-counted one.
pub fn into_ref(self) -> NAStreamRef { Arc::new(self) }
}