aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mtree-test/src/bin/decode.rs47
-rw-r--r--mtree-test/src/bin/encode.rs95
-rw-r--r--mtree-test/src/lib.rs73
3 files changed, 192 insertions, 23 deletions
diff --git a/mtree-test/src/bin/decode.rs b/mtree-test/src/bin/decode.rs
index 6ff2cb3..0fc8ba4 100644
--- a/mtree-test/src/bin/decode.rs
+++ b/mtree-test/src/bin/decode.rs
@@ -1,6 +1,7 @@
use framework::{BitstreamFilter, bitstream_filter_main};
use glam::{I16Vec2, i16vec2};
-use std::io::Result;
+use mtree_test::{BLOCK_SIZE, Frame, LastFrames, frame_to_frame_rect_copy};
+use std::{collections::VecDeque, io::Result};
fn main() -> Result<()> {
bitstream_filter_main::<Dec>()
@@ -8,6 +9,7 @@ fn main() -> Result<()> {
struct Dec {
res: I16Vec2,
+ last: LastFrames,
}
impl BitstreamFilter for Dec {
const INPUT_CODEC_ID: &str = "V_VCEMTREE";
@@ -16,9 +18,50 @@ impl BitstreamFilter for Dec {
fn new(width: u32, height: u32) -> Self {
Self {
res: i16vec2(width as i16, height as i16),
+ last: LastFrames {
+ frame_offset: 0,
+ frames: VecDeque::new(),
+ },
}
}
fn process_block(&mut self, a: Vec<u8>) -> Vec<u8> {
- a
+ let mut a = a.as_slice();
+ let mut frame = Frame::new(self.res);
+
+ for bx in 0..self.res.x / BLOCK_SIZE {
+ for by in 0..self.res.y / BLOCK_SIZE {
+ let boff = i16vec2(bx * BLOCK_SIZE, by * BLOCK_SIZE);
+ let brect = boff..boff + I16Vec2::splat(BLOCK_SIZE);
+ let kind = a[0];
+ a = &a[1..];
+ if kind == 0 {
+ let size = frame.import_rect(self.res, brect, &a);
+ a = &a[size..];
+ } else {
+ let rframeindex =
+ u64::from_le_bytes([a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]]);
+ a = &a[8..];
+ let offx = i16::from_le_bytes([a[0], a[1]]);
+ a = &a[2..];
+ let offy = i16::from_le_bytes([a[0], a[1]]);
+ a = &a[2..];
+
+ let rframe = &self.last.frames[(rframeindex - self.last.frame_offset) as usize];
+ frame_to_frame_rect_copy(
+ self.res,
+ &mut frame,
+ rframe,
+ I16Vec2::splat(BLOCK_SIZE),
+ boff,
+ i16vec2(offx, offy),
+ );
+ }
+ }
+ }
+
+ self.last.frames.push_back(frame.clone());
+
+ eprintln!("out frame");
+ frame.0
}
}
diff --git a/mtree-test/src/bin/encode.rs b/mtree-test/src/bin/encode.rs
index b37fdf6..3cdb1c8 100644
--- a/mtree-test/src/bin/encode.rs
+++ b/mtree-test/src/bin/encode.rs
@@ -1,14 +1,12 @@
use framework::{BitstreamFilter, bitstream_filter_main};
use glam::{I16Vec2, i16vec2};
-use mtree_test::{AbsRef, Frame};
+use mtree_test::{AbsRef, BLOCK_SIZE, Frame, LastFrames, frame_to_frame_rect_copy};
use std::{collections::VecDeque, io::Result};
fn main() -> Result<()> {
bitstream_filter_main::<Enc>()
}
-const BLOCK_SIZE: i16 = 16;
-
struct Enc {
res: I16Vec2,
last: LastFrames,
@@ -27,18 +25,57 @@ impl BitstreamFilter for Enc {
},
tree: MTree::Leaf(AbsRef {
off: i16vec2(0, 0),
- frame: 0,
+ frame: u64::MAX,
}),
}
}
fn process_block(&mut self, frame: Vec<u8>) -> Vec<u8> {
- let frame = Frame(frame);
+ let mut frame = Frame(frame);
+
+ let mut out = Vec::new();
+ let mut num_refs = 0;
+
+ for bx in 0..self.res.x / BLOCK_SIZE {
+ for by in 0..self.res.y / BLOCK_SIZE {
+ let boff = i16vec2(bx * BLOCK_SIZE, by * BLOCK_SIZE);
+ let r = self.tree.search(self.res, &self.last, &frame, boff);
+
+ let rdist = if r.frame == u64::MAX {
+ u32::MAX
+ } else {
+ distance(
+ self.res,
+ &self.last.frames[(r.frame - self.last.frame_offset) as usize],
+ &frame,
+ r.off,
+ boff,
+ )
+ };
+ if rdist < 1000 {
+ out.push(1);
+ out.extend(r.frame.to_le_bytes());
+ out.extend(r.off.x.to_le_bytes());
+ out.extend(r.off.y.to_le_bytes());
+ frame_to_frame_rect_copy(
+ self.res,
+ &mut frame,
+ &self.last.frames[(r.frame - self.last.frame_offset) as usize],
+ I16Vec2::splat(BLOCK_SIZE),
+ boff,
+ r.off,
+ );
+ num_refs += 1;
+ } else {
+ out.push(0);
+ frame.export_rect(self.res, boff..boff + I16Vec2::splat(BLOCK_SIZE), &mut out);
+ }
+ }
+ }
self.last.frames.push_back(frame);
let frame_index = self.last.frame_offset + self.last.frames.len() as u64 - 1;
for xo in 0..self.res.x - BLOCK_SIZE {
- eprintln!("aaaaaaa {} aaaa", self.tree.depth());
for yo in 0..self.res.y - BLOCK_SIZE {
self.tree.insert(
self.res,
@@ -50,16 +87,12 @@ impl BitstreamFilter for Enc {
)
}
}
+ eprintln!("aaaaaaa {} {num_refs} aaaa", self.tree.depth());
- Vec::new()
+ out
}
}
-struct LastFrames {
- frame_offset: u64,
- frames: VecDeque<Frame>,
-}
-
enum MTree {
Branch(Box<[MTree; 2]>),
Leaf(AbsRef),
@@ -88,7 +121,13 @@ impl MTree {
b[1].insert(res, last, r)
}
}
- MTree::Leaf(l) => *self = MTree::Branch(Box::new([MTree::Leaf(*l), MTree::Leaf(r)])),
+ MTree::Leaf(l) => {
+ if l.frame == u64::MAX {
+ *l = r
+ } else {
+ *self = MTree::Branch(Box::new([MTree::Leaf(*l), MTree::Leaf(r)]))
+ }
+ }
}
}
pub fn search(
@@ -135,14 +174,30 @@ fn distance_absref(res: I16Vec2, last: &LastFrames, a: AbsRef, b: AbsRef) -> u32
fn distance(res: I16Vec2, aframe: &Frame, bframe: &Frame, aoff: I16Vec2, boff: I16Vec2) -> u32 {
let mut diff = 0;
for yo in 0..BLOCK_SIZE {
- for xo in 0..BLOCK_SIZE {
- let off = i16vec2(xo, yo);
- let asample = aframe.get(res, aoff + off);
- let bsample = bframe.get(res, boff + off);
+ // for xo in 0..BLOCK_SIZE {
+ // let off = i16vec2(xo, yo);
+ // let asample = aframe.get(res, aoff + off);
+ // let bsample = bframe.get(res, boff + off);
- diff += asample[0].abs_diff(bsample[0]) as u32;
- diff += asample[1].abs_diff(bsample[1]) as u32;
- diff += asample[2].abs_diff(bsample[2]) as u32;
+ // diff += asample[0].abs_diff(bsample[0]) as u32;
+ // diff += asample[1].abs_diff(bsample[1]) as u32;
+ // diff += asample[2].abs_diff(bsample[2]) as u32;
+ // }
+
+ let aslice = aframe.slice(res, yo + aoff.y, aoff.x..aoff.x + BLOCK_SIZE);
+ let bslice = bframe.slice(res, yo + boff.y, boff.x..boff.x + BLOCK_SIZE);
+
+ for i in 0..BLOCK_SIZE as usize {
+ diff += aslice[0][i].abs_diff(bslice[0][i]) as u32;
+ diff += aslice[0][i].abs_diff(bslice[0][i]) as u32;
+ }
+ for i in 0..BLOCK_SIZE as usize / 2 {
+ diff += aslice[1][i].abs_diff(bslice[1][i]) as u32;
+ diff += aslice[1][i].abs_diff(bslice[1][i]) as u32;
+ }
+ for i in 0..BLOCK_SIZE as usize / 2 {
+ diff += aslice[2][i].abs_diff(bslice[2][i]) as u32;
+ diff += aslice[2][i].abs_diff(bslice[2][i]) as u32;
}
}
diff
diff --git a/mtree-test/src/lib.rs b/mtree-test/src/lib.rs
index 1214cbf..cf55e92 100644
--- a/mtree-test/src/lib.rs
+++ b/mtree-test/src/lib.rs
@@ -1,4 +1,7 @@
-use glam::I16Vec2;
+use glam::{I16Vec2, i16vec2};
+use std::{collections::VecDeque, ops::Range};
+
+pub const BLOCK_SIZE: i16 = 4;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct AbsRef {
@@ -6,8 +9,15 @@ pub struct AbsRef {
pub frame: u64,
}
+#[derive(Clone)]
pub struct Frame(pub Vec<u8>);
+
impl Frame {
+ pub fn new(res: I16Vec2) -> Self {
+ let res = res.as_usizevec2();
+ Self(vec![0; res.x * res.y + 2 * (res.x / 2 * res.y / 2)])
+ }
+
pub fn index(&self, res: I16Vec2, p: I16Vec2) -> [usize; 3] {
let res = res.as_usizevec2();
let p = p.as_usizevec2();
@@ -23,7 +33,68 @@ impl Frame {
ysize + usize + puv.x + puv.y * uvstride,
]
}
+ pub fn slice(&self, res: I16Vec2, y: i16, x: Range<i16>) -> [&[u8]; 3] {
+ let start = self.index(res, i16vec2(x.start, y));
+ let end = self.index(res, i16vec2(x.end, y));
+ [
+ &self.0[start[0]..end[0]],
+ &self.0[start[1]..end[1]],
+ &self.0[start[2]..end[2]],
+ ]
+ }
pub fn get(&self, res: I16Vec2, p: I16Vec2) -> [u8; 3] {
self.index(res, p).map(|i| self.0[i])
}
+
+ pub fn export_rect(&self, res: I16Vec2, r: Range<I16Vec2>, out: &mut Vec<u8>) {
+ for y in r.start.y..r.end.y {
+ let slices = self.slice(res, y, r.start.x..r.end.x);
+ out.extend(slices[0]);
+ out.extend(slices[1]);
+ out.extend(slices[2]);
+ }
+ }
+ pub fn import_rect(&mut self, res: I16Vec2, r: Range<I16Vec2>, mut data: &[u8]) -> usize {
+ let mut off = 0;
+ for y in r.start.y..r.end.y {
+ let start = self.index(res, i16vec2(r.start.x, y));
+ let end = self.index(res, i16vec2(r.end.x, y));
+
+ let mut do_slice = |s: &mut [u8]| {
+ s.copy_from_slice(&data[..s.len()]);
+ data = &data[s.len()..];
+ off += s.len();
+ };
+
+ do_slice(&mut self.0[start[0]..end[0]]);
+ do_slice(&mut self.0[start[1]..end[1]]);
+ do_slice(&mut self.0[start[2]..end[2]]);
+ }
+ off
+ }
+}
+
+pub fn frame_to_frame_rect_copy(
+ res: I16Vec2,
+ aframe: &mut Frame,
+ bframe: &Frame,
+ size: I16Vec2,
+ aoff: I16Vec2,
+ boff: I16Vec2,
+) {
+ for y in size.x..size.y {
+ let astart = aframe.index(res, i16vec2(aoff.x, aoff.y + y));
+ let aend = aframe.index(res, i16vec2(aoff.x + size.x, aoff.y + y));
+ let bstart = bframe.index(res, i16vec2(boff.x, boff.y + y));
+ let bend = bframe.index(res, i16vec2(boff.x + size.x, boff.y + y));
+
+ aframe.0[astart[0]..aend[0]].copy_from_slice(&bframe.0[bstart[0]..bend[0]]);
+ aframe.0[astart[1]..aend[1]].copy_from_slice(&bframe.0[bstart[1]..bend[1]]);
+ aframe.0[astart[2]..aend[2]].copy_from_slice(&bframe.0[bstart[2]..bend[2]]);
+ }
+}
+
+pub struct LastFrames {
+ pub frame_offset: u64,
+ pub frames: VecDeque<Frame>,
}