# rav1d **rav1d** is an AV1 cross-platform decoder, open-source, and focused on speed and correctness. It is a Rust port of [dav1d](https://code.videolan.org/videolan/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`](https://nasm.us/) in order to build with assembly support. A release build can then be made using cargo: ```sh 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: ```sh cargo build --profile opt-dev ``` To build just `librav1d` using a stable compiler: ```sh 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: ```sh 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: ```sh 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. ```sh 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`](.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](https://mesonbuild.com/) test suite for testing the Rust port. This means you'll need to [have Meson installed](https://mesonbuild.com/Getting-meson.html) 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. ```sh cargo build --release ``` Or: ```sh cargo build --profile opt-dev ``` Then you can run the tests with the [`test.sh`](.github/workflows/test.sh) helper script: ```sh .github/workflows/test.sh -r target/release/dav1d ``` Or: ```sh .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`](.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](https://videolan.videolan.me/dav1d/dav1d_8h.html) for reference, and the equivalent Rust functions can be found in [`src/lib.rs`](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`](tools/dav1d.rs). A [Rust API is planned](https://github.com/memorysafety/rav1d/issues/1252) for addition in the future.