diff options
author | metamuffin <metamuffin@disroot.org> | 2025-05-07 16:17:44 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-05-07 16:17:44 +0200 |
commit | 24ecbd5e91f125bd68a4d538eeb5a9839f16a4e6 (patch) | |
tree | e902614fc7a66b110e6863d5b10fa494e157bdad /test2/src | |
parent | e33685969d072f369ea2f30c08403f6b3a8e8686 (diff) | |
download | video-codec-experiments-24ecbd5e91f125bd68a4d538eeb5a9839f16a4e6.tar video-codec-experiments-24ecbd5e91f125bd68a4d538eeb5a9839f16a4e6.tar.bz2 video-codec-experiments-24ecbd5e91f125bd68a4d538eeb5a9839f16a4e6.tar.zst |
bugs everywhere
Diffstat (limited to 'test2/src')
-rw-r--r-- | test2/src/decode.rs | 31 | ||||
-rw-r--r-- | test2/src/encode.rs | 92 | ||||
-rw-r--r-- | test2/src/main.rs | 123 |
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 + } +} |