Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build.rs: Detect libva version and enable any libva headers >= 1.20.0 #21

Merged
merged 2 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ usable anywhere.

The native [libva](https://github.com/intel/libva) library is required at link
time, so make sure to have the `libva-dev` or equivalent package for your
distribution installed. The compatible libva version is 1.22.0. The VA-API
driver corresponding to your hardware is also required: for Intel hardware it
will be [intel-media-driver](https://github.com/intel/media-driver), whereas AMD
hardware relies on [Mesa](https://gitlab.freedesktop.org/mesa/mesa).
distribution installed. The libva version needs to be 1.20.0 or newer. The
VA-API driver corresponding to your hardware is also required: for Intel
hardware it will be [intel-media-driver](https://github.com/intel/media-driver),
whereas AMD hardware relies on [Mesa](https://gitlab.freedesktop.org/mesa/mesa).

An easy way to see whether everything is in order is to run the `vainfo`
utility packaged with `libva-utils` or as a standalone package in some
Expand Down
4 changes: 4 additions & 0 deletions lib/Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ rust_library {
"//apex_available:anyapex",
],

cfgs: [
"libva_1_21_or_higher",
],

vendor: true,
enabled: false,
arch: {
Expand Down
3 changes: 2 additions & 1 deletion lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ log = { version = "0", features = ["release_max_level_debug"] }

[build-dependencies]
bindgen = "0.70.1"
pkg-config = "0.3.26"
pkg-config = "0.3.31"
regex = "1.11.1"

[dev-dependencies]
crc32fast = "1.2.1"
76 changes: 73 additions & 3 deletions lib/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use regex::Regex;
use std::env::VarError;
use std::env::{self};
use std::fs::read_to_string;
use std::path::{Path, PathBuf};

mod bindgen_gen;
Expand All @@ -16,13 +19,70 @@ const CROS_LIBVA_LIB_PATH_ENV: &str = "CROS_LIBVA_LIB_PATH";
/// Wrapper file to use as input of bindgen.
const WRAPPER_PATH: &str = "libva-wrapper.h";

// Return VA_MAJOR_VERSION and VA_MINOR_VERSION from va_version.h.
fn get_va_version(va_h_path: &str) -> (u32, u32) {
let va_version_h_path = Path::new(va_h_path).join("va/va_version.h");
assert!(
va_version_h_path.exists(),
"{} doesn't exist",
va_version_h_path.display()
);
let header_content = read_to_string(va_version_h_path).unwrap();
let lines = header_content.lines();

const VERSION_REGEX_STRINGS: [&str; 2] = [
r"#define VA_MAJOR_VERSION\s*[0-9]+",
r"#define VA_MINOR_VERSION\s*[0-9]+",
];
let mut numbers: [u32; 2] = [0; 2];
for i in 0..2 {
let re = Regex::new(VERSION_REGEX_STRINGS[i]).unwrap();
let match_line = lines
.clone()
.filter(|&s| re.is_match(s))
.collect::<Vec<_>>();
assert_eq!(
match_line.len(),
1,
"unexpected match for {}: {:?}",
VERSION_REGEX_STRINGS[i],
match_line
);
let number_str = Regex::new(r"[0-9]+")
.unwrap()
.find(match_line[0])
.unwrap()
.as_str();
numbers[i] = number_str.parse::<u32>().unwrap();
}

(numbers[0], numbers[1])
}

fn main() {
// Do not require dependencies when generating docs.
if std::env::var("CARGO_DOC").is_ok() || std::env::var("DOCS_RS").is_ok() {
return;
}

let va_h_path = env::var(CROS_LIBVA_H_PATH_ENV).unwrap_or_default();
let va_h_path = env::var(CROS_LIBVA_H_PATH_ENV)
.or_else(|e| {
if let VarError::NotPresent = e {
let libva_library = pkg_config::probe_library("libva");
match libva_library {
Ok(_) => Ok(libva_library.unwrap().include_paths[0]
.clone()
.into_os_string()
.into_string()
.unwrap()),
Err(e) => panic!("libva is not found in system: {}", e),
}
} else {
Err(e)
}
})
.expect("libva header location is unknown");

let va_lib_path = env::var(CROS_LIBVA_LIB_PATH_ENV).unwrap_or_default();
// Check the path exists.
if !va_h_path.is_empty() {
Expand All @@ -33,11 +93,21 @@ fn main() {
);
}

let (major, minor) = get_va_version(&va_h_path);
println!("libva {}.{} is used to generate bindings", major, minor);
let va_check_version = |desired_major: u32, desired_minor: u32| {
major > desired_major || (major == desired_major && minor >= desired_minor)
};

if va_check_version(1, 21) {
println!("cargo::rustc-cfg=libva_1_21_or_higher");
}

if !va_lib_path.is_empty() {
assert!(
Path::new(&va_h_path).exists(),
Path::new(&va_lib_path).exists(),
"{} doesn't exist",
va_h_path
va_lib_path
);
println!("cargo:rustc-link-arg=-Wl,-rpath={}", va_lib_path);
}
Expand Down
28 changes: 25 additions & 3 deletions lib/src/buffer/av1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,10 +736,11 @@ impl AV1EncPictureFlags {
let disable_frame_recon = disable_frame_recon as u32;
let allow_intrabc = allow_intrabc as u32;
let palette_mode_enable = palette_mode_enable as u32;
let allow_screen_content_tools = allow_screen_content_tools as u32;
let force_integer_mv = force_integer_mv as u32;

let _bitfield_1 =
#[cfg(libva_1_21_or_higher)]
let _bitfield_1 = {
let allow_screen_content_tools = allow_screen_content_tools as u32;
let force_integer_mv = force_integer_mv as u32;
bindings::_VAEncPictureParameterBufferAV1__bindgen_ty_1__bindgen_ty_1::new_bitfield_1(
frame_type,
error_resilient_mode,
Expand All @@ -757,6 +758,27 @@ impl AV1EncPictureFlags {
allow_screen_content_tools,
force_integer_mv,
Default::default(),
)
};
#[cfg(not(libva_1_21_or_higher))]
let _bitfield_1 =
bindings::_VAEncPictureParameterBufferAV1__bindgen_ty_1__bindgen_ty_1::new_bitfield_1(
frame_type,
error_resilient_mode,
disable_cdf_update,
use_superres,
allow_high_precision_mv,
use_ref_frame_mvs,
disable_frame_end_update_cdf,
reduced_tx_set,
enable_frame_obu,
long_term_reference,
disable_frame_recon,
allow_intrabc,
palette_mode_enable,
//allow_screen_content_tools,
//force_integer_mv,
Default::default(),
);

Self(bindings::_VAEncPictureParameterBufferAV1__bindgen_ty_1 {
Expand Down
Loading