Crates.io | syeve |
lib.rs | syeve |
version | 0.1.0 |
source | src |
created_at | 2021-09-28 21:49:21.116944 |
updated_at | 2021-09-28 21:49:21.116944 |
description | Simple yet efficient video encoding (lossless streaming codec) |
homepage | |
repository | https://framagit.org/ZettaScript/syeve |
max_upload_size | |
id | 457799 |
size | 81,964 |
This is a lossless video codec, aiming at screen capture and anything else you'd want to format in PNG instead of JPEG. It is the equivalent of PNG for video.
As PNG, there are two steps: filtering, and compressing.
The filter transforms the pixels into the differences between adjacent pixels. This way adjacent pixels with the same color have the value 0, and linear gradients become constant series. The filtered image is now easier to compress with a conventional algorithm.
The difference with PNG is that the filter also takes the difference across time, so that if the frames are almost the same, they will be full of zeros.
Run a P2P video-conferencing example:
# Run these commands in two different terminals or machines
cargo run --release -p conference -- server 0.0.0.0:8080
cargo run --release -p conference -- client 127.0.0.1:8080
(change 127.0.0.1
to the server address)
// Let `input_raw_frame: Vec<u8>` be an RGB24 bitmap of size 1920*1080
let mut buf = Vec::new();
let mut encoder = syeve::Encoder::new((1920, 1080), 3, syeve::Compression::Brotli(4), 30);
encoder.encode(&mut input_raw_frame, &mut buf).unwrap();
let mut decoder = syeve::Decoder::new();
let output_raw_frame = decoder.decode(&buf).unwrap().pixels;
Lossy video formats are very efficient, but:
⚠ unstable, not benchmarked, not fuzz-tested... but promising 😎
Single frame encoding is faster than with image-rs/image-png
(thanks to SIMD optimization).
Any help with optimization (potentially lossy) or benchmark or else would be greatly appreciated. (PR/issue/email welcome)
The protocol is extremely simple: comparable to PNG, but each frame depends on the previous frame.
"data" is the filtered bitmap image, compressed with the specified algo. Its length is width*height*pixel_size
. (pixel_size
is the number of bytes per pixel, generally 3 for RGB and 4 for RGBA)
Compression algos:
The first frame should have frame number to zero. Frame number must be incremented by one between each frame. Because each frame depends on the previous frame, a frame loss may result in a broken frame for the decoder. This problem is reduced by sending periodically a fully self-described frame. This frame should have frame number to zero, and a sequence number different from the previous frame (typically incremented by one). The sequence number of the first frame can be random.
CopyLeft 2021 Pascal Engélibert
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.