From 5b3c03bc0cfcf89e76953dde13ed58a39b5d1dd0 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Wed, 8 Mar 2023 15:43:22 +0100 Subject: do stuff, idk --- lvc/src/bench.rs | 16 +++++++-- lvc/src/diff.rs | 19 +++++++++++ lvc/src/encode.rs | 98 ++++++++++++++++++++++++++++++++++++------------------- lvc/src/impls.rs | 11 +++++++ lvc/tools/d-disp | 2 +- lvc/tools/d-dispd | 2 +- 6 files changed, 109 insertions(+), 39 deletions(-) (limited to 'lvc') diff --git a/lvc/src/bench.rs b/lvc/src/bench.rs index 91b13b6..48d220c 100644 --- a/lvc/src/bench.rs +++ b/lvc/src/bench.rs @@ -1,4 +1,4 @@ -use crate::{diff::diff, Frame, Ref, View, P2}; +use crate::{diff::*, Frame, Ref, View, P2}; use std::time::Instant; fn measure(f: impl FnOnce()) { @@ -13,7 +13,17 @@ fn bench_diff() { let size = P2 { x: 2000, y: 2000 }; let f1 = Frame::new(size); let f2 = Frame::new(size); - measure(move || { + measure(|| { diff([&f1, &f2], View::all(size), Ref::default()); - }) + }); } + +// #[test] +// fn bench_fast_diff() { +// let size = P2 { x: 2000, y: 2000 }; +// let f1 = Frame::new(size); +// let f2 = Frame::new(size); +// measure(|| { +// diff_fast([&f1, &f2], View::all(size), Ref::default()); +// }); +// } diff --git a/lvc/src/diff.rs b/lvc/src/diff.rs index fbb6b0a..4d1a805 100644 --- a/lvc/src/diff.rs +++ b/lvc/src/diff.rs @@ -19,6 +19,25 @@ pub fn pixel_diff(p1: Pixel, p2: Pixel) -> u32 { p1.r.abs_diff(p2.r) as u32 + p1.g.abs_diff(p2.g) as u32 + p1.b.abs_diff(p2.b) as u32 } +// pub fn diff([frame1, frame2]: [&Frame; 2], view: View, rp: Ref) -> u32 { +// let mut k = 0; +// for y in view.a.y..view.b.y { +// let s1_ystart = (y * frame1.size.x) as usize; +// let s2_ystart = ((y + rp.pos_off.y) * frame1.size.x + rp.pos_off.x) as usize; +// let s1 = &frame1.pixels[s1_ystart + view.a.x as usize..s1_ystart + view.b.x as usize]; +// let s2 = &frame2.pixels[s2_ystart + view.a.x as usize..s2_ystart + view.b.x as usize]; +// let s1 = unsafe { std::mem::transmute::<_, &[i16]>(s1) }; +// let s2 = unsafe { std::mem::transmute::<_, &[i16]>(s2) }; + +// k += s1 +// .iter() +// .zip(s2.iter()) +// .map(|(a, b)| a.abs_diff(*b) as u32) +// .sum::() +// } +// k +// } + // pub fn fast_diff([frame1, frame2]: [&Frame; 2], view: View, rp: Ref) -> u32 { // assert!(view.size().x % 5 == 0); diff --git a/lvc/src/encode.rs b/lvc/src/encode.rs index 10f8c50..fde4f94 100644 --- a/lvc/src/encode.rs +++ b/lvc/src/encode.rs @@ -1,6 +1,6 @@ use crate::diff::{diff, pixel_diff}; use crate::split::split; -use crate::{Block, Frame, Ref, View, P2}; +use crate::{Block, Frame, Pixel, Ref, View, P2}; pub struct EncodeConfig { pub threshold: u32, @@ -25,15 +25,15 @@ pub fn encode(last_frame: &Frame, frame: &Frame, view: View, config: &EncodeConf let att = 1. - attention(frame, view) as f32 * 0.000001; let thres = (config.threshold as f32 * att.clamp(0.2, 1.0)) as u32; - for granularity in [4, 2, 1] { - for _ in 0..config.iters { - let (nd, nrp) = optimize_ref(last_frame, frame, view, d, r, granularity); - if nd < d { - r = nrp; - d = nd; - } else { - break; - } + let target_average = average_color(frame, view); + + for granularity in [8, 8, 4, 2, 1, 1, 1] { + let (nd, nrp) = optimize_ref(last_frame, frame, view, r, granularity, target_average); + if nd < d { + r = nrp; + d = nd; + } else { + break; } } @@ -48,33 +48,42 @@ pub fn optimize_ref( last_frame: &Frame, frame: &Frame, view: View, - mut d: u32, - mut r: Ref, + r: Ref, granularity: i32, + target_average: Pixel, ) -> (u32, Ref) { - let mut n = |f: fn(&mut Ref, i32)| { - let mut r2 = r; - f(&mut r2, granularity); - - let d2 = diff([last_frame, frame], view, r2); - if d2 < d { - d = d2; - r = r2; - } - }; - - n(|r, g| r.pos_off.x += g); - n(|r, g| r.pos_off.x -= g); - n(|r, g| r.pos_off.y += g); - n(|r, g| r.pos_off.y -= g); - n(|r, g| r.color_off.r += (g as i16) << 2); - n(|r, g| r.color_off.r -= (g as i16) << 2); - n(|r, g| r.color_off.g += (g as i16) << 2); - n(|r, g| r.color_off.g -= (g as i16) << 2); - n(|r, g| r.color_off.b += (g as i16) << 2); - n(|r, g| r.color_off.b -= (g as i16) << 2); + [ + Some(r.apply(|r| r.pos_off.x += granularity)), + Some(r.apply(|r| r.pos_off.x -= granularity)), + Some(r.apply(|r| r.pos_off.y += granularity)), + Some(r.apply(|r| r.pos_off.y -= granularity)), + { + let mut r = r; + let last_avr = average_color(last_frame, view); + let diff = target_average - last_avr; + r.color_off = diff; + if diff != Pixel::BLACK { + Some(r) + } else { + None + } + }, + // n(|r, g| r.color_off.r += (g as i16) << 2); + // n(|r, g| r.color_off.r -= (g as i16) << 2); + // n(|r, g| r.color_off.g += (g as i16) << 2); + // n(|r, g| r.color_off.g -= (g as i16) << 2); + // n(|r, g| r.color_off.b += (g as i16) << 2); + // n(|r, g| r.color_off.b -= (g as i16) << 2); + ] + .into_iter() + .flatten() + .map(|r| { + let d = diff([last_frame, frame], view, r); - (d, r) + (d, r) + }) + .min_by_key(|e| e.0) + .unwrap() } pub fn attention(frame: &Frame, view: View) -> u32 { @@ -88,3 +97,24 @@ pub fn attention(frame: &Frame, view: View) -> u32 { } k } + +pub fn average_color(frame: &Frame, view: View) -> Pixel { + let mut r = 0u32; + let mut g = 0u32; + let mut b = 0u32; + + for y in view.a.y..view.b.y { + for x in view.a.x..view.b.x { + let p = frame[P2 { x, y }]; + r += p.r as u32; + g += p.g as u32; + b += p.b as u32; + } + } + let area = view.size().area() as u32; + Pixel { + r: (r / area) as i16, + g: (g / area) as i16, + b: (b / area) as i16, + } +} diff --git a/lvc/src/impls.rs b/lvc/src/impls.rs index 2a5a497..04699c6 100644 --- a/lvc/src/impls.rs +++ b/lvc/src/impls.rs @@ -50,6 +50,17 @@ impl Add for Pixel { } } } +impl Sub for Pixel { + type Output = Pixel; + #[inline] + fn sub(self, rhs: Self) -> Self::Output { + Self { + r: self.r - rhs.r, + g: self.g - rhs.g, + b: self.b - rhs.b, + } + } +} impl P2 { pub const ZERO: P2 = P2 { x: 0, y: 0 }; pub const X: P2 = P2 { x: 1, y: 0 }; diff --git a/lvc/tools/d-disp b/lvc/tools/d-disp index 5879bf3..f62d229 100755 --- a/lvc/tools/d-disp +++ b/lvc/tools/d-disp @@ -1,2 +1,2 @@ #!/bin/fish -cargo run --release -- -w 1920 -h 1080 decode | ffplay -video_size 1920x1080 -pixel_format rgb24 -f rawvideo pipe:0 \ No newline at end of file +cargo run --release -- -w 1920 -h 1080 decode | ffplay -loglevel quiet -video_size 1920x1080 -pixel_format rgb24 -f rawvideo pipe:0 \ No newline at end of file diff --git a/lvc/tools/d-dispd b/lvc/tools/d-dispd index c4b435d..dac3faf 100755 --- a/lvc/tools/d-dispd +++ b/lvc/tools/d-dispd @@ -1,2 +1,2 @@ #!/bin/fish -cargo run --release -- -w 1920 -h 1080 decode --debug | ffplay -video_size 1920x1080 -pixel_format rgb24 -f rawvideo pipe:0 \ No newline at end of file +cargo run --release -- -w 1920 -h 1080 decode --debug | ffplay -loglevel quiet -video_size 1920x1080 -pixel_format rgb24 -f rawvideo pipe:0 \ No newline at end of file -- cgit v1.2.3-70-g09d2