diff options
Diffstat (limited to 'lvc/src/encode.rs')
-rw-r--r-- | lvc/src/encode.rs | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/lvc/src/encode.rs b/lvc/src/encode.rs index 935aaba..10f8c50 100644 --- a/lvc/src/encode.rs +++ b/lvc/src/encode.rs @@ -1,14 +1,16 @@ -use crate::diff::diff; +use crate::diff::{diff, pixel_diff}; use crate::split::split; -use crate::{Block, Frame, Ref, View}; +use crate::{Block, Frame, Ref, View, P2}; pub struct EncodeConfig { pub threshold: u32, pub max_block_size: usize, + pub iters: usize, } pub fn encode(last_frame: &Frame, frame: &Frame, view: View, config: &EncodeConfig) -> Block { - if view.size().area() > config.max_block_size { + let view_area = view.size().area(); + if view_area > config.max_block_size { let [av, bv] = split(view); let (ab, bb) = rayon::join( || Box::new(encode(last_frame, frame, av, config)), @@ -20,8 +22,11 @@ pub fn encode(last_frame: &Frame, frame: &Frame, view: View, config: &EncodeConf let mut r = Ref::default(); let mut d = diff([last_frame, frame], view, r); + 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..10 { + for _ in 0..config.iters { let (nd, nrp) = optimize_ref(last_frame, frame, view, d, r, granularity); if nd < d { r = nrp; @@ -32,7 +37,7 @@ pub fn encode(last_frame: &Frame, frame: &Frame, view: View, config: &EncodeConf } } - if d < config.threshold { + if d < thres { return Block::Ref(r); } else { Block::Lit(frame.export(view)) @@ -71,3 +76,15 @@ pub fn optimize_ref( (d, r) } + +pub fn attention(frame: &Frame, view: View) -> u32 { + let mut k = 0; + for y in view.a.y..view.b.y - 1 { + for x in view.a.x..view.b.x - 1 { + let p = P2 { x, y }; + k += pixel_diff(frame[p], frame[p + P2::X]).pow(2); + k += pixel_diff(frame[p], frame[p + P2::Y]).pow(2); + } + } + k +} |