ralfbiedert / openh264-rs

Idiomatic Rust wrappers around OpenH264.
69 stars 35 forks source link

Latest Version docs ![BSD-2] Rust Rust

OpenH264 Rust API

Idiomatic and low-level bindings for OpenH264, converting between these two in Rust:

sample_image

Example API

Decode some H.264 bitstream to YUV:

use openh264::decoder::Decoder;
use openh264::nal_units;

let h264_in = include_bytes!("../tests/data/multi_512x512.h264");
let mut decoder = Decoder::new()?;

// Split H.264 into NAL units and decode each.
for packet in nal_units(h264_in) {
    // On the first few frames this may fail, so you should check the result
    // a few packets before giving up.
    let maybe_some_yuv = decoder.decode(packet);
}

And encode the same YUV back to H.264:

use openh264::encoder::Encoder;

let mut encoder = Encoder::new()?;

// Encode YUV back into H.264.
let bitstream = encoder.encode(&yuv)?;

Platform Support

Test results on various platforms:

Platform Compiled Unit Tested
x86_64-pc-windows-msvc
x86_64-pc-windows-gnu
x86_64-unknown-linux-gnu
x86_64-apple-darwin
i686-unknown-linux-gnu
i686-pc-windows-msvc
i686-pc-windows-gnu
armv7-unknown-linux-gnueabihf -
aarch64-unknown-linux-gnu -
aarch64-apple-darwin -
aarch64-pc-windows-msvc -
aarch64-linux-android 🆗1 -
wasm32-unknown-unknown 2 -

✅ works out of the box; 🆗 the usual shenanigans required; ❌ not supported.

1 via cargo build --target <platform>, needs CXX set and libc++_shared.so.
2 unclear if could ever work, investigation welcome

Performance

Tested on a i9-9900K, Windows 10, single threaded de- and encoding:

-- Default --
test decode_yuv_single_1920x1080     ... bench:   9,243,380 ns/iter (+/- 497,200)
test decode_yuv_single_512x512_cabac ... bench:   1,841,775 ns/iter (+/- 53,211)
test decode_yuv_single_512x512_cavlc ... bench:   2,076,030 ns/iter (+/- 7,287)
test encode_1920x1080_from_yuv       ... bench:  38,657,620 ns/iter (+/- 793,310)
test encode_512x512_from_yuv         ... bench:   6,420,605 ns/iter (+/- 1,003,485)

-- If `nasm` available --
test decode_yuv_single_1920x1080     ... bench:   4,265,260 ns/iter (+/- 89,438)
test decode_yuv_single_512x512_cabac ... bench:     901,025 ns/iter (+/- 21,902)
test decode_yuv_single_512x512_cavlc ... bench:   1,618,880 ns/iter (+/- 53,713)
test encode_1920x1080_from_yuv       ... bench:  13,455,160 ns/iter (+/- 862,042)
test encode_512x512_from_yuv         ... bench:   4,011,700 ns/iter (+/- 2,094,471)

-- Color Conversion --
test convert_yuv_to_rgb_1920x1080    ... bench:   7,226,290 ns/iter (+/- 110,871)
test convert_yuv_to_rgb_512x512      ... bench:     907,340 ns/iter (+/- 28,296)

Compile Features

FAQ

Contributing

PRs are very welcome. Feel free to submit PRs and fixes right away. You can open issues if you want to discuss things, but due to time restrictions on my side the project will have to rely on people contributing.

Especially needed:

Changelog

License