/rav1d

An AV1 decoder in Rust.

Primary LanguageAssemblyBSD 2-Clause "Simplified" LicenseBSD-2-Clause

rav1d

rav1d is an AV1 cross-platform decoder, open-source, and focused on speed and correctness. It is a Rust port of dav1d.

Building

rav1d is written in Rust and uses the standard Rust toolchain to build. The Rust toolchain can be installed by going to https://rustup.rs. The rav1d library builds on stable Rust for x86, x86_64, and aarch64, but currently requires a nightly compiler for arm and riscv64. The project is configured to use a nightly compiler by default via rust-toolchain.toml, but a stable library build can be made with the +stable cargo flag.

For x86 targets, you'll also need to install nasm in order to build with assembly support.

A release build can then be made using cargo:

cargo build --release

For development purposes you may also want to use the opt-dev profile, which runs faster than a regular debug build but has all debug checks still enabled:

cargo build --profile opt-dev

To build just librav1d using a stable compiler:

cargo +stable build --lib --release

Feature Flags

The following feature flags are supported:

  • asm - Enables optimized assembly routines, if available for the target platform.
  • bitdepth_8 - Enables support for 8 bitdepth decoding.
  • bitdepth_16 - Enables support for 10 and 12 bitdepth decoding.

All of these features are enabled by default. In order to build a version of librav1d that disables one or more of these features use the --no-default-features flag in combination with the --features flag to enable any desired features. For example, to build without assembly routines, which is useful when testing the Rust fallback functions, do the following:

cargo build --no-default-features --features="bitdepth_8,bitdepth_16"

Cross-Compiling

rav1d can be cross-compiled for a target other than the host platform using the cargo --target flag. This will require passing additional arguments to rustc to tell it what linker to use. This can be done by setting the RUSTFLAGS enviroment variable and specifying the linker compiler flag. For example, compiling for aarch64-unknown-linux-gnu from an Ubuntu Linux machine would be done as follows:

RUSTFLAGS="-C linker=aarch64-linux-gnu-gcc" cargo build --target aarch64-unknown-linux-gnu

If you're cross-compiling in order to run tests under QEMU (qemu-*-static) you'll also need to specify the +crt-static target feature.

RUSTFLAGS="-C target-feature=+crt-static -C linker=aarch64-linux-gnu-gcc" cargo build --target aarch64-unknown-linux-gnu

This will require installing the rustup component for the target platform and the appropriate cross-platform compiler/linker toolchain for your target platform. Examples of how we cross-compile rav1d in CI can be found in .github/workflows/build-and-test-qemu.yml.

The following targets are currently supported:

  • x86_64-unknown-linux-gnu
  • i686-unknown-linux-gnu
  • armv7-unknown-linux-gnueabihf
  • aarch64-unknown-linux-gnu
  • riscv64gc-unknown-linux-gnu

Running Tests

Currently we use the original Meson test suite for testing the Rust port. This means you'll need to have Meson installed to run tests.

To setup and run the tests, do the following:

First, build rav1d using cargo. You'll need to do this step manually before running any tests because it is not built automatically when tests are run. It's recommended to run tests with either the release or opt-dev profile as the debug build runs slowly and often causes tests to timeout. The opt-dev profile is generally ideal for development purposes as it enables some optimizations while leaving debug checks enabled.

cargo build --release

Or:

cargo build --profile opt-dev

Then you can run the tests with the test.sh helper script:

.github/workflows/test.sh -r target/release/dav1d

Or:

.github/workflows/test.sh -r target/opt-dev/dav1d

The test script accepts additional arguments to configure how tests are run:

  • -s PATH - Specify a path to the seek_stress binary in order to run the seek_stress tests. This is generally in the same output directory as the main dav1d binary, e.g. target/release/seek_stress.
  • -t MULTIPLIER - Specify a multiplier for the test timeout. Allows for tests to take longer to run, e.g. if running tests with a debug build.
  • -f DELAY - Specify a frame delay for the tests. If specified the tests will also be run with multiple threads.
  • -n - Test with negative strides.
  • -w WRAPPER - Specify a wrapper binary to use to run the tests. This is necessary for testing under QEMU for platforms other than the host platform.

You can learn more about how to build and test by referencing the CI scripts in the .github/workflows folder.

Using rav1d

librav1d is designed to be a drop-in replacement for libdav1d, so it primarily exposes a C API with the same usage as libdav1d's. This is found in the librav1d.a library generated by cargo build. libdav1d's primary API documentation can be found here for reference, and the equivalent Rust functions can be found in src/lib.rs. You can also reference the dav1d binary's code to see how it uses the API, which can be found at tools/dav1d.rs.

A Rust API is planned for addition in the future.