aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2022-12-06 08:16:09 +0100
committermetamuffin <metamuffin@disroot.org>2022-12-06 08:16:09 +0100
commit5002d0df81f74418665e4e99179ba56d8e78cbe1 (patch)
tree2ece906f886934dd0fc335a4aa31bc5363fa92e8
parentbafb1df8b7764a0a62f1c656eb52fbe7bfd8b8ac (diff)
downloadvideo-codec-experiments-5002d0df81f74418665e4e99179ba56d8e78cbe1.tar
video-codec-experiments-5002d0df81f74418665e4e99179ba56d8e78cbe1.tar.bz2
video-codec-experiments-5002d0df81f74418665e4e99179ba56d8e78cbe1.tar.zst
more codde
-rw-r--r--evc/Cargo.lock7
-rw-r--r--evc/Cargo.toml1
-rw-r--r--evc/src/bin/decode.rs19
-rw-r--r--evc/src/bin/encode.rs25
-rw-r--r--evc/src/block.rs4
-rw-r--r--evc/src/frame.rs4
-rw-r--r--evc/src/header.rs12
-rw-r--r--evc/src/pixel.rs4
-rw-r--r--evc/src/ser.rs116
9 files changed, 119 insertions, 73 deletions
diff --git a/evc/Cargo.lock b/evc/Cargo.lock
index 06f5cb2..84e5513 100644
--- a/evc/Cargo.lock
+++ b/evc/Cargo.lock
@@ -3,6 +3,12 @@
version = 3
[[package]]
+name = "anyhow"
+version = "1.0.66"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
+
+[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -76,6 +82,7 @@ dependencies = [
name = "evc"
version = "0.1.0"
dependencies = [
+ "anyhow",
"clap",
]
diff --git a/evc/Cargo.toml b/evc/Cargo.toml
index d86ebef..43818ee 100644
--- a/evc/Cargo.toml
+++ b/evc/Cargo.toml
@@ -5,3 +5,4 @@ edition = "2021"
[dependencies]
clap = { version = "*", features = ["derive"] }
+anyhow = "1.0.66"
diff --git a/evc/src/bin/decode.rs b/evc/src/bin/decode.rs
index 293181a..0a00426 100644
--- a/evc/src/bin/decode.rs
+++ b/evc/src/bin/decode.rs
@@ -1,6 +1,5 @@
#![feature(box_patterns)]
-use std::io::{self, BufReader, BufWriter};
-
+use anyhow::Context;
use clap::Parser;
use evc::{
block::{Block, BlockInner},
@@ -9,24 +8,26 @@ use evc::{
ser::Source,
view::View,
};
+use std::io::{BufReader, BufWriter};
#[derive(Parser)]
#[clap(about, version)]
pub struct DecodeArgs {}
-fn main() -> io::Result<()> {
+fn main() -> anyhow::Result<()> {
let _args = DecodeArgs::parse();
let mut input = BufReader::new(std::io::stdin());
let mut output = BufWriter::new(std::io::stdout());
- let header = input.get::<Header>()?;
+ let header = input.get::<Header>().context("reading header")?;
eprintln!("{header:?}");
let size = header.resolution;
-
+
let mut prev = Frame::new(size);
- loop {
- let block = Block::read(&mut input, size)?;
+ for i in 0.. {
+ eprintln!("decode frame {i}");
+ let block = Block::read(&mut input, size).context("reading encoded frame")?;
let mut frame = Frame::new(size);
blit_block(
@@ -35,9 +36,11 @@ fn main() -> io::Result<()> {
prev.view((0, 0), size),
);
- frame.write(&mut output)?;
+ frame.write(&mut output).context("writing raw frame")?;
prev = frame;
}
+ drop(input);
+ Ok(())
}
fn blit_block(block: &Block, mut target: View<&mut Frame>, prev: View<&Frame>) {
diff --git a/evc/src/bin/encode.rs b/evc/src/bin/encode.rs
index c426aba..1934e26 100644
--- a/evc/src/bin/encode.rs
+++ b/evc/src/bin/encode.rs
@@ -1,3 +1,4 @@
+use anyhow::Context;
use clap::Parser;
use evc::{
block::{Block, BlockInner},
@@ -6,7 +7,7 @@ use evc::{
ser::Sink,
view::View,
};
-use std::io::{self, BufReader, BufWriter};
+use std::io::{BufReader, BufWriter};
#[derive(Parser)]
#[clap(about, version)]
@@ -17,28 +18,32 @@ pub struct EncodeArgs {
height: usize,
}
-fn main() -> io::Result<()> {
+fn main() -> anyhow::Result<()> {
let args = EncodeArgs::parse();
let mut input = BufReader::new(std::io::stdin());
let mut output = BufWriter::new(std::io::stdout());
let size = (args.width, args.height);
- output.put(Header {
- resolution: size,
- frame_count: 0,
- })?;
+ output
+ .put(Header {
+ resolution: size,
+ frame_count: 0,
+ })
+ .context("writing header")?;
let mut prev_frame = Frame::new(size);
for i in 0.. {
- println!("frame {i}");
- let frame = Frame::read(&mut input, size)?;
+ eprintln!("encode frame {i}");
+ let frame = Frame::read(&mut input, size)
+ .context("reading raw frame")
+ .unwrap();
let v1 = frame.view((0, 0), size);
let v2 = prev_frame.view((0, 0), size);
let root = encode_block(v1, v2);
- root.write(&mut output)?;
+ root.write(&mut output).context("writing encoded frame")?;
prev_frame = frame;
}
@@ -48,7 +53,7 @@ fn main() -> io::Result<()> {
fn encode_block(view: View<&Frame>, prev: View<&Frame>) -> Block {
let diff = View::diff(&view, &prev) / view.area() as f64;
- eprintln!("{:?} {diff}", view.size);
+ // eprintln!("{:?} {diff}", view.size);
let inner = if diff < 0.5 {
BlockInner::Reference {
translation: (0, 0),
diff --git a/evc/src/block.rs b/evc/src/block.rs
index 261882a..f58bcb3 100644
--- a/evc/src/block.rs
+++ b/evc/src/block.rs
@@ -17,7 +17,7 @@ pub enum BlockInner {
}
impl Block {
- pub fn write(&self, sink: &mut impl std::io::Write) -> std::io::Result<()> {
+ pub fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> {
match &self.inner {
BlockInner::Literal(pixels) => {
sink.put(0u8)?;
@@ -35,7 +35,7 @@ impl Block {
Ok(())
}
- pub fn read(source: &mut impl std::io::Read, size: (usize, usize)) -> std::io::Result<Self> {
+ pub fn read(source: &mut impl std::io::Read, size: (usize, usize)) -> anyhow::Result<Self> {
let inner = match source.get::<u8>()? {
0 => BlockInner::Literal(source.get()?),
1 => BlockInner::Split(Box::new({
diff --git a/evc/src/frame.rs b/evc/src/frame.rs
index 1269bf2..c36abf3 100644
--- a/evc/src/frame.rs
+++ b/evc/src/frame.rs
@@ -22,7 +22,7 @@ impl Frame {
.collect(),
}
}
- pub fn read(source: &mut impl Source, size: (usize, usize)) -> io::Result<Self> {
+ pub fn read(source: &mut impl Source, size: (usize, usize)) -> anyhow::Result<Self> {
let mut frame = Frame::new(size);
for y in 0..size.1 {
for x in 0..size.0 {
@@ -32,7 +32,7 @@ impl Frame {
}
Ok(frame)
}
- pub fn write(&self, sink: &mut impl Sink) -> io::Result<()> {
+ pub fn write(&self, sink: &mut impl Sink) -> anyhow::Result<()> {
for y in 0..self.size.1 {
for x in 0..self.size.0 {
sink.put(self[(x, y)])?;
diff --git a/evc/src/header.rs b/evc/src/header.rs
index 923e8ff..5244ce5 100644
--- a/evc/src/header.rs
+++ b/evc/src/header.rs
@@ -1,20 +1,22 @@
use crate::ser::{Ser, Sink, Source};
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Copy)]
pub struct Header {
pub resolution: (usize, usize),
pub frame_count: usize,
}
+pub const MAGIC: [u8; 4] = [0x5eu8, 0xb1u8, 0xc3u8, 0x08u8];
+
impl Ser for Header {
- fn write(&self, sink: &mut impl std::io::Write) -> std::io::Result<()> {
- sink.put([0x5eu8, 0xb1u8, 0xc3u8, 0x08u8])?;
+ fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> {
+ sink.put(MAGIC)?;
sink.put((self.resolution, self.frame_count))?;
Ok(())
}
- fn read(source: &mut impl std::io::Read) -> std::io::Result<Self> {
- source.get::<[u8; 4]>()?;
+ fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> {
+ assert_eq!(source.get::<[u8; 4]>()?, MAGIC);
let (resolution, frame_count) = source.get()?;
Ok(Self {
resolution,
diff --git a/evc/src/pixel.rs b/evc/src/pixel.rs
index 442c1b5..aaf8d83 100644
--- a/evc/src/pixel.rs
+++ b/evc/src/pixel.rs
@@ -8,11 +8,11 @@ pub struct Pixel {
}
impl Ser for Pixel {
- fn write(&self, sink: &mut impl std::io::Write) -> std::io::Result<()> {
+ fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> {
sink.put((self.r, self.g, self.b))
}
- fn read(source: &mut impl std::io::Read) -> std::io::Result<Self> {
+ fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> {
let (r, g, b) = source.get()?;
Ok(Self { r, g, b })
}
diff --git a/evc/src/ser.rs b/evc/src/ser.rs
index 2d0bc82..6e1ef98 100644
--- a/evc/src/ser.rs
+++ b/evc/src/ser.rs
@@ -1,61 +1,62 @@
-use std::io::{self, Read, Write};
+use anyhow::Context;
+use std::io::{Read, Write};
pub trait Sink {
- fn put<V: Ser>(&mut self, value: V) -> io::Result<()>;
+ fn put<V: Ser>(&mut self, value: V) -> anyhow::Result<()>;
}
pub trait Source {
- fn get<V: Ser>(&mut self) -> io::Result<V>;
+ fn get<V: Ser>(&mut self) -> anyhow::Result<V>;
}
impl<T: Write> Sink for T {
- fn put<V: Ser>(&mut self, value: V) -> io::Result<()> {
+ fn put<V: Ser>(&mut self, value: V) -> anyhow::Result<()> {
value.write(self)
}
}
impl<T: Read> Source for T {
- fn get<V: Ser>(&mut self) -> io::Result<V> {
+ fn get<V: Ser>(&mut self) -> anyhow::Result<V> {
V::read(self)
}
}
pub trait Ser: Sized {
- fn write(&self, sink: &mut impl Write) -> io::Result<()>;
- fn read(source: &mut impl Read) -> io::Result<Self>;
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()>;
+ fn read(source: &mut impl Read) -> anyhow::Result<Self>;
}
impl<A: Ser, B: Ser> Ser for (A, B) {
- fn write(&self, sink: &mut impl Write) -> io::Result<()> {
- self.0.write(sink)?;
- self.1.write(sink)?;
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ self.0.write(sink).context("first tuple field")?;
+ self.1.write(sink).context("second tuple field")?;
Ok(())
}
- fn read(source: &mut impl Read) -> io::Result<Self> {
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
Ok((A::read(source)?, B::read(source)?))
}
}
impl<A: Ser, B: Ser, C: Ser> Ser for (A, B, C) {
- fn write(&self, sink: &mut impl Write) -> io::Result<()> {
- self.0.write(sink)?;
- self.1.write(sink)?;
- self.2.write(sink)?;
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ self.0.write(sink).context("first tuple field")?;
+ self.1.write(sink).context("second tuple field")?;
+ self.2.write(sink).context("third tuple field")?;
Ok(())
}
- fn read(source: &mut impl Read) -> io::Result<Self> {
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
Ok((A::read(source)?, B::read(source)?, C::read(source)?))
}
}
impl<A: Ser, const N: usize> Ser for [A; N] {
- fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
for e in self {
- e.write(sink)?;
+ e.write(sink).context("some array")?;
}
Ok(())
}
- fn read(source: &mut impl Read) -> io::Result<Self> {
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
let mut k: [A; N] = unsafe { std::mem::zeroed() };
for i in 0..N {
k[i] = A::read(source)?;
@@ -65,15 +66,15 @@ impl<A: Ser, const N: usize> Ser for [A; N] {
}
impl<T: Ser> Ser for Vec<T> {
- fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
self.len().write(sink)?;
for e in self {
- e.write(sink)?;
+ e.write(sink).context("some vec")?;
}
Ok(())
}
- fn read(source: &mut impl Read) -> io::Result<Self> {
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
let mut v = vec![];
for _ in 0..usize::read(source)? {
v.push(T::read(source)?)
@@ -83,70 +84,82 @@ impl<T: Ser> Ser for Vec<T> {
}
impl Ser for u8 {
- fn write(&self, sink: &mut impl Write) -> io::Result<()> {
- sink.write_all(&[*self])
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ Ok(sink.write_all(&[*self]).context("write u8")?)
}
- fn read(source: &mut impl Read) -> io::Result<Self> {
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
let mut buf = [0u8; 1];
source.read_exact(&mut buf)?;
Ok(buf[0])
}
}
impl Ser for u16 {
- fn write(&self, sink: &mut impl Write) -> io::Result<()> {
- sink.write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 2]>(self) })
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 2]>(self) })
+ .context("write 16")?)
}
- fn read(source: &mut impl Read) -> io::Result<Self> {
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
let mut buf = [0u8; 2];
source.read_exact(&mut buf)?;
Ok(unsafe { std::mem::transmute_copy(&buf) })
}
}
impl Ser for u32 {
- fn write(&self, sink: &mut impl Write) -> io::Result<()> {
- sink.write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 4]>(self) })
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 4]>(self) })
+ .context("write u32")?)
}
- fn read(source: &mut impl Read) -> io::Result<Self> {
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
let mut buf = [0u8; 4];
source.read_exact(&mut buf)?;
Ok(unsafe { std::mem::transmute_copy(&buf) })
}
}
impl Ser for u64 {
- fn write(&self, sink: &mut impl Write) -> io::Result<()> {
- sink.write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ .context("write u64")?)
}
- fn read(source: &mut impl Read) -> io::Result<Self> {
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
let mut buf = [0u8; 8];
source.read_exact(&mut buf)?;
Ok(unsafe { std::mem::transmute_copy(&buf) })
}
}
impl Ser for usize {
- fn write(&self, sink: &mut impl Write) -> io::Result<()> {
- sink.write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ .context("write usize")?)
}
- fn read(source: &mut impl Read) -> io::Result<Self> {
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
let mut buf = [0u8; 8];
source.read_exact(&mut buf)?;
Ok(unsafe { std::mem::transmute_copy(&buf) })
}
}
impl Ser for f32 {
- fn write(&self, sink: &mut impl Write) -> io::Result<()> {
- sink.write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 4]>(self) })
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 4]>(self) })
+ .context("write f32")?)
}
- fn read(source: &mut impl Read) -> io::Result<Self> {
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
let mut buf = [0u8; 4];
source.read_exact(&mut buf)?;
Ok(unsafe { std::mem::transmute_copy(&buf) })
}
}
impl Ser for f64 {
- fn write(&self, sink: &mut impl Write) -> io::Result<()> {
- sink.write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ .context("write f64")?)
}
- fn read(source: &mut impl Read) -> io::Result<Self> {
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
let mut buf = [0u8; 8];
source.read_exact(&mut buf)?;
Ok(unsafe { std::mem::transmute_copy(&buf) })
@@ -155,10 +168,18 @@ impl Ser for f64 {
#[cfg(test)]
mod test {
- use super::Sink;
+ use super::{Ser, Sink};
+ use crate::header::Header;
use crate::ser::Source;
+ use std::fmt::Debug;
use std::io::Cursor;
+ fn test_ser<T: PartialEq + Ser + Debug + Copy>(value: T) {
+ let mut buf = vec![];
+ Cursor::new(&mut buf).put(value).unwrap();
+ assert_eq!(value, Cursor::new(&mut buf).get().unwrap());
+ }
+
#[test]
fn simple() {
let mut buf = vec![];
@@ -171,4 +192,11 @@ mod test {
Cursor::new(&mut buf).put((10usize, 5u8, 3u16)).unwrap();
assert_eq!((10usize, 5u8, 3u16), Cursor::new(&mut buf).get().unwrap());
}
+ #[test]
+ fn header() {
+ test_ser(Header {
+ frame_count: 123,
+ resolution: (13, 37),
+ });
+ }
}