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()); 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_matrix_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 ()>( 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; } }