#![allow(bad_style, non_camel_case_types)]
use std::{
os::raw::{c_char, c_float, c_int, c_short, c_uchar, c_uint, c_ulong, c_ushort, c_void},
sync::OnceLock,
};
use crate::{
buffer::BufferType,
config::ConfigAttrib,
display::DisplayAttribute,
error::{Error, VAStatus},
image::{ImageFormat, VAImage},
raw::*,
subpicture::SubpictureFlags,
surface::SurfaceStatus,
surface::{ExportSurfaceFlags, RTFormat, SurfaceAttrib, SurfaceAttribMemoryType},
vpp::{FilterType, RawProcPipelineCaps},
Entrypoint, Profile,
};
macro_rules! dylib {
(
pub struct $strukt:ident;
$(
fn $func:ident( $( $name:ident : $t:ty ),* $(,)? ) $( -> $ret:ty )?;
)+
) => {
$(
pub(crate) type $func = unsafe extern "C" fn( $( $name : $t ),* ) $( -> $ret )?;
)+
pub struct $strukt {
$(
$func: $func,
)+
}
#[allow(unused)]
impl $strukt {
fn load() -> Result<Self, Error> {
unsafe {
let libname = if cfg!(target_os = "windows") {
concat!(stringify!($strukt), ".dll").replace("lib", "")
} else {
concat!(stringify!($strukt), ".so").replace('_', "-")
};
let lib = libloading::Library::new(&libname).map_err(|e| Error::dlopen(&libname, e))?;
let this = Self {
$(
$func: *lib.get(concat!(stringify!($func), "\0").as_bytes())
.map_err(|e| Error::dlsym(&libname, stringify!($func), e))?,
)+
};
std::mem::forget(lib);
Ok(this)
}
}
pub fn get() -> Result<&'static Self, Error> {
static CELL: OnceLock<Result<$strukt, Error>> = OnceLock::new();
match CELL.get_or_init(Self::load) {
Ok(this) => Ok(this),
Err(e) => Err(Error::statik(e)),
}
}
$(
pub(crate) unsafe fn $func( &self, $( $name : $t ),* ) $( -> $ret )? {
(self.$func)($($name),*)
}
)+
}
};
}
dylib! {
pub struct libva;
fn vaErrorStr(error_status: VAStatus) -> *const c_char;
fn vaSetErrorCallback(dpy: VADisplay, callback: VAMessageCallback, user_context: *mut c_void);
fn vaSetInfoCallback(dpy: VADisplay, callback: VAMessageCallback, user_context: *mut c_void);
fn vaDisplayIsValid(dpy: VADisplay) -> c_int;
fn vaSetDriverName(dpy: VADisplay, driver_name: *mut c_char) -> VAStatus;
fn vaInitialize(dpy: VADisplay, major_version: *mut c_int, minor_version: *mut c_int) -> VAStatus;
fn vaTerminate(dpy: VADisplay) -> VAStatus;
fn vaQueryVendorString(dpy: VADisplay) -> *const c_char;
fn vaMaxNumProfiles(dpy: VADisplay) -> c_int;
fn vaMaxNumEntrypoints(dpy: VADisplay) -> c_int;
fn vaMaxNumConfigAttributes(dpy: VADisplay) -> c_int;
fn vaQueryConfigProfiles(dpy: VADisplay, profile_list: *mut Profile, num_profiles: *mut c_int) -> VAStatus;
fn vaQueryConfigEntrypoints(dpy: VADisplay, profile: Profile, entrypoint_list: *mut Entrypoint, num_entrypoints: *mut c_int) -> VAStatus;
fn vaGetConfigAttributes(dpy: VADisplay, profile: Profile, entrypoint: Entrypoint, attrib_list: *mut ConfigAttrib, num_attribs: c_int) -> VAStatus;
fn vaCreateConfig(dpy: VADisplay, profile: Profile, entrypoint: Entrypoint, attrib_list: *mut ConfigAttrib, num_attribs: c_int, config_id: *mut VAConfigID) -> VAStatus;
fn vaDestroyConfig(dpy: VADisplay, config_id: VAConfigID) -> VAStatus;
fn vaQueryConfigAttributes(dpy: VADisplay, config_id: VAConfigID, profile: *mut Profile, entrypoint: *mut Entrypoint, attrib_list: *mut ConfigAttrib, num_attribs: *mut c_int) -> VAStatus;
fn vaQuerySurfaceAttributes(dpy: VADisplay, config: VAConfigID, attrib_list: *mut SurfaceAttrib, num_attribs: *mut c_uint) -> VAStatus;
fn vaCreateSurfaces(dpy: VADisplay, format: RTFormat, width: c_uint, height: c_uint, surfaces: *mut VASurfaceID, num_surfaces: c_uint, attrib_list: *mut SurfaceAttrib, num_attribs: c_uint) -> VAStatus;
fn vaDestroySurfaces(dpy: VADisplay, surfaces: *mut VASurfaceID, num_surfaces: c_int) -> VAStatus;
fn vaCreateContext(dpy: VADisplay, config_id: VAConfigID, picture_width: c_int, picture_height: c_int, flag: c_int, render_targets: *mut VASurfaceID, num_render_targets: c_int, context: *mut VAContextID) -> VAStatus;
fn vaDestroyContext(dpy: VADisplay, context: VAContextID) -> VAStatus;
fn vaCreateMFContext(dpy: VADisplay, mf_context: *mut VAMFContextID) -> VAStatus;
fn vaQueryProcessingRate(dpy: VADisplay, config: VAConfigID, proc_buf: *mut VAProcessingRateParameter, processing_rate: *mut c_uint) -> VAStatus;
fn vaCreateBuffer(dpy: VADisplay, context: VAContextID, type_: BufferType, size: c_uint, num_elements: c_uint, data: *mut c_void, buf_id: *mut VABufferID) -> VAStatus;
fn vaCreateBuffer2(dpy: VADisplay, context: VAContextID, type_: BufferType, width: c_uint, height: c_uint, unit_size: *mut c_uint, pitch: *mut c_uint, buf_id: *mut VABufferID) -> VAStatus;
fn vaBufferSetNumElements(dpy: VADisplay, buf_id: VABufferID, num_elements: c_uint) -> VAStatus;
fn vaMapBuffer(dpy: VADisplay, buf_id: VABufferID, pbuf: *mut *mut c_void) -> VAStatus;
fn vaUnmapBuffer(dpy: VADisplay, buf_id: VABufferID) -> VAStatus;
fn vaDestroyBuffer(dpy: VADisplay, buffer_id: VABufferID) -> VAStatus;
fn vaAcquireBufferHandle(dpy: VADisplay, buf_id: VABufferID, buf_info: *mut VABufferInfo) -> VAStatus;
fn vaReleaseBufferHandle(dpy: VADisplay, buf_id: VABufferID) -> VAStatus;
fn vaExportSurfaceHandle(dpy: VADisplay, surface_id: VASurfaceID, mem_type: SurfaceAttribMemoryType, flags: ExportSurfaceFlags, descriptor: *mut c_void) -> VAStatus;
fn vaBeginPicture(dpy: VADisplay, context: VAContextID, render_target: VASurfaceID) -> VAStatus;
fn vaRenderPicture(dpy: VADisplay, context: VAContextID, buffers: *mut VABufferID, num_buffers: c_int) -> VAStatus;
fn vaEndPicture(dpy: VADisplay, context: VAContextID) -> VAStatus;
fn vaMFSubmit(dpy: VADisplay, mf_context: VAMFContextID, contexts: *mut VAContextID, num_contexts: c_int) -> VAStatus;
fn vaSyncSurface(dpy: VADisplay, render_target: VASurfaceID) -> VAStatus;
fn vaSyncSurface2(dpy: VADisplay, surface: VASurfaceID, timeout_ns: u64) -> VAStatus;
fn vaQuerySurfaceStatus(dpy: VADisplay, render_target: VASurfaceID, status: *mut SurfaceStatus) -> VAStatus;
fn vaQuerySurfaceError(dpy: VADisplay, surface: VASurfaceID, error_status: VAStatus, error_info: *mut *mut c_void) -> VAStatus;
fn vaSyncBuffer(dpy: VADisplay, buf_id: VABufferID, timeout_ns: u64) -> VAStatus;
fn vaMaxNumImageFormats(dpy: VADisplay) -> c_int;
fn vaQueryImageFormats(dpy: VADisplay, format_list: *mut ImageFormat, num_formats: *mut c_int) -> VAStatus;
fn vaCreateImage(dpy: VADisplay, format: *mut ImageFormat, width: c_int, height: c_int, image: *mut VAImage) -> VAStatus;
fn vaDestroyImage(dpy: VADisplay, image: VAImageID) -> VAStatus;
fn vaSetImagePalette(dpy: VADisplay, image: VAImageID, palette: *mut c_uchar) -> VAStatus;
fn vaGetImage(dpy: VADisplay, surface: VASurfaceID, x: c_int, y: c_int, width: c_uint, height: c_uint, image: VAImageID) -> VAStatus;
fn vaPutImage(
dpy: VADisplay,
surface: VASurfaceID,
image: VAImageID,
src_x: c_int,
src_y: c_int,
src_width: c_uint,
src_height: c_uint,
dest_x: c_int,
dest_y: c_int,
dest_width: c_uint,
dest_height: c_uint
) -> VAStatus;
fn vaDeriveImage(dpy: VADisplay, surface: VASurfaceID, image: *mut VAImage) -> VAStatus;
fn vaMaxNumSubpictureFormats(dpy: VADisplay) -> c_int;
fn vaQuerySubpictureFormats(dpy: VADisplay, format_list: *mut ImageFormat, flags: *mut c_uint, num_formats: *mut c_uint) -> VAStatus;
fn vaCreateSubpicture(dpy: VADisplay, image: VAImageID, subpicture: *mut VASubpictureID) -> VAStatus;
fn vaDestroySubpicture(dpy: VADisplay, subpicture: VASubpictureID) -> VAStatus;
fn vaSetSubpictureImage(dpy: VADisplay, subpicture: VASubpictureID, image: VAImageID) -> VAStatus;
fn vaSetSubpictureChromakey(dpy: VADisplay, subpicture: VASubpictureID, chromakey_min: c_uint, chromakey_max: c_uint, chromakey_mask: c_uint) -> VAStatus;
fn vaSetSubpictureGlobalAlpha(dpy: VADisplay, subpicture: VASubpictureID, global_alpha: c_float) -> VAStatus;
fn vaAssociateSubpicture(
dpy: VADisplay,
subpicture: VASubpictureID,
target_surfaces: *mut VASurfaceID,
num_surfaces: c_int,
src_x: i32,
src_y: i32,
src_width: u16,
src_height: u16,
dest_x: i16,
dest_y: i16,
dest_width: u16,
dest_height: u16,
flags: SubpictureFlags,
) -> VAStatus;
fn vaDeassociateSubpicture(dpy: VADisplay, subpicture: VASubpictureID, target_surfaces: *mut VASurfaceID, num_surfaces: c_int) -> VAStatus;
fn vaMaxNumDisplayAttributes(dpy: VADisplay) -> c_int;
fn vaQueryDisplayAttributes(dpy: VADisplay, attr_list: *mut DisplayAttribute, num_attributes: *mut c_int) -> VAStatus;
fn vaGetDisplayAttributes(dpy: VADisplay, attr_list: *mut DisplayAttribute, num_attributes: c_int) -> VAStatus;
fn vaSetDisplayAttributes(dpy: VADisplay, attr_list: *mut DisplayAttribute, num_attributes: c_int) -> VAStatus;
fn vaQueryVideoProcFilters(dpy: VADisplay, context: VAContextID, filters: *mut FilterType, num_filters: *mut c_uint) -> VAStatus;
fn vaQueryVideoProcFilterCaps(dpy: VADisplay, context: VAContextID, type_: FilterType, filter_caps: *mut c_void, num_filter_caps: *mut c_uint) -> VAStatus;
fn vaQueryVideoProcPipelineCaps(dpy: VADisplay, context: VAContextID, filters: *mut VABufferID, num_filters: c_uint, pipeline_caps: *mut RawProcPipelineCaps) -> VAStatus;
}
dylib! {
pub struct libva_x11;
fn vaGetDisplay(dpy: *mut Display) -> VADisplay;
fn vaPutSurface(
dpy: VADisplay,
surface: VASurfaceID,
draw: Drawable,
srcx: c_short,
srcy: c_short,
srcw: c_ushort,
srch: c_ushort,
destx: c_short,
desty: c_short,
destw: c_ushort,
desth: c_ushort,
cliprects: *mut Rectangle,
number_cliprects: c_uint,
flags: c_uint
) -> VAStatus;
}
dylib! {
pub struct libva_wayland;
fn vaGetDisplayWl(display: *mut wl_display) -> VADisplay;
fn vaGetSurfaceBufferWl(dpy: VADisplay, surface: VASurfaceID, flags: c_uint, out_buffer: *mut *mut wl_buffer) -> VAStatus;
fn vaGetImageBufferWl(dpy: VADisplay, image: VAImageID, flags: c_uint, out_buffer: *mut *mut wl_buffer) -> VAStatus;
}
dylib! {
pub struct libva_drm;
fn vaGetDisplayDRM(fd: c_int) -> VADisplay;
}
dylib! {
pub struct libva_win32;
fn vaGetDisplayWin32(adapter_luid: *const c_void) -> VADisplay;
}
pub struct wl_display;
pub struct wl_buffer;
pub struct Display;
pub type Drawable = c_ulong;