aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lvc/Cargo.lock316
-rw-r--r--lvc/Cargo.toml1
-rw-r--r--lvc/src/debug.rs2
-rw-r--r--lvc/src/decode.rs2
-rw-r--r--lvc/src/encode.rs22
-rw-r--r--lvc/src/lib.rs2
-rw-r--r--lvc/src/main.rs101
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;
+ }
+ }
}
}