From ca8452f0b03bdf2c416eeee51ba59a8c9cd8c502 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Tue, 12 Nov 2019 18:48:10 +0100 Subject: [PATCH] core: add frame reordering functionality --- nihav-core/src/lib.rs | 1 + nihav-core/src/reorder.rs | 91 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 nihav-core/src/reorder.rs diff --git a/nihav-core/src/lib.rs b/nihav-core/src/lib.rs index 4b6729c..75dbc78 100644 --- a/nihav-core/src/lib.rs +++ b/nihav-core/src/lib.rs @@ -17,6 +17,7 @@ pub mod refs; pub mod register; #[allow(clippy::unreadable_literal)] pub mod detect; +pub mod reorder; pub mod scale; #[cfg(feature="dsp")] diff --git a/nihav-core/src/reorder.rs b/nihav-core/src/reorder.rs new file mode 100644 index 0000000..54c0288 --- /dev/null +++ b/nihav-core/src/reorder.rs @@ -0,0 +1,91 @@ +use std::mem::swap; +pub use crate::frame::{FrameType, NAFrameRef}; + +pub trait FrameReorderer { + fn add_frame(&mut self, fref: NAFrameRef) -> bool; + fn get_frame(&mut self) -> Option; + fn flush(&mut self); + fn get_last_frames(&mut self) -> Option; +} + +pub struct NoReorderer { + fref: Option, +} + +impl NoReorderer { + pub fn new() -> Self { + Self { fref: None } + } +} + +impl FrameReorderer for NoReorderer { + fn add_frame(&mut self, fref: NAFrameRef) -> bool { + if self.fref.is_none() { + self.fref = Some(fref); + true + } else { + false + } + } + fn get_frame(&mut self) -> Option { + let mut ret = None; + swap(&mut ret, &mut self.fref); + ret + } + fn flush(&mut self) { self.fref = None; } + fn get_last_frames(&mut self) -> Option { None } +} + +pub struct IPBReorderer { + frames: Vec, + max_depth: usize, + last_ft: FrameType, +} + +impl IPBReorderer { + pub fn new(max_depth: usize) -> Self { + Self { + frames: Vec::with_capacity(max_depth), + max_depth, + last_ft: FrameType::Other, + } + } +} + +impl FrameReorderer for IPBReorderer { + fn add_frame(&mut self, fref: NAFrameRef) -> bool { + if self.frames.len() < self.max_depth { + let cur_ft = fref.get_frame_type(); + if cur_ft != FrameType::B { + self.frames.push(fref); + self.last_ft = cur_ft; + } else { + let pframe = self.frames.pop(); + if pframe.is_some() { + self.frames.push(fref); + self.frames.push(pframe.unwrap()); + } else { + self.last_ft = cur_ft; + } + } + true + } else { + false + } + } + fn get_frame(&mut self) -> Option { + if !self.frames.is_empty() { + Some(self.frames.remove(0)) + } else { + None + } + } + fn flush(&mut self) { + self.frames.clear(); + self.last_ft = FrameType::Other; + } + fn get_last_frames(&mut self) -> Option { + self.get_frame() + } +} + -- 2.30.2