Giter Club home page Giter Club logo

openh264-rust's Introduction

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, EncoderConfig};

let config = EncoderConfig::new(512, 512);
let mut encoder = Encoder::with_config(config)?;

// 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-unknown-linux-gnu
x86_64-apple-darwin
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

  • decoder - Enable the decoder. Used by default.
  • encoder - Enable the encoder. Used by default.

FAQ

  • How does openh264-sys2 differ from openh264-sys?

    We directly ship OpenH264 source code and provide simple, hand-crafted compilation via cc in build.rs. Ouropenh264-sys2 crate should compile via cargo build out of the box on most platforms, and cross-compile via cargo build --target ... as long as the environment variable CXX is properly set.

  • Which exact OpenH264 version does this use?

    See this file for the upstream URL and Git hash used on latest master.

  • I need to fix an important OpenH264 security hole, how can I update the library?

    Cisco's OpenH264 library is contained in openh264-sys2/upstream. Updating is as simple as pulling their latest source, and running update_openh264.sh (and, if APIs changed, regen-bindings.bat).

  • I heard Rust is super-safe, will this make decoding my videos safe too?

    No. Below a thin Rust layer we rely on a very complex C library, and an equally complex standard. Apart from Rust being a much nicer language to work with, depending on this project will give you no additional safety guarantees as far as video handling is concerned. FYI, this is not making a statement about OpenH264, but about the realities of securing +50k lines of C against attacks.

  • Feature X is missing or broken, will you fix it?

    Right now I only have time to implement what I need. However, I will gladly accept PRs either extending the APIs, or fixing bugs; see below.

  • Can I get a performance boost?

    Make sure you have the command nasm somewhere in your PATH for your current platform (should be a single, standalone executable you don't even need to install). If found by build.rs it should be used automatically for an up to 3x speed boost.

  • Decoder::decode() returned an error, is this a bug?

    Maybe. Probably not. Some encoders can write data OpenH264 doesn't understand, and if all frames fail this could either be your encoder doing exotic things, OpenH264 not having implemented a certain feature, or us having a bug.

    If only some frames fail the most likely reasons are your encoder injecting some special packets or transmission errors. In other words, unless you have a controlled setup you should not terminate on the first error(s), but simply continue decoding and hope for the decoder to recover.

    FWIW, we consider OpenH264's h264dec the reference decoder. If you can get it to emit YUV it would be a bug if we can't. However, any stream / frame it fails on is pretty much a wontfix for us.

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:

  • BT.601 / BT.709 YUV <-> RGB Conversion
  • Faster YUV to RGB conversion
  • WASM investigation (either patch, or evidence it can't be fixed)
  • Feedback which platforms successfully built on

Changelog

  • v0.3 - Change some APIs to better reflect OpenH264 behavior.
  • v0.2 - Added encoder; asm feature for 2x - 3x speed boost.
  • v0.1 - Initial release, decoder only.

License

  • OpenH264 core library is BSD-2, Cisco.
  • Wrapper code is BSD-2, Ralf Biedert.

openh264-rust's People

Contributors

astraw avatar gil0mendes avatar jelmansouri avatar ralfbiedert avatar repnop avatar sandeepbansal avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.