Load libva at runtime via dlopen instead of linking#1
Conversation
Switch the bindgen bindings to dynamic-loading mode so libva is dlopen'd
at runtime instead of linked at build time. The build no longer depends
on libva at all (only libclang plus the vendored headers), and the
resulting binary carries no NEEDED libva, so it loads on a libva-less
host and the caller can fall back to another encoder.
Previously build.rs probed libva/libva-drm via pkg-config whenever the
target OS was Linux, which required libva-dev at build time and made the
binary hard-link libva.so.2. It also broke the docs.rs build, since
docs.rs builds on Linux with no libva-dev installed.
- bindgen_gen.rs: dynamic_library_name("Va") + dynamic_link_require_all(false)
- build.rs: drop the pkg-config link step
- src/bindings.rs: OnceLock-cached load()/va() over libloading. Load
libva-drm.so.2, whose NEEDED libva.so.2 exposes the core va* symbols
through dlsym's dependency search.
- Display::open_drm_display loads libva up front and returns a new
LibvaUnavailable error, so a libva-less host falls back gracefully
instead of aborting at process load.
- rewrite the 40 va* call sites through the loaded accessor
- Cargo.toml: add libloading, drop the pkg-config build-dep
Tested on an aarch64 Linux host with no libva installed: the crate
builds with rust + clang only, the probe binary has no NEEDED libva, and
Display::open() returns None gracefully. Installing the libva runtime
libs advances past load() (dlopen resolves) and still falls back cleanly.
Real VAAPI hardware encode is unverified (needs an x86 box with a driver).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Sorry @kixelated, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
|
Warning Review limit reached
Next review available in: 54 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (12)
✨ Finishing Touches✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
1 similar comment
|
Warning Review limit reached
Next review available in: 54 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (12)
✨ Finishing Touches✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What
Switch the bindgen bindings from link-time
extern "C"declarations to bindgen's dynamic-loading mode, so libva isdlopen'd at runtime rather than linked at build time.bindgen_gen.rs:.dynamic_library_name("Va").dynamic_link_require_all(false)— bindgen emits aVastruct oflibloading-resolved function pointers (77va*wrappers) with zeroextern "C"link blocks.require_all(false)lets a system libva older than the vendored headers still load (a missing symbol only errors if actually called).build.rs: delete thepkg_config::probe("libva"/"libva-drm")block. No link step; the build needs only libclang + the vendored headers.src/bindings.rs: aOnceLock-cachedload()/va()accessor overlibloading. Itdlopenslibva-drm.so.2, whoseNEEDED libva.so.2exposes the coreva*symbols via dlsym's dependency search, so one load covers bothvaGetDisplayDRMand the rest.display.rs:Display::open_drm_displaycallsload()up front and returns a newOpenDrmDisplayError::LibvaUnavailableon failure, so a libva-less host falls back gracefully (Display::open()→None) instead of aborting at process load.bindings::vaFoo(call sites now go throughbindings::va().vaFoo(.Cargo.toml: addlibloading, drop thepkg-configbuild-dep.Why
build.rsprobed libva/libva-drm via pkg-config whenever the target OS was Linux, which (a) requiredlibva-devat build time and (b) made the binary hard-linklibva.so.2, so a libva-less host failed to load rather than falling back. It also broke the docs.rs build (docs.rs builds on Linux with nolibva-dev), which is what surfaced this. This is the fix tracked in moq #1837, and theflake.nixcomment already described this intended behavior ("libva is dlopen'd at runtime, not linked at build") — the code now matches it.Testing
Verified on an aarch64 Linux host with no libva installed (rust + clang only):
NEEDED libva(ldd) — dlopen, not link.open_drm_displayreturnsErr(LibvaUnavailable("libva-drm.so.2: cannot open shared object file")),Display::open()→None, exit 0, no panic.libva2/libva-drm2, no-dev), the probe clearsload()and fails later at device open — confirming the dlopen resolves — and still falls back cleanly.Not tested: a real VAAPI hardware encode. That needs an x86 host with a working Intel/AMD driver; the test host is ARM with no GPU. Worth a smoke encode before publishing
0.0.3.Follow-up (not in this PR)
Publish as
moq-vaapi 0.0.3, then in the moq monorepo bumpmoq-vaapi = "0.0.3", correct the stale "hard-links libva" comments inrs/moq-video/Cargo.toml, and drop the temporary[package.metadata.docs.rs]stopgap so docs.rs documents thevaapifeature again.🤖 Generated with Claude Code
(written by Opus 4.8)