diff options
author | Kostya Shishkov <kostya.shishkov@gmail.com> | 2019-11-12 18:48:10 +0100 |
---|---|---|
committer | Kostya Shishkov <kostya.shishkov@gmail.com> | 2019-11-12 18:48:10 +0100 |
commit | ca8452f0b03bdf2c416eeee51ba59a8c9cd8c502 (patch) | |
tree | d53164519b2c98ba61514f1278ecb6d0335d5d36 /nihav-core/src/reorder.rs | |
parent | f18bba90acb625ff6bdabc9a2ad7c68bd40e3313 (diff) | |
download | nihav-ca8452f0b03bdf2c416eeee51ba59a8c9cd8c502.tar.gz |
core: add frame reordering functionality
Diffstat (limited to 'nihav-core/src/reorder.rs')
-rw-r--r-- | nihav-core/src/reorder.rs | 91 |
1 files changed, 91 insertions, 0 deletions
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<NAFrameRef>; + fn flush(&mut self); + fn get_last_frames(&mut self) -> Option<NAFrameRef>; +} + +pub struct NoReorderer { + fref: Option<NAFrameRef>, +} + +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<NAFrameRef> { + 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<NAFrameRef> { None } +} + +pub struct IPBReorderer { + frames: Vec<NAFrameRef>, + 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<NAFrameRef> { + 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<NAFrameRef> { + self.get_frame() + } +} + |