58ccd530fc
ffmpeg-sys-next binds a curated header list that omits every hwcontext_*.h, so AVVulkanDeviceContext/AVVulkanFramesContext/AVVkFrame — the surface that lets FFmpeg's Vulkan Video decoder run on the presenter's own VkDevice and hand the decoded VkImages back — had no Rust bindings at all. pf-ffvk generates them at build time from the SYSTEM headers, which is the only ABI-safe option: the struct layout depends on FF_API_* deprecation gates resolved in libavutil/version.h (confirmed: FFmpeg 8.1 still carries the FIXED_QUEUES fields). Ships ash<->vulkan.h handle conversions; opaque AVHW*/AVFrame types keep ffmpeg-sys-next the owner of the core surface (pointer casts across). Needs vulkan-headers (Arch) / libvulkan-dev (CI, added); PF_FFVK_VULKAN_INCLUDE overrides for cross builds. Verified: bindgen layout tests pass, av_vk_frame_alloc links and zero-initializes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
76 lines
3.4 KiB
Rust
76 lines
3.4 KiB
Rust
//! Generate bindings for `libavutil/hwcontext_vulkan.h` against the SYSTEM headers.
|
|
//!
|
|
//! ffmpeg-sys-next binds a curated header list that omits every hwcontext_*.h; the
|
|
//! Vulkan hwcontext structs (`AVVulkanDeviceContext`, `AVVkFrame`) are what let us run
|
|
//! FFmpeg's Vulkan Video decoder on the presenter's own VkDevice and read the decoded
|
|
//! VkImages back. Their layout depends on compile-time FF_API_* deprecation gates in
|
|
//! libavutil/version.h, so bindgen over the installed header is the only ABI-safe
|
|
//! source of truth — hand transcription would silently skew on the next FFmpeg bump.
|
|
//!
|
|
//! Non-Linux targets get an empty file: the workspace builds on macOS (clients/apple is
|
|
//! the client there), and this shim is Linux-client plumbing only.
|
|
|
|
use std::env;
|
|
use std::path::PathBuf;
|
|
|
|
fn main() {
|
|
println!("cargo:rerun-if-changed=wrapper.h");
|
|
let out = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs");
|
|
|
|
if env::var("CARGO_CFG_TARGET_OS").as_deref() != Ok("linux") {
|
|
std::fs::write(&out, "// pf-ffvk: Linux-only, empty on this target\n").unwrap();
|
|
return;
|
|
}
|
|
|
|
// Include paths from pkg-config (libavutil for the hwcontext header; the Vulkan
|
|
// headers usually live in /usr/include, but honor a registered vulkan.pc too).
|
|
// PF_FFVK_VULKAN_INCLUDE prepends an explicit Vulkan-Headers include dir — for
|
|
// cross builds and boxes without the system package.
|
|
println!("cargo:rerun-if-env-changed=PF_FFVK_VULKAN_INCLUDE");
|
|
let mut includes: Vec<PathBuf> = Vec::new();
|
|
if let Ok(dir) = env::var("PF_FFVK_VULKAN_INCLUDE") {
|
|
includes.push(PathBuf::from(dir));
|
|
}
|
|
let avutil = pkg_config::Config::new()
|
|
.cargo_metadata(false)
|
|
.probe("libavutil")
|
|
.expect("pkg-config: libavutil not found — install the FFmpeg dev package");
|
|
includes.extend(avutil.include_paths);
|
|
if let Ok(vk) = pkg_config::Config::new()
|
|
.cargo_metadata(false)
|
|
.probe("vulkan")
|
|
{
|
|
includes.extend(vk.include_paths);
|
|
}
|
|
|
|
let mut builder = bindgen::Builder::default()
|
|
.header("wrapper.h")
|
|
// The whole point of this crate: the Vulkan hwcontext surface…
|
|
.allowlist_type("AVVulkan.*")
|
|
.allowlist_type("AVVkFrame.*")
|
|
.allowlist_function("av_vk_frame_alloc")
|
|
.allowlist_function("av_vkfmt_from_pixfmt")
|
|
// …plus nothing else of FFmpeg: the core types these structs reference only
|
|
// ever appear behind pointers here, so keep them opaque instead of duplicating
|
|
// ffmpeg-sys-next's definitions (callers cast pointers between the crates).
|
|
.opaque_type("AVHWDeviceContext")
|
|
.opaque_type("AVHWFramesContext")
|
|
.opaque_type("AVBufferRef")
|
|
.opaque_type("AVFrame")
|
|
.derive_debug(false)
|
|
.layout_tests(true);
|
|
for dir in &includes {
|
|
builder = builder.clang_arg(format!("-I{}", dir.display()));
|
|
}
|
|
let bindings = builder.generate().expect(
|
|
"bindgen over libavutil/hwcontext_vulkan.h failed — is `vulkan-headers` installed? \
|
|
(the header includes <vulkan/vulkan.h>)",
|
|
);
|
|
bindings.write_to_file(&out).unwrap();
|
|
|
|
// The av_vk_* symbols live in libavutil, which ffmpeg-sys-next already links into
|
|
// every consumer of this crate; no extra link flags needed. Emitting the lib anyway
|
|
// keeps `cargo test -p pf-ffvk` linking standalone.
|
|
println!("cargo:rustc-link-lib=avutil");
|
|
}
|