aboutsummaryrefslogtreecommitdiff
path: root/evc/src/codec/encode
diff options
context:
space:
mode:
Diffstat (limited to 'evc/src/codec/encode')
-rw-r--r--evc/src/codec/encode/advanced.rs115
-rw-r--r--evc/src/codec/encode/mod.rs112
-rw-r--r--evc/src/codec/encode/simple.rs65
3 files changed, 0 insertions, 292 deletions
diff --git a/evc/src/codec/encode/advanced.rs b/evc/src/codec/encode/advanced.rs
deleted file mode 100644
index 0e45176..0000000
--- a/evc/src/codec/encode/advanced.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-use super::EncodeConfig;
-use crate::{
- block::{AdvancedReference, Block},
- frame::Frame,
- refsampler::Sampler,
- view::View,
-};
-
-pub fn default(
- view: &View<&Frame>,
- prev: &View<&Frame>,
- config: &EncodeConfig,
- max_diff: f64,
-) -> (f64, Block) {
- let mut pm = AdvancedReference::default();
- let sampler = Sampler::from_refblock(prev.clone(), &pm);
- let mut diff = View::diff_sampler(&view, &sampler);
- if diff < max_diff {
- (diff, Block::REFZERO)
- } else {
- loop {
- let (mut d, mut p) = (diff, pm.clone());
-
- if config.do_translate {
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x += 4);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x -= 4);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y += 4);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y -= 4);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x += 2);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x -= 2);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y += 2);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y -= 2);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x += 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x -= 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y += 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y -= 1);
- }
- if config.do_value_scale {
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.value_scale += 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.value_scale -= 1);
- }
- if config.do_linear_transform {
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.a -= 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.a += 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.b -= 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.b += 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.c -= 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.c += 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.d -= 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.d += 1);
- }
-
- if d >= diff {
- break (diff, Block::AdvancedReference(pm));
- }
-
- diff = d;
- pm = p;
- }
- }
-}
-
-pub fn partial(
- view: &View<&Frame>,
- prev: &View<&Frame>,
- _config: &EncodeConfig,
- max_diff: f64,
-) -> (f64, Block) {
- let mut pm = AdvancedReference::default();
- let sampler = Sampler::from_refblock(prev.clone(), &pm);
- let mut diff = View::diff_sampler(&view, &sampler);
- if diff < max_diff {
- (diff, Block::REFZERO)
- } else {
- loop {
- let (mut d, mut p) = (diff, pm.clone());
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x += 2);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x -= 2);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y += 2);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y -= 2);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x += 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x -= 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y += 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y -= 1);
-
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.value_scale += 1);
- pk(&view, &prev, &mut d, &mut p, &pm, |p| p.value_scale -= 1);
-
- if d >= diff {
- break (diff, Block::AdvancedReference(pm));
- }
- diff = d;
- pm = p;
- }
- }
-}
-
-#[inline]
-fn pk<F: FnMut(&mut AdvancedReference) -> ()>(
- view: &View<&Frame>,
- prev: &View<&Frame>,
- diff: &mut f64,
- params: &mut AdvancedReference,
- initial_params: &AdvancedReference,
- mut f: F,
-) {
- let mut p = initial_params.clone();
- f(&mut p);
- let sampler = Sampler::from_refblock(prev.clone(), &p);
- let d = View::diff_sampler(view, &sampler);
- if d < *diff {
- *diff = d;
- *params = p;
- }
-}
diff --git a/evc/src/codec/encode/mod.rs b/evc/src/codec/encode/mod.rs
deleted file mode 100644
index 30342f0..0000000
--- a/evc/src/codec/encode/mod.rs
+++ /dev/null
@@ -1,112 +0,0 @@
-pub mod advanced;
-pub mod simple;
-
-use crate::{
- block::Block,
- frame::Frame,
- helpers::{pixel::Pixel, vector::Vec2},
- view::View,
-};
-use clap::ValueEnum;
-
-#[derive(Debug, Clone)]
-pub struct EncodeConfig {
- pub mode: EncodeMode,
- pub ref_thres: f64,
- pub max_diff_area: isize,
- pub min_block_size: isize,
- pub weight_factor: f64,
-
- pub do_translate: bool,
- pub do_value_scale: bool,
- pub do_linear_transform: bool,
-}
-
-#[derive(Debug, Clone, ValueEnum)]
-pub enum EncodeMode {
- Trivial,
- SimpleFast,
- SimpleExhaustive,
- Advanced,
- AdvancedPartial,
-}
-
-pub fn encode_block(view: View<&Frame>, prev: View<&Frame>, config: &EncodeConfig) -> (f64, Block) {
- let (diff, refblock) = if view.area() > config.max_diff_area {
- (
- f64::INFINITY,
- Block::Reference {
- translation: Vec2::<isize>::ZERO,
- },
- )
- } else {
- let weight = importance(&view).max(0.5);
- let irrelevance = config.weight_factor / weight;
- let max_diff = config.ref_thres - irrelevance;
- let (diff, refblock) = match config.mode {
- EncodeMode::Trivial => (
- View::diff(&view, &prev),
- Block::Reference {
- translation: Vec2::<isize>::ZERO,
- },
- ),
- EncodeMode::SimpleExhaustive => simple::exhaustive(&view, &prev, config, max_diff),
- EncodeMode::SimpleFast => simple::fast(&view, &prev, config, max_diff),
- EncodeMode::Advanced => advanced::default(&view, &prev, config, max_diff),
- EncodeMode::AdvancedPartial => advanced::partial(&view, &prev, config, max_diff),
- };
- (diff - irrelevance, refblock)
- };
- if diff < config.ref_thres {
- (diff, refblock)
- } else {
- if view.size.x < config.min_block_size || view.size.y < config.min_block_size {
- (0.0, Block::Literal(view.pixels()))
- } else {
- let [av, bv] =
- unsafe { std::mem::transmute::<_, [View<&'static Frame>; 2]>(view.split()) };
- let [ap, bp] =
- unsafe { std::mem::transmute::<_, [View<&'static Frame>; 2]>(prev.split()) };
- let config = unsafe { std::mem::transmute::<_, &'static EncodeConfig>(config) };
-
- // only bother to do multithreading, when the block is big.
- let ((ad, a), (bd, b)) = if view.area() > 100 {
- rayon::join(
- || encode_block(av, ap, config),
- || encode_block(bv, bp, config),
- )
- } else {
- (encode_block(av, ap, config), encode_block(bv, bp, config))
- };
-
- (
- ad + bd,
- if a.is_literal() && b.is_literal() {
- Block::Literal(view.pixels())
- } else if Block::identical_ref(&a, &b) {
- Block::Reference {
- translation: Vec2::<isize>::ZERO,
- }
- } else {
- Block::Split(Box::new([a, b]))
- },
- )
- }
- }
-}
-
-pub fn importance(view: &View<&Frame>) -> f64 {
- let mut acc = 0;
- for x in 0..view.size.x {
- for y in 0..view.size.y {
- let p = Vec2 { x, y };
- if x > 0 {
- acc += Pixel::distance(view[p], view[p + Vec2::<isize>::LEFT]);
- }
- if y > 0 {
- acc += Pixel::distance(view[p], view[p + Vec2::<isize>::UP]);
- }
- }
- }
- (acc / view.area() as usize) as f64
-}
diff --git a/evc/src/codec/encode/simple.rs b/evc/src/codec/encode/simple.rs
deleted file mode 100644
index 2a971af..0000000
--- a/evc/src/codec/encode/simple.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-use crate::{block::Block, frame::Frame, helpers::vector::Vec2, view::View};
-
-use super::EncodeConfig;
-
-pub fn exhaustive(
- view: &View<&Frame>,
- prev: &View<&Frame>,
- _config: &EncodeConfig,
- _max_diff: f64,
-) -> (f64, Block) {
- let mut diff = f64::INFINITY;
- let mut translation = Vec2::<isize>::ZERO;
- const OFFSETS: &[isize] = &[-64, -32, -16, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 32, 64];
- for x in OFFSETS {
- for y in OFFSETS {
- let t = Vec2 { x: *x, y: *y };
- let d = View::diff(&view, &prev.offset(t));
- if d < diff {
- translation = t;
- diff = d;
- }
- }
- }
- (diff, Block::Reference { translation })
-}
-
-pub fn fast(
- view: &View<&Frame>,
- prev: &View<&Frame>,
- _config: &EncodeConfig,
- max_diff: f64,
-) -> (f64, Block) {
- let mut offset = Vec2::<isize>::ZERO;
- let mut diff = View::diff(&view, &prev);
- if diff < max_diff {
- (diff, Block::REFZERO)
- } else {
- loop {
- let (mut d, mut o) = (diff, offset);
- let mut probe = |test_o: Vec2<isize>| {
- let test_d = View::diff(&prev.clone().offset(test_o), &view);
- if test_d < d {
- d = test_d;
- o = test_o;
- }
- };
-
- probe(offset + Vec2 { x: 8, y: 0 });
- probe(offset + Vec2 { x: -8, y: 0 });
- probe(offset + Vec2 { x: 0, y: 8 });
- probe(offset + Vec2 { x: 0, y: -8 });
-
- probe(offset + Vec2 { x: 1, y: 0 });
- probe(offset + Vec2 { x: -1, y: 0 });
- probe(offset + Vec2 { x: 0, y: 1 });
- probe(offset + Vec2 { x: 0, y: -1 });
-
- if d >= diff {
- break (diff, Block::Reference { translation: o });
- }
- diff = d;
- offset = o;
- }
- }
-}