Add AVHeader type to build.rs (#39)
* Rename `is_feature` to `optional` * Replace Library::new with two separate functions * Add AVHeader abstraction * Add Library::enabled helper function
This commit is contained in:
parent
3206eedcf0
commit
22fda65cda
@ -17,30 +17,53 @@ use bindgen::callbacks::{
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Library {
|
struct Library {
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
is_feature: bool,
|
optional: bool,
|
||||||
features: &'static [AVFeature],
|
features: &'static [AVFeature],
|
||||||
|
headers: &'static [AVHeader],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Library {
|
impl Library {
|
||||||
const fn new(name: &'static str, is_feature: bool, features: &'static [AVFeature]) -> Self {
|
const fn required(
|
||||||
|
name: &'static str,
|
||||||
|
features: &'static [AVFeature],
|
||||||
|
headers: &'static [AVHeader],
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
is_feature,
|
optional: false,
|
||||||
features,
|
features,
|
||||||
|
headers,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fn optional(
|
||||||
|
name: &'static str,
|
||||||
|
features: &'static [AVFeature],
|
||||||
|
headers: &'static [AVHeader],
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
optional: true,
|
||||||
|
features,
|
||||||
|
headers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enabled(&self) -> bool {
|
||||||
|
!self.optional || cargo_feature_enabled(self.name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LIBRARIES: &[Library] = &[
|
static LIBRARIES: &[Library] = &[
|
||||||
Library::new("avutil", false, AVUTIL_FEATURES),
|
Library::required("avutil", AVUTIL_FEATURES, AVUTIL_HEADERS),
|
||||||
Library::new("avcodec", true, AVCODEC_FEATURES),
|
Library::optional("avcodec", AVCODEC_FEATURES, AVCODEC_HEADERS),
|
||||||
Library::new("avformat", true, AVFORMAT_FEATURES),
|
Library::optional("avformat", AVFORMAT_FEATURES, AVFORMAT_HEADERS),
|
||||||
Library::new("avdevice", true, AVDEVICE_FEATURES),
|
Library::optional("avdevice", AVDEVICE_FEATURES, AVDEVICE_HEADERS),
|
||||||
Library::new("avfilter", true, AVFILTER_FEATURES),
|
Library::optional("avfilter", AVFILTER_FEATURES, AVFILTER_HEADERS),
|
||||||
Library::new("avresample", true, AVRESAMPLE_FEATURES),
|
Library::optional("avresample", AVRESAMPLE_FEATURES, AVRESAMPLE_HEADERS),
|
||||||
Library::new("swscale", true, SWSCALE_FEATURES),
|
Library::optional("swscale", SWSCALE_FEATURES, SWSCALE_HEADERS),
|
||||||
Library::new("swresample", true, SWRESAMPLE_FEATURES),
|
Library::optional("swresample", SWRESAMPLE_FEATURES, SWRESAMPLE_HEADERS),
|
||||||
Library::new("postproc", true, POSTPROC_FEATURES),
|
Library::optional("postproc", POSTPROC_FEATURES, POSTPROC_HEADERS),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -225,6 +248,89 @@ static SWRESAMPLE_FEATURES: &[AVFeature] = &[];
|
|||||||
|
|
||||||
static POSTPROC_FEATURES: &[AVFeature] = &[];
|
static POSTPROC_FEATURES: &[AVFeature] = &[];
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct AVHeader {
|
||||||
|
name: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AVHeader {
|
||||||
|
const fn new(name: &'static str) -> Self {
|
||||||
|
Self { name }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static AVUTIL_HEADERS: &[AVHeader] = &[
|
||||||
|
AVHeader::new("adler32.h"),
|
||||||
|
AVHeader::new("aes.h"),
|
||||||
|
AVHeader::new("audio_fifo.h"),
|
||||||
|
AVHeader::new("base64.h"),
|
||||||
|
AVHeader::new("blowfish.h"),
|
||||||
|
AVHeader::new("bprint.h"),
|
||||||
|
AVHeader::new("buffer.h"),
|
||||||
|
AVHeader::new("camellia.h"),
|
||||||
|
AVHeader::new("cast5.h"),
|
||||||
|
AVHeader::new("channel_layout.h"),
|
||||||
|
AVHeader::new("cpu.h"),
|
||||||
|
AVHeader::new("crc.h"),
|
||||||
|
AVHeader::new("dict.h"),
|
||||||
|
AVHeader::new("display.h"),
|
||||||
|
AVHeader::new("downmix_info.h"),
|
||||||
|
AVHeader::new("error.h"),
|
||||||
|
AVHeader::new("eval.h"),
|
||||||
|
AVHeader::new("fifo.h"),
|
||||||
|
AVHeader::new("file.h"),
|
||||||
|
AVHeader::new("frame.h"),
|
||||||
|
AVHeader::new("hash.h"),
|
||||||
|
AVHeader::new("hmac.h"),
|
||||||
|
AVHeader::new("hwcontext.h"),
|
||||||
|
AVHeader::new("imgutils.h"),
|
||||||
|
AVHeader::new("lfg.h"),
|
||||||
|
AVHeader::new("log.h"),
|
||||||
|
AVHeader::new("lzo.h"),
|
||||||
|
AVHeader::new("macros.h"),
|
||||||
|
AVHeader::new("mathematics.h"),
|
||||||
|
AVHeader::new("md5.h"),
|
||||||
|
AVHeader::new("mem.h"),
|
||||||
|
AVHeader::new("motion_vector.h"),
|
||||||
|
AVHeader::new("murmur3.h"),
|
||||||
|
AVHeader::new("opt.h"),
|
||||||
|
AVHeader::new("parseutils.h"),
|
||||||
|
AVHeader::new("pixdesc.h"),
|
||||||
|
AVHeader::new("pixfmt.h"),
|
||||||
|
AVHeader::new("random_seed.h"),
|
||||||
|
AVHeader::new("rational.h"),
|
||||||
|
AVHeader::new("replaygain.h"),
|
||||||
|
AVHeader::new("ripemd.h"),
|
||||||
|
AVHeader::new("samplefmt.h"),
|
||||||
|
AVHeader::new("sha.h"),
|
||||||
|
AVHeader::new("sha512.h"),
|
||||||
|
AVHeader::new("stereo3d.h"),
|
||||||
|
AVHeader::new("avstring.h"),
|
||||||
|
AVHeader::new("threadmessage.h"),
|
||||||
|
AVHeader::new("time.h"),
|
||||||
|
AVHeader::new("timecode.h"),
|
||||||
|
AVHeader::new("twofish.h"),
|
||||||
|
AVHeader::new("avutil.h"),
|
||||||
|
AVHeader::new("xtea.h"),
|
||||||
|
];
|
||||||
|
static AVCODEC_HEADERS: &[AVHeader] = &[
|
||||||
|
AVHeader::new("avcodec.h"),
|
||||||
|
AVHeader::new("dv_profile.h"),
|
||||||
|
AVHeader::new("avfft.h"),
|
||||||
|
AVHeader::new("vorbis_parser.h"),
|
||||||
|
];
|
||||||
|
static AVFORMAT_HEADERS: &[AVHeader] = &[AVHeader::new("avformat.h"), AVHeader::new("avio.h")];
|
||||||
|
static AVDEVICE_HEADERS: &[AVHeader] = &[AVHeader::new("avdevice.h")];
|
||||||
|
static AVFILTER_HEADERS: &[AVHeader] = &[
|
||||||
|
AVHeader::new("buffersink.h"),
|
||||||
|
AVHeader::new("buffersrc.h"),
|
||||||
|
AVHeader::new("avfilter.h"),
|
||||||
|
];
|
||||||
|
static AVRESAMPLE_HEADERS: &[AVHeader] = &[AVHeader::new("avresample.h")];
|
||||||
|
static SWSCALE_HEADERS: &[AVHeader] = &[AVHeader::new("swscale.h")];
|
||||||
|
static SWRESAMPLE_HEADERS: &[AVHeader] = &[AVHeader::new("swresample.h")];
|
||||||
|
static POSTPROC_HEADERS: &[AVHeader] = &[AVHeader::new("postprocess.h")];
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Callbacks;
|
struct Callbacks;
|
||||||
|
|
||||||
@ -481,7 +587,7 @@ fn build() -> io::Result<()> {
|
|||||||
// configure building libraries based on features
|
// configure building libraries based on features
|
||||||
for lib in LIBRARIES
|
for lib in LIBRARIES
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|lib| lib.is_feature)
|
.filter(|lib| lib.optional)
|
||||||
.filter(|lib| !(lib.name == "avresample" && ffmpeg_major_version >= 5))
|
.filter(|lib| !(lib.name == "avresample" && ffmpeg_major_version >= 5))
|
||||||
{
|
{
|
||||||
configure.switch(&lib.name.to_uppercase(), lib.name);
|
configure.switch(&lib.name.to_uppercase(), lib.name);
|
||||||
@ -586,11 +692,7 @@ fn check_features(include_paths: &[PathBuf]) {
|
|||||||
let mut includes_code = String::new();
|
let mut includes_code = String::new();
|
||||||
let mut main_code = String::new();
|
let mut main_code = String::new();
|
||||||
|
|
||||||
for lib in LIBRARIES {
|
for lib in LIBRARIES.iter().filter(|lib| lib.enabled()) {
|
||||||
if lib.is_feature && !cargo_feature_enabled(lib.name) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let header = format!("lib{}/{}.h", lib.name, lib.name);
|
let header = format!("lib{}/{}.h", lib.name, lib.name);
|
||||||
for feature in lib.features {
|
for feature in lib.features {
|
||||||
let var = format!("FF_API_{}", feature.name);
|
let var = format!("FF_API_{}", feature.name);
|
||||||
@ -700,11 +802,7 @@ fn check_features(include_paths: &[PathBuf]) {
|
|||||||
|
|
||||||
println!("stdout of {}={}", executable.display(), stdout);
|
println!("stdout of {}={}", executable.display(), stdout);
|
||||||
|
|
||||||
for lib in LIBRARIES {
|
for lib in LIBRARIES.iter().filter(|lib| lib.enabled()) {
|
||||||
if lib.is_feature && !cargo_feature_enabled(lib.name) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for feature in lib.features {
|
for feature in lib.features {
|
||||||
let var = format!("FF_API_{}", feature.name);
|
let var = format!("FF_API_{}", feature.name);
|
||||||
let var_str = format!("[{var}]");
|
let var_str = format!("[{var}]");
|
||||||
@ -812,10 +910,8 @@ fn maybe_search_include(include_paths: &[PathBuf], header: &str) -> Option<Strin
|
|||||||
|
|
||||||
fn link_to_libraries(statik: bool) {
|
fn link_to_libraries(statik: bool) {
|
||||||
let ffmpeg_ty = if statik { "static" } else { "dylib" };
|
let ffmpeg_ty = if statik { "static" } else { "dylib" };
|
||||||
for lib in LIBRARIES {
|
for lib in LIBRARIES.iter().filter(|lib| lib.enabled()) {
|
||||||
if !lib.is_feature || cargo_feature_enabled(lib.name) {
|
println!("cargo:rustc-link-lib={}={}", ffmpeg_ty, lib.name);
|
||||||
println!("cargo:rustc-link-lib={}={}", ffmpeg_ty, lib.name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if cargo_feature_enabled("build_zlib") && cfg!(target_os = "linux") {
|
if cargo_feature_enabled("build_zlib") && cfg!(target_os = "linux") {
|
||||||
println!("cargo:rustc-link-lib=z");
|
println!("cargo:rustc-link-lib=z");
|
||||||
@ -988,103 +1084,17 @@ fn main() {
|
|||||||
|
|
||||||
// The input headers we would like to generate
|
// The input headers we would like to generate
|
||||||
// bindings for.
|
// bindings for.
|
||||||
if cargo_feature_enabled("avcodec") {
|
for lib in LIBRARIES.iter().filter(|lib| lib.enabled()) {
|
||||||
builder = builder
|
for header in lib.headers {
|
||||||
.header(search_include(&include_paths, "libavcodec/avcodec.h"))
|
builder = builder.header(search_include(
|
||||||
.header(search_include(&include_paths, "libavcodec/dv_profile.h"))
|
&include_paths,
|
||||||
.header(search_include(&include_paths, "libavcodec/avfft.h"))
|
&format!("lib{}/{}", lib.name, header.name),
|
||||||
.header(search_include(&include_paths, "libavcodec/vorbis_parser.h"));
|
));
|
||||||
|
|
||||||
if ffmpeg_major_version < 5 {
|
|
||||||
builder = builder.header(search_include(&include_paths, "libavcodec/vaapi.h"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cargo_feature_enabled("avdevice") {
|
if cargo_feature_enabled("avcodec") && ffmpeg_major_version < 5 {
|
||||||
builder = builder.header(search_include(&include_paths, "libavdevice/avdevice.h"));
|
builder = builder.header(search_include(&include_paths, "libavcodec/vaapi.h"))
|
||||||
}
|
|
||||||
|
|
||||||
if cargo_feature_enabled("avfilter") {
|
|
||||||
builder = builder
|
|
||||||
.header(search_include(&include_paths, "libavfilter/buffersink.h"))
|
|
||||||
.header(search_include(&include_paths, "libavfilter/buffersrc.h"))
|
|
||||||
.header(search_include(&include_paths, "libavfilter/avfilter.h"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if cargo_feature_enabled("avformat") {
|
|
||||||
builder = builder
|
|
||||||
.header(search_include(&include_paths, "libavformat/avformat.h"))
|
|
||||||
.header(search_include(&include_paths, "libavformat/avio.h"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if cargo_feature_enabled("avresample") {
|
|
||||||
builder = builder.header(search_include(&include_paths, "libavresample/avresample.h"));
|
|
||||||
}
|
|
||||||
|
|
||||||
builder = builder
|
|
||||||
.header(search_include(&include_paths, "libavutil/adler32.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/aes.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/audio_fifo.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/base64.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/blowfish.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/bprint.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/buffer.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/camellia.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/cast5.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/channel_layout.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/cpu.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/crc.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/dict.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/display.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/downmix_info.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/error.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/eval.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/fifo.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/file.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/frame.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/hash.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/hmac.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/hwcontext.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/imgutils.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/lfg.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/log.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/lzo.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/macros.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/mathematics.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/md5.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/mem.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/motion_vector.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/murmur3.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/opt.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/parseutils.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/pixdesc.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/pixfmt.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/random_seed.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/rational.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/replaygain.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/ripemd.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/samplefmt.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/sha.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/sha512.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/stereo3d.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/avstring.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/threadmessage.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/time.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/timecode.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/twofish.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/avutil.h"))
|
|
||||||
.header(search_include(&include_paths, "libavutil/xtea.h"));
|
|
||||||
|
|
||||||
if cargo_feature_enabled("postproc") {
|
|
||||||
builder = builder.header(search_include(&include_paths, "libpostproc/postprocess.h"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if cargo_feature_enabled("swresample") {
|
|
||||||
builder = builder.header(search_include(&include_paths, "libswresample/swresample.h"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if cargo_feature_enabled("swscale") {
|
|
||||||
builder = builder.header(search_include(&include_paths, "libswscale/swscale.h"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(hwcontext_drm_header) =
|
if let Some(hwcontext_drm_header) =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user