aboutsummaryrefslogtreecommitdiff
path: root/framework/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-11-15 20:03:59 +0100
committermetamuffin <metamuffin@disroot.org>2023-11-15 20:03:59 +0100
commit9e1a836f663c03e462fbf1bcff444a20aaf56eaf (patch)
tree90b3fa998cdda4c7d2c22a58b42cdb5a4369f547 /framework/src
parent0196cc1a12cf787a4c5bfc3645b0364eb5daf93a (diff)
downloadvideo-codec-experiments-9e1a836f663c03e462fbf1bcff444a20aaf56eaf.tar
video-codec-experiments-9e1a836f663c03e462fbf1bcff444a20aaf56eaf.tar.bz2
video-codec-experiments-9e1a836f663c03e462fbf1bcff444a20aaf56eaf.tar.zst
a
Diffstat (limited to 'framework/src')
-rw-r--r--framework/src/lib.rs142
-rw-r--r--framework/src/vector.rs128
2 files changed, 270 insertions, 0 deletions
diff --git a/framework/src/lib.rs b/framework/src/lib.rs
index 139597f..89fcc10 100644
--- a/framework/src/lib.rs
+++ b/framework/src/lib.rs
@@ -1,2 +1,144 @@
+use std::{
+ io::{self, stdin, stdout, Read, Write},
+ ops::{Index, IndexMut},
+ time::Instant,
+};
+use vector::{UVec2, Vec2};
+pub mod vector;
+#[derive(Clone)]
+pub struct CodecParams {
+ pub width: usize,
+ pub height: usize,
+ pub debug: usize,
+ pub mode: CodecMode,
+}
+#[derive(Clone)]
+pub enum CodecMode {
+ Encode,
+ Decode,
+}
+
+pub struct Framework {
+ process_start: Instant,
+ params: CodecParams,
+}
+
+impl Framework {
+ pub fn init() -> (Self, CodecParams) {
+ let width = std::env::var("V_WIDTH").unwrap().parse().unwrap();
+ let height = std::env::var("V_HEIGHT").unwrap().parse().unwrap();
+ let debug = std::env::var("V_DEBUG").unwrap().parse().unwrap();
+ let mode = match std::env::var("V_MODE").unwrap().as_str() {
+ "encode" => CodecMode::Encode,
+ "decode" => CodecMode::Decode,
+ _ => panic!("invalid mode"),
+ };
+ let params = CodecParams {
+ height,
+ width,
+ debug,
+ mode,
+ };
+ (
+ Self {
+ params: params.clone(),
+ process_start: Instant::now(),
+ },
+ params,
+ )
+ }
+
+ pub fn next_frame(&mut self) -> Option<Frame> {
+ self.process_start = Instant::now();
+ Some(Frame::read(self.params.width, self.params.height, stdin()).unwrap())
+ }
+ pub fn encode_done(&mut self, output: &[u8]) {
+ let el = self.process_start.elapsed();
+ eprintln!("size={}Kb t={el:?}", output.len() / 1000 * 8)
+ }
+
+ pub fn next_chunk(&mut self, buffer: &mut Vec<u8>) -> bool {
+ true
+ }
+ pub fn decode_done(&mut self, output: &Frame) {
+ output.write(stdout()).unwrap();
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct Frame {
+ pub width: usize,
+ pub height: usize,
+ pub pixels: Vec<Pixel<u8>>,
+}
+
+#[derive(Debug, Clone, Copy)]
+pub struct Pixel<T> {
+ pub r: T,
+ pub g: T,
+ pub b: T,
+}
+pub type EPixel = Pixel<u8>;
+
+impl Frame {
+ pub fn new(width: usize, height: usize) -> Self {
+ Self {
+ height,
+ width,
+ pixels: vec![Pixel::BLACK; width * height],
+ }
+ }
+ pub fn read(width: usize, height: usize, mut r: impl Read) -> io::Result<Self> {
+ let mut f = Frame::new(width, height);
+ let p = unsafe {
+ std::slice::from_raw_parts_mut(
+ f.pixels.as_mut_slice().as_mut_ptr() as *mut u8,
+ width * height * 3,
+ )
+ };
+ r.read_exact(p)?;
+ Ok(f)
+ }
+ pub fn write(&self, mut w: impl Write) -> io::Result<()> {
+ let p = unsafe {
+ std::slice::from_raw_parts(
+ self.pixels.as_slice().as_ptr() as *const u8,
+ self.width * self.height * 3,
+ )
+ };
+ w.write_all(p)
+ }
+}
+
+impl Index<(usize, usize)> for Frame {
+ type Output = Pixel<u8>;
+ #[inline]
+ fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
+ &self.pixels[x + y * self.width]
+ }
+}
+impl IndexMut<(usize, usize)> for Frame {
+ #[inline]
+ fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
+ &mut self.pixels[x + y * self.width]
+ }
+}
+impl Index<UVec2> for Frame {
+ type Output = Pixel<u8>;
+ #[inline]
+ fn index(&self, Vec2 { x, y }: UVec2) -> &Self::Output {
+ &self.pixels[x + y * self.width]
+ }
+}
+impl IndexMut<UVec2> for Frame {
+ #[inline]
+ fn index_mut(&mut self, Vec2 { x, y }: UVec2) -> &mut Self::Output {
+ &mut self.pixels[x + y * self.width]
+ }
+}
+
+impl Pixel<u8> {
+ pub const BLACK: Pixel<u8> = Pixel { r: 0, g: 0, b: 0 };
+}
diff --git a/framework/src/vector.rs b/framework/src/vector.rs
new file mode 100644
index 0000000..5227d04
--- /dev/null
+++ b/framework/src/vector.rs
@@ -0,0 +1,128 @@
+pub type UVec2 = Vec2<usize>;
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Vec2<T> {
+ pub x: T,
+ pub y: T,
+}
+
+impl From<Vec2<isize>> for Vec2<u16> {
+ fn from(value: Vec2<isize>) -> Self {
+ Self {
+ x: value.x as u16,
+ y: value.y as u16,
+ }
+ }
+}
+impl From<Vec2<u16>> for Vec2<isize> {
+ fn from(value: Vec2<u16>) -> Self {
+ Self {
+ x: value.x as isize,
+ y: value.y as isize,
+ }
+ }
+}
+impl From<Vec2<f32>> for Vec2<isize> {
+ fn from(value: Vec2<f32>) -> Self {
+ Self {
+ x: value.x as isize,
+ y: value.y as isize,
+ }
+ }
+}
+
+impl Vec2<isize> {
+ pub const ZERO: Vec2<isize> = Vec2 { x: 0, y: 0 };
+ pub const UP: Vec2<isize> = Vec2 { x: 0, y: -1 };
+ pub const LEFT: Vec2<isize> = Vec2 { x: -1, y: 0 };
+}
+impl Vec2<f32> {
+ pub const ZERO: Vec2<f32> = Vec2 { x: 0.0, y: 0.0 };
+ pub const UP: Vec2<f32> = Vec2 { x: 0.0, y: -1.0 };
+ pub const LEFT: Vec2<f32> = Vec2 { x: -1.0, y: 0.0 };
+}
+
+impl<T: std::ops::Div<Output = T> + Copy> Vec2<T> {
+ pub fn downscale(&self, f: T) -> Self {
+ Self {
+ x: self.x / f,
+ y: self.y / f,
+ }
+ }
+}
+
+impl<T: std::ops::Mul<Output = T> + Copy> Vec2<T> {
+ pub fn scale(&self, f: T) -> Self {
+ Self {
+ x: self.x * f,
+ y: self.y * f,
+ }
+ }
+ pub fn area(&self) -> T {
+ self.x * self.y
+ }
+}
+
+impl Vec2<isize> {
+ pub fn x_only(&self) -> Self {
+ Self { x: self.x, y: 0 }
+ }
+ pub fn y_only(&self) -> Self {
+ Self { x: 0, y: self.y }
+ }
+}
+
+impl Into<Vec2<f32>> for Vec2<isize> {
+ fn into(self) -> Vec2<f32> {
+ Vec2 {
+ x: self.x as f32,
+ y: self.y as f32,
+ }
+ }
+}
+impl From<(isize, isize)> for Vec2<f32> {
+ fn from((x, y): (isize, isize)) -> Self {
+ Vec2 {
+ x: x as f32,
+ y: y as f32,
+ }
+ }
+}
+
+impl<T: std::ops::Add> std::ops::Add for Vec2<T> {
+ type Output = Vec2<T::Output>;
+ #[inline]
+ fn add(self, rhs: Self) -> Self::Output {
+ Vec2 {
+ x: self.x + rhs.x,
+ y: self.y + rhs.y,
+ }
+ }
+}
+impl<T: std::ops::Sub> std::ops::Sub for Vec2<T> {
+ type Output = Vec2<T::Output>;
+ #[inline]
+ fn sub(self, rhs: Self) -> Self::Output {
+ Vec2 {
+ x: self.x - rhs.x,
+ y: self.y - rhs.y,
+ }
+ }
+}
+impl<T: std::ops::Mul> std::ops::Mul for Vec2<T> {
+ type Output = Vec2<T::Output>;
+ #[inline]
+ fn mul(self, rhs: Self) -> Self::Output {
+ Vec2 {
+ x: self.x * rhs.x,
+ y: self.y * rhs.y,
+ }
+ }
+}
+
+impl<T> From<(T, T)> for Vec2<T> {
+ #[inline]
+ fn from((x, y): (T, T)) -> Self {
+ Vec2 { x, y }
+ }
+}