diff options
author | metamuffin <metamuffin@disroot.org> | 2023-03-07 19:13:59 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-03-07 19:13:59 +0100 |
commit | da39ed55e1440fba61122c5fa2262ab9b0a9dd21 (patch) | |
tree | 0dd3e8f1f192451d46dceab700a686beaab02bbd /lvc/src | |
parent | 00f4bab2f1a1dcec9d2bf683b574dc0b9c599bcb (diff) | |
download | video-codec-experiments-da39ed55e1440fba61122c5fa2262ab9b0a9dd21.tar video-codec-experiments-da39ed55e1440fba61122c5fa2262ab9b0a9dd21.tar.bz2 video-codec-experiments-da39ed55e1440fba61122c5fa2262ab9b0a9dd21.tar.zst |
works very well
Diffstat (limited to 'lvc/src')
-rw-r--r-- | lvc/src/debug.rs | 2 | ||||
-rw-r--r-- | lvc/src/decode.rs | 2 | ||||
-rw-r--r-- | lvc/src/encode.rs | 22 | ||||
-rw-r--r-- | lvc/src/lib.rs | 2 | ||||
-rw-r--r-- | lvc/src/main.rs | 101 |
5 files changed, 99 insertions, 30 deletions
diff --git a/lvc/src/debug.rs b/lvc/src/debug.rs index 9959e9a..0e6fb7a 100644 --- a/lvc/src/debug.rs +++ b/lvc/src/debug.rs @@ -3,7 +3,7 @@ use crate::{split::split, Block, Frame, Pixel, View, P2}; pub fn draw_debug(frame: &mut Frame, view: View, block: &Block) { match block { Block::Lit(_) => rect(frame, view, Pixel::GREEN), - Block::Split([a, b]) => { + Block::Split(a, b) => { let [av, bv] = split(view); draw_debug(frame, av, &a); draw_debug(frame, bv, &b); diff --git a/lvc/src/decode.rs b/lvc/src/decode.rs index b4f2391..da69080 100644 --- a/lvc/src/decode.rs +++ b/lvc/src/decode.rs @@ -3,7 +3,7 @@ use crate::{split::split, Block, Frame, View, P2}; pub fn decode(last_frame: &Frame, frame: &mut Frame, view: View, block: &Block) { match block { Block::Lit(pxs) => frame.import(view, &pxs), - Block::Split([a, b]) => { + Block::Split(a, b) => { let [av, bv] = split(view); decode(last_frame, frame, av, &a); decode(last_frame, frame, bv, &b); diff --git a/lvc/src/encode.rs b/lvc/src/encode.rs index 5df803b..935aaba 100644 --- a/lvc/src/encode.rs +++ b/lvc/src/encode.rs @@ -1,18 +1,20 @@ 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 { +pub struct EncodeConfig { + pub threshold: u32, + pub max_block_size: usize, +} + +pub fn encode(last_frame: &Frame, frame: &Frame, view: View, config: &EncodeConfig) -> Block { + if view.size().area() > config.max_block_size { let [av, bv] = split(view); - return Block::Split( - rayon::join( - || Box::new(encode(last_frame, frame, av)), - || Box::new(encode(last_frame, frame, bv)), - ) - .to_array(), + let (ab, bb) = rayon::join( + || Box::new(encode(last_frame, frame, av, config)), + || Box::new(encode(last_frame, frame, bv, config)), ); + return Block::Split(ab, bb); } let mut r = Ref::default(); @@ -30,7 +32,7 @@ pub fn encode(last_frame: &Frame, frame: &Frame, view: View) -> Block { } } - if d < 10000 { + if d < config.threshold { return Block::Ref(r); } else { Block::Lit(frame.export(view)) diff --git a/lvc/src/lib.rs b/lvc/src/lib.rs index d9fdfa3..33a8cfb 100644 --- a/lvc/src/lib.rs +++ b/lvc/src/lib.rs @@ -40,7 +40,7 @@ pub struct View { #[derive(Debug, Clone, Encode, Decode)] pub enum Block { Lit(Vec<Pixel>), - Split([Box<Block>; 2]), + Split(Box<Block>,Box<Block>), Ref(Ref), } diff --git a/lvc/src/main.rs b/lvc/src/main.rs index 413e4a4..48df911 100644 --- a/lvc/src/main.rs +++ b/lvc/src/main.rs @@ -1,30 +1,97 @@ -use lvc::{debug::draw_debug, decode::decode, encode::encode, Frame, Pixel, PixelValue, View, P2}; +use bincode::config::standard; +use clap::{Parser, Subcommand}; +use lvc::{ + debug::draw_debug, + decode::decode, + encode::{encode, EncodeConfig}, + Block, Frame, Pixel, PixelValue, View, P2, +}; use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write}; +#[derive(Parser)] +#[clap(about, version)] +struct Args { + // Width of the video signal + #[arg(short, long)] + width: u16, + // Height of the video signal + #[arg(short, long)] + height: u16, + #[clap(subcommand)] + action: Action, +} +#[derive(Clone, Subcommand)] +enum Action { + // Compress video + Encode { + #[arg(short, long, default_value_t = 1024)] + block_size: usize, + #[arg(short, long, default_value_t = 10_000)] + threshold: u32, + }, + // Decompress video + Decode { + #[arg(short, long)] + debug: bool, + }, +} + fn main() { - let size = P2 { x: 1920, y: 1080 }; + let args = Args::parse(); - let mut last_frame = Frame::new(size); - let mut debug_frame = Some(Frame::new(size)); + let size = P2 { + x: args.width as i32, + y: args.height as i32, + }; + match args.action { + Action::Decode { debug } => { + let mut frame = Frame::new(size); + let mut last_frame = Frame::new(size); + let mut debug_frame = if debug { Some(Frame::new(size)) } else { None }; - let mut stdin = BufReader::new(stdin()); - let mut stdout = BufWriter::new(stdout()); + let mut stdin = BufReader::new(stdin()); + let mut stdout = BufWriter::new(stdout()); - loop { - let mut frame = read_frame(&mut stdin, size); + loop { + let b: Block = bincode::decode_from_std_read(&mut stdin, standard()).unwrap(); + decode(&last_frame, &mut frame, View::all(size), &b); - let b = encode(&last_frame, &frame, View::all(size)); - decode(&last_frame, &mut frame, View::all(size), &b); + if let Some(debug_frame) = &mut debug_frame { + debug_frame.pixels.copy_from_slice(&frame.pixels); + draw_debug(debug_frame, View::all(size), &b); + write_frame(&mut stdout, &debug_frame); + } else { + write_frame(&mut stdout, &frame); + } - if let Some(debug_frame) = &mut debug_frame { - debug_frame.pixels.copy_from_slice(&frame.pixels); - draw_debug(debug_frame, View::all(size), &b); - write_frame(&mut stdout, &debug_frame); - } else { - write_frame(&mut stdout, &frame); + last_frame.pixels.copy_from_slice(&frame.pixels); + } } + Action::Encode { + block_size, + threshold, + } => { + let config = EncodeConfig { + threshold, + max_block_size: block_size, + }; + + let mut last_frame = Frame::new(size); - last_frame = frame; + let mut stdin = BufReader::new(stdin()); + let mut stdout = BufWriter::new(stdout()); + + for frame_number in 0.. { + eprintln!("encode frame {frame_number}"); + let mut frame = read_frame(&mut stdin, size); + + let b: Block = encode(&last_frame, &frame, View::all(size), &config); + bincode::encode_into_std_write(&b, &mut stdout, standard()).unwrap(); + + decode(&last_frame, &mut frame, View::all(size), &b); + last_frame = frame; + } + } } } |