Rust development guide¶
This page covers getting started with the VMAFX Rust bindings.
Overview¶
The repository ships a Rust workspace at the repo root (Cargo.toml). Its first member is bindings/rust/vmafx-sys, the low-level FFI crate.
| Crate | Description |
|---|---|
vmafx-sys | Auto-generated raw FFI bindings + thin safe wrappers. |
A higher-level vmafx crate is planned for a future PR.
Prerequisites¶
Rust toolchain¶
Install the stable toolchain via rustup:
The crate targets Rust 2021 edition. Any stable release from 1.65+ is sufficient.
libvmaf¶
vmafx-sys links against libvmaf.so at runtime and uses its headers at build time. You must have a compatible install of libvmaf before running cargo build.
Option A — system install (recommended for development)¶
# From the repo root:
meson setup build -Denable_cuda=false -Denable_sycl=false
ninja -C build
sudo ninja -C build install # installs to /usr/local by default
sudo ldconfig # refresh the dynamic linker cache
Verify the install:
pkg-config --modversion libvmaf # should print the library version
ls /usr/local/lib/libvmaf.so # should exist
Option B — non-standard prefix¶
If you install to a prefix other than /usr/local, set:
export LIBVMAF_PREFIX=$HOME/.local
export PKG_CONFIG_PATH=$LIBVMAF_PREFIX/lib/pkgconfig
export LD_LIBRARY_PATH=$LIBVMAF_PREFIX/lib:$LD_LIBRARY_PATH
build.rs reads LIBVMAF_PREFIX to locate both the headers (used by bindgen) and the shared library (used by the linker).
Using vmafx-sys as a dependency¶
Add to your crate's Cargo.toml:
Once the crate is published to crates.io, you will instead write:
The safe vs sys API split¶
vmafx-sys exposes two layers.
Raw layer (use vmafx_sys::*)¶
Auto-generated by bindgen from libvmaf.h. Every C type, constant, and function is available. Use this layer when you need access to functionality not yet wrapped by the safe layer.
Safe layer (use vmafx_sys::safe::*)¶
Thin RAII wrappers that:
- Manage object lifetimes automatically (
VmafContextcloses on drop,VmafModeldestroys on drop). - Convert negative C error codes into
Result<T, VmafxError>. - Confine
unsafeto the actual FFI call sites only. - Mark all types
Send.
use vmafx_sys::safe::{VmafContext, VmafModel, alloc_yuv420p_8bit, unref_picture};
let mut ctx = VmafContext::new()?;
let mut model = VmafModel::from_path("/usr/local/share/model/vmaf_v0.6.1.json")?;
ctx.use_features_from_model(&mut model)?;
// Queue frames...
let mut ref_pic = alloc_yuv420p_8bit(576, 324)?;
let mut dist_pic = alloc_yuv420p_8bit(576, 324)?;
// ... fill pic.data[0..3] with YUV plane bytes ...
ctx.read_pictures(&mut ref_pic, &mut dist_pic, 0)?;
ctx.flush()?;
let score = ctx.score_pooled(&mut model, 0, 0)?;
Building¶
Running the smoke test¶
VMAFX_REPO=$(git rev-parse --show-toplevel) \
LD_LIBRARY_PATH=/usr/local/lib \
cargo run --example score
Expected output:
vmafx-sys version: 3.x.y-lusoris.N
Reference: .../python/test/resource/yuv/src01_hrc00_576x324.yuv
Distorted: .../python/test/resource/yuv/src01_hrc01_576x324.yuv
Model: .../model/vmaf_v0.6.1.json
Frames processed: 240
Mean VMAF score: 76.6680
Score assertion PASSED (expected 76.6680)
Running tests¶
VMAFX_REPO=$(git rev-parse --show-toplevel) \
LD_LIBRARY_PATH=/usr/local/lib \
cargo test -p vmafx-sys --all-features
The integration test (tests/integration_test.rs) scores the Netflix golden YUV pair and asserts the mean VMAF equals 76.668 (places=4). If the YUV files are not present (e.g. a CI environment without test fixtures), the test skips gracefully.
Linting¶
These two gates run in CI on every PR touching bindings/rust/.
Environment variables reference¶
| Variable | Default | Description |
|---|---|---|
LIBVMAF_PREFIX | /usr/local | libvmaf install prefix. Used by build.rs. |
VMAFX_REPO | auto-detected from CARGO_MANIFEST_DIR | Repo root; used to resolve test fixtures. |
VMAFX_YUV_REF | <VMAFX_REPO>/python/test/resource/yuv/src01_hrc00_576x324.yuv | Reference YUV override. |
VMAFX_YUV_DIST | <VMAFX_REPO>/python/test/resource/yuv/src01_hrc01_576x324.yuv | Distorted YUV override. |
VMAFX_MODEL | <VMAFX_REPO>/model/vmaf_v0.6.1.json | Model path override. |
Troubleshooting¶
error: could not find native library 'vmaf'¶
The linker cannot find libvmaf.so. Fix:
error: failed to run custom build command for vmafx-sys¶
bindgen failed to parse the header. Check that:
LIBVMAF_PREFIXpoints to a directory containinginclude/libvmaf/libvmaf.h.clang/libclang-devis installed.
cargo: error[E0425]: cannot find function ...¶
The installed libvmaf version is older than expected. Build from source (Option A above) rather than using the distro package.