aboutsummaryrefslogtreecommitdiffstats
path: root/nihav-core/src/reorder.rs
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2019-11-12 18:48:10 +0100
committerKostya Shishkov <kostya.shishkov@gmail.com>2019-11-12 18:48:10 +0100
commitca8452f0b03bdf2c416eeee51ba59a8c9cd8c502 (patch)
treed53164519b2c98ba61514f1278ecb6d0335d5d36 /nihav-core/src/reorder.rs
parentf18bba90acb625ff6bdabc9a2ad7c68bd40e3313 (diff)
downloadnihav-ca8452f0b03bdf2c416eeee51ba59a8c9cd8c502.tar.gz
core: add frame reordering functionality
Diffstat (limited to 'nihav-core/src/reorder.rs')
-rw-r--r--nihav-core/src/reorder.rs91
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()
+ }
+}
+