diff options
-rw-r--r-- | mtree-test/src/bin/decode.rs | 47 | ||||
-rw-r--r-- | mtree-test/src/bin/encode.rs | 95 | ||||
-rw-r--r-- | mtree-test/src/lib.rs | 73 |
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>, } |