aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-03-07 17:56:50 +0100
committermetamuffin <metamuffin@disroot.org>2023-03-07 17:56:50 +0100
commit00f4bab2f1a1dcec9d2bf683b574dc0b9c599bcb (patch)
treec3f09431e5b1ea41e2201ab0dba906eb0fa5d30a
parent414990bb53f5c9e2028d42db46fa641fa606cd86 (diff)
downloadvideo-codec-experiments-00f4bab2f1a1dcec9d2bf683b574dc0b9c599bcb.tar
video-codec-experiments-00f4bab2f1a1dcec9d2bf683b574dc0b9c599bcb.tar.bz2
video-codec-experiments-00f4bab2f1a1dcec9d2bf683b574dc0b9c599bcb.tar.zst
works well
-rw-r--r--lvc/src/encode.rs82
-rw-r--r--lvc/src/impls.rs16
-rw-r--r--lvc/src/lib.rs11
3 files changed, 71 insertions, 38 deletions
diff --git a/lvc/src/encode.rs b/lvc/src/encode.rs
index d85ac30..5df803b 100644
--- a/lvc/src/encode.rs
+++ b/lvc/src/encode.rs
@@ -1,51 +1,71 @@
use crate::diff::diff;
+use crate::impls::ToArray;
use crate::split::split;
use crate::{Block, Frame, Ref, View};
pub fn encode(last_frame: &Frame, frame: &Frame, view: View) -> Block {
if view.size().area() > 1024 {
let [av, bv] = split(view);
- return Block::Split([
- Box::new(encode(last_frame, frame, av)),
- Box::new(encode(last_frame, frame, bv)),
- ]);
+ return Block::Split(
+ rayon::join(
+ || Box::new(encode(last_frame, frame, av)),
+ || Box::new(encode(last_frame, frame, bv)),
+ )
+ .to_array(),
+ );
}
- let mut rp = Ref::default();
- let mut d = diff([last_frame, frame], view, rp);
+ let mut r = Ref::default();
+ let mut d = diff([last_frame, frame], view, r);
- for _ in 0..500 {
- let (nd, nrp) = optimize_ref(last_frame, frame, view, rp);
- if nd < d {
- rp = nrp;
- d = nd;
- } else {
- break;
+ for granularity in [4, 2, 1] {
+ for _ in 0..10 {
+ let (nd, nrp) = optimize_ref(last_frame, frame, view, d, r, granularity);
+ if nd < d {
+ r = nrp;
+ d = nd;
+ } else {
+ break;
+ }
}
}
if d < 10000 {
- return Block::Ref(rp);
+ return Block::Ref(r);
} else {
Block::Lit(frame.export(view))
}
}
-pub fn optimize_ref(last_frame: &Frame, frame: &Frame, view: View, rp: Ref) -> (u32, Ref) {
- [
- rp.apply(|r| r.pos_off.x += 1),
- rp.apply(|r| r.pos_off.x -= 1),
- rp.apply(|r| r.pos_off.y += 1),
- rp.apply(|r| r.pos_off.y -= 1),
- rp.apply(|r| r.color_off.r += 10),
- rp.apply(|r| r.color_off.r -= 10),
- rp.apply(|r| r.color_off.g += 10),
- rp.apply(|r| r.color_off.g -= 10),
- rp.apply(|r| r.color_off.b += 10),
- rp.apply(|r| r.color_off.b -= 10),
- ]
- .map(|p| (diff([last_frame, frame], view, p), p))
- .into_iter()
- .min_by_key(|x| x.0)
- .unwrap()
+pub fn optimize_ref(
+ last_frame: &Frame,
+ frame: &Frame,
+ view: View,
+ mut d: u32,
+ mut r: Ref,
+ granularity: i32,
+) -> (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);
+
+ (d, r)
}
diff --git a/lvc/src/impls.rs b/lvc/src/impls.rs
index 0801361..00614c9 100644
--- a/lvc/src/impls.rs
+++ b/lvc/src/impls.rs
@@ -88,7 +88,10 @@ impl Index<P2> for Frame {
type Output = Pixel;
#[inline]
fn index(&self, P2 { x, y }: P2) -> &Self::Output {
- &self.pixels[x as usize + (y as usize * self.size.x as usize)]
+ &self
+ .pixels
+ .get(x as usize + (y as usize * self.size.x as usize))
+ .unwrap_or(&Pixel { r: 0, g: 0, b: 0 })
}
}
impl IndexMut<P2> for Frame {
@@ -97,3 +100,14 @@ impl IndexMut<P2> for Frame {
&mut self.pixels[x as usize + (y as usize * self.size.x as usize)]
}
}
+
+pub trait ToArray {
+ type Output;
+ fn to_array(self) -> [Self::Output; 2];
+}
+impl<A> ToArray for (A, A) {
+ type Output = A;
+ fn to_array(self) -> [A; 2] {
+ [self.0, self.1]
+ }
+}
diff --git a/lvc/src/lib.rs b/lvc/src/lib.rs
index 4a88b93..d9fdfa3 100644
--- a/lvc/src/lib.rs
+++ b/lvc/src/lib.rs
@@ -2,18 +2,17 @@
use bincode::{Decode, Encode};
+#[cfg(test)]
+pub mod bench;
+pub mod debug;
+pub mod decode;
pub mod diff;
pub mod encode;
pub mod impls;
-pub mod decode;
pub mod split;
-pub mod debug;
-#[cfg(test)]
-pub mod bench;
-pub type PixelValue = u8;
+pub type PixelValue = i16;
-#[repr(C, align(1))]
#[derive(Debug, Clone, Copy, Default, Encode, Decode)]
pub struct Pixel {
pub r: PixelValue,