blob: 3f4f5b5dc4995aaf2246c5defcf9ee61f94bfa7e [file] [log] [blame]
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Build rust library and bindings for dav1d.
use std::env;
use std::path::PathBuf;
fn path_buf(inputs: &[&str]) -> PathBuf {
let path: PathBuf = inputs.iter().collect();
path
}
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let build_target = std::env::var("TARGET").unwrap();
if !build_target.contains("android") {
panic!("Not an android target: {build_target}");
};
// Generate bindings.
let project_root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let header_file = PathBuf::from(&project_root).join("wrapper.h");
let outfile = PathBuf::from(&project_root).join(path_buf(&["src", "bindings.rs"]));
let host_tag = "linux-x86_64"; // TODO: Support windows and mac.
let sysroot = format!(
"{}/toolchains/llvm/prebuilt/{}/sysroot/",
env!("ANDROID_NDK_ROOT"),
host_tag
);
let mut bindings = bindgen::Builder::default()
.header(header_file.into_os_string().into_string().unwrap())
.clang_arg(format!("--sysroot={sysroot}"))
.clang_arg(format!("--target={build_target}"))
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.derive_default(true)
.layout_tests(false)
.generate_comments(false);
let allowlist_items = &[
"AMediaCodec",
"AMediaCodecBufferInfo",
"AMediaCodec_configure",
"AMediaCodec_createCodecByName",
"AMediaCodec_createDecoderByType",
"AMediaCodec_delete",
"AMediaCodec_dequeueInputBuffer",
"AMediaCodec_dequeueOutputBuffer",
"AMediaCodec_getInputBuffer",
"AMediaCodec_getOutputBuffer",
"AMediaCodec_getOutputFormat",
"AMediaCodec_queueInputBuffer",
"AMediaCodec_releaseOutputBuffer",
"AMediaCodec_releaseOutputBuffer",
"AMediaCodec_start",
"AMediaCodec_stop",
"AMediaFormat",
"AMediaFormat_delete",
"AMediaFormat_getBuffer",
"AMediaFormat_getInt32",
"AMediaFormat_new",
"AMediaFormat_setBuffer",
"AMediaFormat_setInt32",
"AMediaFormat_setString",
];
for allowlist_item in allowlist_items {
bindings = bindings.allowlist_item(allowlist_item);
}
// Ideally, we should be able to merge this list with the one above. But somehow bindgen does
// not generate bindings for these when they are called with allowlist_item instead of
// allowlist_var.
let allowlist_vars = &[
"AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED",
"AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED",
"AMEDIACODEC_INFO_TRY_AGAIN_LATER",
"AMEDIAFORMAT_KEY_COLOR_FORMAT",
"AMEDIAFORMAT_KEY_CSD_0",
"AMEDIAFORMAT_KEY_HEIGHT",
"AMEDIAFORMAT_KEY_MAX_INPUT_SIZE",
"AMEDIAFORMAT_KEY_MIME",
"AMEDIAFORMAT_KEY_SLICE_HEIGHT",
"AMEDIAFORMAT_KEY_STRIDE",
"AMEDIAFORMAT_KEY_WIDTH",
];
for allowlist_var in allowlist_vars {
bindings = bindings.allowlist_var(allowlist_var);
}
let bindings = bindings
.generate()
.unwrap_or_else(|_| panic!("Unable to generate bindings for dav1d."));
bindings
.write_to_file(outfile.as_path())
.unwrap_or_else(|_| panic!("Couldn't write bindings for dav1d"));
println!(
"cargo:rustc-env=CRABBYAVIF_ANDROID_NDK_MEDIA_BINDINGS_RS={}",
outfile.display()
);
println!("cargo:rustc-link-lib=mediandk");
}