core/reorder: simplify I/P/B reorderer
[nihav.git] / nihav-core / src / reorder.rs
1 use std::mem::swap;
2 pub use crate::frame::{FrameType, NAFrameRef};
3
4 pub trait FrameReorderer {
5 fn add_frame(&mut self, fref: NAFrameRef) -> bool;
6 fn get_frame(&mut self) -> Option<NAFrameRef>;
7 fn flush(&mut self);
8 fn get_last_frames(&mut self) -> Option<NAFrameRef>;
9 }
10
11 pub struct NoReorderer {
12 fref: Option<NAFrameRef>,
13 }
14
15 impl NoReorderer {
16 pub fn new() -> Self {
17 Self { fref: None }
18 }
19 }
20
21 impl FrameReorderer for NoReorderer {
22 fn add_frame(&mut self, fref: NAFrameRef) -> bool {
23 if self.fref.is_none() {
24 self.fref = Some(fref);
25 true
26 } else {
27 false
28 }
29 }
30 fn get_frame(&mut self) -> Option<NAFrameRef> {
31 let mut ret = None;
32 swap(&mut ret, &mut self.fref);
33 ret
34 }
35 fn flush(&mut self) { self.fref = None; }
36 fn get_last_frames(&mut self) -> Option<NAFrameRef> { None }
37 }
38
39 #[derive(Default)]
40 pub struct IPBReorderer {
41 rframe: Option<NAFrameRef>,
42 bframe: Option<NAFrameRef>,
43 }
44
45 impl IPBReorderer {
46 pub fn new() -> Self { Self::default() }
47 }
48
49 impl FrameReorderer for IPBReorderer {
50 fn add_frame(&mut self, fref: NAFrameRef) -> bool {
51 if self.rframe.is_some() && self.bframe.is_some() { return false; }
52 let is_b = fref.get_frame_type() == FrameType::B;
53 if is_b && self.bframe.is_some() { return false; }
54 if is_b {
55 self.bframe = Some(fref);
56 } else {
57 std::mem::swap(&mut self.bframe, &mut self.rframe);
58 self.rframe = Some(fref);
59 }
60 true
61 }
62 fn get_frame(&mut self) -> Option<NAFrameRef> {
63 let mut ret = None;
64 if self.bframe.is_some() {
65 std::mem::swap(&mut ret, &mut self.bframe);
66 }
67 ret
68 }
69 fn flush(&mut self) {
70 self.rframe = None;
71 self.bframe = None;
72 }
73 fn get_last_frames(&mut self) -> Option<NAFrameRef> {
74 let mut ret = None;
75 if self.bframe.is_some() {
76 std::mem::swap(&mut ret, &mut self.bframe);
77 } else if self.rframe.is_some() {
78 std::mem::swap(&mut ret, &mut self.rframe);
79 }
80 ret
81 }
82 }
83