diff options
Diffstat (limited to 'lvc')
-rw-r--r-- | lvc/Cargo.lock | 316 | ||||
-rw-r--r-- | lvc/Cargo.toml | 1 | ||||
-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 |
7 files changed, 415 insertions, 31 deletions
diff --git a/lvc/Cargo.lock b/lvc/Cargo.lock index 0c9c575..2dd5615 100644 --- a/lvc/Cargo.lock +++ b/lvc/Cargo.lock @@ -28,12 +28,61 @@ dependencies = [ ] [[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] +name = "clap" +version = "4.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d7ae14b20b94cb02149ed21a86c423859cbe18dc7ed69845cace50e52b40a5" +dependencies = [ + "bitflags", + "clap_derive", + "clap_lex", + "is-terminal", + "once_cell", + "strsim", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44bec8e5c9d09e439c4335b1af0abaab56dcf3b94999a936e1bb47b9134288f0" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09" +dependencies = [ + "os_str_bytes", +] + +[[package]] name = "crossbeam-channel" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -83,6 +132,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] name = "hermit-abi" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -92,16 +168,51 @@ dependencies = [ ] [[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "io-lifetimes" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfa919a82ea574332e2de6e74b4c36e74d41982b335080fa59d4ef31be20fdf3" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "is-terminal" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys", +] + +[[package]] name = "libc" version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + +[[package]] name = "lvc" version = "0.1.0" dependencies = [ "bincode", + "clap", "rayon", ] @@ -120,11 +231,65 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] [[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] name = "rayon" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -147,6 +312,20 @@ dependencies = [ ] [[package]] +name = "rustix" +version = "0.36.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -159,7 +338,142 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" [[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] name = "virtue" version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b60dcd6a64dd45abf9bd426970c9843726da7fc08f44cd6fcebf68c21220a63" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" diff --git a/lvc/Cargo.toml b/lvc/Cargo.toml index 71eb470..f53a95f 100644 --- a/lvc/Cargo.toml +++ b/lvc/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" [dependencies] rayon = "1.7.0" bincode = "2.0.0-rc.2" +clap = { version = "4.1.8", features = ["derive"] } 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; + } + } } } |