From 11b78570656bd0ca67594472765fc629aa25fd25 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Thu, 9 Mar 2023 19:04:33 +0100 Subject: move all logic to codec crate --- lvc/codec/src/encode.rs | 70 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) (limited to 'lvc/codec/src/encode.rs') diff --git a/lvc/codec/src/encode.rs b/lvc/codec/src/encode.rs index 030e882..d612daf 100644 --- a/lvc/codec/src/encode.rs +++ b/lvc/codec/src/encode.rs @@ -1,23 +1,85 @@ use crate::diff::{diff, pixel_diff}; +use crate::huff::write_huff; use crate::split::split; -use crate::{Block, Frame, Pixel, Ref, View, P2}; +use crate::{decode::decode_block, Block, Frame, Pixel, Ref, View, P2}; +use std::io::{BufReader, BufWriter, Read, Write}; +use std::time::Instant; #[derive(Debug, Clone)] pub struct EncodeConfig { pub threshold: f32, pub max_block_size: usize, pub attention_split: u32, + pub keyframe_interval: usize, } -pub fn encode(last_frame: &Frame, frame: &Frame, view: View, config: &EncodeConfig) -> Block { +pub fn encode( + config: EncodeConfig, + size: P2, + input: impl Read, + output: impl Write, +) -> std::io::Result<()> { + let mut input = BufReader::new(input); + let mut output = BufWriter::new(output); + + let mut last_frame = Frame::new(size); + for frame_number in 0.. { + let mut frame = Frame::read(&mut input, size)?; + + let mut config = config.clone(); + if frame_number % config.keyframe_interval != 0 { + config.threshold = std::f32::INFINITY; + } + + let t = Instant::now(); + let b: Block = encode_block(&last_frame, &frame, View::all(size), &config); + let time_encode = t.elapsed(); + + let t = Instant::now(); + decode_block(&last_frame, &mut frame, View::all(size), &b); + last_frame = frame; + let time_decode = t.elapsed(); + + if true { + let mut buf = vec![]; + let mut bufw = std::io::Cursor::new(&mut buf); + b.write(&mut bufw)?; + drop(bufw); + let t = Instant::now(); + let bits_raw = buf.len() * 8; + let bits_huff = write_huff(&buf, &mut output)?; + let time_huff = t.elapsed(); + drop(buf); + + eprintln!( + "frame {frame_number}: {:?}", + time_decode + time_huff + time_encode + ); + eprintln!( + "\tencode {time_encode:?} ({:.2}%)", + (bits_raw as f32 / (size.area() * 24) as f32) * 100.0 + ); + eprintln!( + "\thuff {time_huff:?} ({:.2}%)", + (bits_huff as f32 / bits_raw as f32) * 100.0 + ); + eprintln!("\tdecode {time_decode:?}"); + } else { + b.write(&mut output)?; + } + } + Ok(()) +} + +pub fn encode_block(last_frame: &Frame, frame: &Frame, view: View, config: &EncodeConfig) -> Block { let view_area = view.size().area(); if view_area > config.max_block_size || (view_area > 64 && attention(frame, view) > config.attention_split) { let [av, bv] = split(view); let (ab, bb) = rayon::join( - || Box::new(encode(last_frame, frame, av, config)), - || Box::new(encode(last_frame, frame, bv, config)), + || Box::new(encode_block(last_frame, frame, av, config)), + || Box::new(encode_block(last_frame, frame, bv, config)), ); return Block::Split(ab, bb); } -- cgit v1.2.3-70-g09d2