aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test2/src/decode.rs31
-rw-r--r--test2/src/encode.rs92
-rw-r--r--test2/src/main.rs123
3 files changed, 169 insertions, 77 deletions
diff --git a/test2/src/decode.rs b/test2/src/decode.rs
index 974c6d9..da0538b 100644
--- a/test2/src/decode.rs
+++ b/test2/src/decode.rs
@@ -1,20 +1,43 @@
+use crate::{BLOCK_SIZE, Frame};
use framework::BitstreamFilter;
-use glam::{I16Vec2, i16vec2};
+use glam::{IVec2, ivec2};
pub struct Dec {
- res: I16Vec2,
+ res: IVec2,
+ last: Frame,
}
impl BitstreamFilter for Dec {
const INPUT_CODEC_ID: &str = "V_VCETEST2";
const OUTPUT_CODEC_ID: &str = "V_UNCOMPRESSED";
fn new(width: u32, height: u32) -> Self {
+ let res = ivec2(width as i32, height as i32);
Self {
- res: i16vec2(width as i16, height as i16),
+ res,
+ last: Frame::new(res),
}
}
fn process_block(&mut self, a: Vec<u8>) -> Vec<u8> {
- a
+ let mut buf = a.as_slice();
+ let mut frame = Frame::new(self.res);
+ for by in 0..frame.res.y / BLOCK_SIZE {
+ for bx in 0..frame.res.x / BLOCK_SIZE {
+ let boff = ivec2(bx * BLOCK_SIZE, by * BLOCK_SIZE);
+
+ let reloff = ivec2(buf[0] as i32 - 127, buf[1] as i32 - 127);
+ buf = &buf[2..];
+
+ let roff = reloff + boff;
+
+ Frame::copy_block(&self.last, &mut frame, roff, boff);
+
+ let size = frame.import_block_diff(boff, buf);
+ buf = &buf[size..];
+ }
+ }
+
+ self.last = frame.clone();
+ frame.data
}
}
diff --git a/test2/src/encode.rs b/test2/src/encode.rs
index 54c7a3a..ed091cb 100644
--- a/test2/src/encode.rs
+++ b/test2/src/encode.rs
@@ -1,4 +1,4 @@
-use crate::BLOCK_SIZE;
+use crate::{BLOCK_SIZE, Frame};
use framework::BitstreamFilter;
use glam::{IVec2, ivec2};
@@ -24,12 +24,16 @@ impl BitstreamFilter for Enc {
res: self.res,
};
+ let mut out = Vec::new();
+ let mut oldblock = Vec::new();
+ let mut newblock = Vec::new();
+
for by in 0..frame.res.y / BLOCK_SIZE {
for bx in 0..frame.res.x / BLOCK_SIZE {
let boff = ivec2(bx * BLOCK_SIZE, by * BLOCK_SIZE);
let mut best_d = Frame::compare_block(&frame, &self.last, boff, boff);
- let mut best_off = ivec2(0, 0);
+ let mut best_off = boff;
for granularity in [8, 4, 2, 1] {
for dir in [
@@ -57,83 +61,25 @@ impl BitstreamFilter for Enc {
}
}
- if best_d < 8 * 8 * 20 {
- Frame::copy_block(&self.last, &mut frame, best_off, boff);
- }
- }
- }
-
- self.last = frame.clone();
- frame.data
- }
-}
-
-#[derive(Clone)]
-struct Frame {
- res: IVec2,
- data: Vec<u8>,
-}
-
-impl Frame {
- fn new(res: IVec2) -> Self {
- Frame {
- res,
- data: vec![127; (res.x * res.y + res.x * res.y / 2) as usize],
- }
- }
- fn copy_block(aframe: &Frame, bframe: &mut Frame, aoff: IVec2, boff: IVec2) {
- assert_eq!(aframe.res, bframe.res);
- let res = aframe.res;
-
- // Luma
- for y in 0..BLOCK_SIZE {
- let ay_off = aoff.x + (y + aoff.y) * res.x;
- let by_off = boff.x + (y + boff.y) * res.x;
-
- bframe.data[by_off as usize..(by_off + BLOCK_SIZE) as usize]
- .copy_from_slice(&aframe.data[ay_off as usize..(ay_off + BLOCK_SIZE) as usize]);
- }
-
- // Chroma
- let uvplane_off = res.x * res.y;
-
- for y in 0..BLOCK_SIZE / 2 {
- let ay_off = uvplane_off + (aoff.x & !1) + (y + aoff.y / 2) * res.x;
- let by_off = uvplane_off + (boff.x & !1) + (y + boff.y / 2) * res.x;
-
- bframe.data[by_off as usize..(by_off + BLOCK_SIZE) as usize]
- .copy_from_slice(&aframe.data[ay_off as usize..(ay_off + BLOCK_SIZE) as usize]);
- }
- }
- fn compare_block(aframe: &Frame, bframe: &Frame, aoff: IVec2, boff: IVec2) -> u32 {
- assert_eq!(aframe.res, bframe.res);
- let res = aframe.res;
- let mut diff = 0;
+ oldblock.clear();
+ frame.export_block(boff, &mut oldblock);
- // Luma
- for y in 0..BLOCK_SIZE {
- let ay_off = aoff.x + (y + aoff.y) * res.x;
- let by_off = boff.x + (y + boff.y) * res.x;
+ Frame::copy_block(&self.last, &mut frame, best_off, boff);
- for x in 0..BLOCK_SIZE {
- diff += aframe.data[(ay_off + x) as usize]
- .abs_diff(bframe.data[(by_off + x) as usize]) as u32
- }
- }
+ newblock.clear();
+ frame.export_block(boff, &mut newblock);
- // Chroma
- let uvplane_off = res.x * res.y;
+ let reloff = best_off - boff;
+ out.push((reloff.x + 127) as u8);
+ out.push((reloff.y + 127) as u8);
- for y in 0..BLOCK_SIZE / 2 {
- let ay_off = uvplane_off + (aoff.x & !1) + (y + aoff.y / 2) * res.x;
- let by_off = uvplane_off + (boff.x & !1) + (y + boff.y / 2) * res.x;
-
- for x in 0..BLOCK_SIZE {
- diff += aframe.data[(ay_off + x) as usize]
- .abs_diff(bframe.data[(by_off + x) as usize]) as u32;
+ for i in 0..(BLOCK_SIZE * BLOCK_SIZE + BLOCK_SIZE * BLOCK_SIZE / 4) {
+ out.push(newblock[i as usize] - oldblock[i as usize] + 127)
+ }
}
}
- diff
+ self.last = frame.clone();
+ out
}
}
diff --git a/test2/src/main.rs b/test2/src/main.rs
index 1f10f76..bbbf8d3 100644
--- a/test2/src/main.rs
+++ b/test2/src/main.rs
@@ -4,6 +4,7 @@ pub mod encode;
use decode::Dec;
use encode::Enc;
use framework::bitstream_filter_main;
+use glam::IVec2;
use std::env::args;
pub const BLOCK_SIZE: i32 = 8;
@@ -15,3 +16,125 @@ fn main() -> Result<(), std::io::Error> {
_ => panic!("unknown mode"),
}
}
+
+#[derive(Clone)]
+struct Frame {
+ res: IVec2,
+ data: Vec<u8>,
+}
+
+impl Frame {
+ fn new(res: IVec2) -> Self {
+ Frame {
+ res,
+ data: vec![127; (res.x * res.y + res.x * res.y / 2) as usize],
+ }
+ }
+ fn export_block(&self, off: IVec2, buf: &mut Vec<u8>) {
+ // Luma
+ for y in 0..BLOCK_SIZE {
+ let y_off = off.x + (y + off.y) * self.res.x;
+ buf.extend(&self.data[y_off as usize..(y_off + BLOCK_SIZE) as usize]);
+ }
+ // Chroma
+ let uvplane_off = self.res.x * self.res.y;
+ for y in 0..BLOCK_SIZE / 2 {
+ let y_off = uvplane_off + (off.x & !1) + (y + off.y / 2) * self.res.x;
+ buf.extend(&self.data[y_off as usize..(y_off + BLOCK_SIZE) as usize]);
+ }
+ }
+ fn import_block(&mut self, off: IVec2, buf: &[u8]) -> usize {
+ let mut p = 0;
+ // Luma
+ for y in 0..BLOCK_SIZE {
+ let y_off = off.x + (y + off.y) * self.res.x;
+ self.data[y_off as usize..(y_off + BLOCK_SIZE) as usize]
+ .copy_from_slice(&buf[p..p + BLOCK_SIZE as usize]);
+ p += BLOCK_SIZE as usize;
+ }
+ // Chroma
+ let uvplane_off = self.res.x * self.res.y;
+ for y in 0..BLOCK_SIZE / 2 {
+ let y_off = uvplane_off + (off.x & !1) + (y + off.y / 2) * self.res.x;
+ self.data[y_off as usize..(y_off + BLOCK_SIZE) as usize]
+ .copy_from_slice(&buf[p..p + BLOCK_SIZE as usize]);
+ p += BLOCK_SIZE as usize;
+ }
+ p
+ }
+ fn import_block_diff(&mut self, off: IVec2, buf: &[u8]) -> usize {
+ // Luma
+ for y in 0..BLOCK_SIZE {
+ let y_off = off.x + (y + off.y) * self.res.x;
+ let i = y * BLOCK_SIZE;
+ for x in 0..BLOCK_SIZE {
+ self.data[(y_off + x) as usize] = self.data[(y_off + x) as usize]
+ .saturating_add_signed(buf[(i + x) as usize] as i8 - 127);
+ }
+ }
+ // Chroma
+ let uvplane_off = self.res.x * self.res.y;
+ for y in 0..BLOCK_SIZE / 2 {
+ let y_off = uvplane_off + (off.x & !1) + (y + off.y / 2) * self.res.x;
+ let i = BLOCK_SIZE * BLOCK_SIZE + y * BLOCK_SIZE;
+ for x in 0..BLOCK_SIZE {
+ self.data[(y_off + x) as usize] = self.data[(y_off + x) as usize]
+ .saturating_add_signed(buf[(i + x) as usize] as i8 - 127);
+ }
+ }
+ (BLOCK_SIZE * BLOCK_SIZE + BLOCK_SIZE * BLOCK_SIZE / 4) as usize
+ }
+ fn copy_block(aframe: &Frame, bframe: &mut Frame, aoff: IVec2, boff: IVec2) {
+ assert_eq!(aframe.res, bframe.res);
+ let res = aframe.res;
+
+ // Luma
+ for y in 0..BLOCK_SIZE {
+ let ay_off = aoff.x + (y + aoff.y) * res.x;
+ let by_off = boff.x + (y + boff.y) * res.x;
+
+ bframe.data[by_off as usize..(by_off + BLOCK_SIZE) as usize]
+ .copy_from_slice(&aframe.data[ay_off as usize..(ay_off + BLOCK_SIZE) as usize]);
+ }
+
+ // Chroma
+ let uvplane_off = res.x * res.y;
+ for y in 0..BLOCK_SIZE / 2 {
+ let ay_off = uvplane_off + (aoff.x & !1) + (y + aoff.y / 2) * res.x;
+ let by_off = uvplane_off + (boff.x & !1) + (y + boff.y / 2) * res.x;
+
+ bframe.data[by_off as usize..(by_off + BLOCK_SIZE) as usize]
+ .copy_from_slice(&aframe.data[ay_off as usize..(ay_off + BLOCK_SIZE) as usize]);
+ }
+ }
+ fn compare_block(aframe: &Frame, bframe: &Frame, aoff: IVec2, boff: IVec2) -> u32 {
+ assert_eq!(aframe.res, bframe.res);
+ let res = aframe.res;
+ let mut diff = 0;
+
+ // Luma
+ for y in 0..BLOCK_SIZE {
+ let ay_off = aoff.x + (y + aoff.y) * res.x;
+ let by_off = boff.x + (y + boff.y) * res.x;
+
+ for x in 0..BLOCK_SIZE {
+ diff += aframe.data[(ay_off + x) as usize]
+ .abs_diff(bframe.data[(by_off + x) as usize]) as u32
+ }
+ }
+
+ // Chroma
+ let uvplane_off = res.x * res.y;
+ for y in 0..BLOCK_SIZE / 2 {
+ let ay_off = uvplane_off + (aoff.x & !1) + (y + aoff.y / 2) * res.x;
+ let by_off = uvplane_off + (boff.x & !1) + (y + boff.y / 2) * res.x;
+
+ for x in 0..BLOCK_SIZE {
+ diff += aframe.data[(ay_off + x) as usize]
+ .abs_diff(bframe.data[(by_off + x) as usize]) as u32;
+ }
+ }
+
+ diff
+ }
+}