diff --git a/.cargo/config.toml b/.cargo/config.toml index fcfd81db..1ad62c53 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,5 @@ +[build] +target = "aarch64-unknown-linux-gnu" + [target.'cfg(all(not(miri), not(target_arch = "x86_64")))'] runner = ["remote-test.sh"] diff --git a/Cargo.lock b/Cargo.lock index ff6e08e3..299ed362 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2345,9 +2345,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.14" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempdir" @@ -2823,6 +2823,30 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vdo" +version = "0.1.0" +dependencies = [ + "anyhow", + "env_logger", + "glib", + "glib-sys", + "gobject-sys", + "log", + "thiserror", + "vdo-sys", +] + +[[package]] +name = "vdo-sys" +version = "0.0.0" +dependencies = [ + "bindgen", + "glib-sys", + "gobject-sys", + "pkg-config", +] + [[package]] name = "version-compare" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index e5d42629..5560c191 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,6 +60,8 @@ licensekey = { path = "crates/licensekey" } licensekey-sys = { path = "crates/licensekey-sys" } mdb = { path = "crates/mdb" } mdb-sys = { path = "crates/mdb-sys" } +vdo = { path = "crates/vdo" } +vdo-sys = { path = "crates/vdo-sys" } [workspace.package] edition = "2021" diff --git a/crates/vdo-sys/Cargo.toml b/crates/vdo-sys/Cargo.toml new file mode 100644 index 00000000..523270db --- /dev/null +++ b/crates/vdo-sys/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "vdo-sys" +version = "0.0.0" +edition.workspace = true + +[build-dependencies] +bindgen = { workspace = true } +pkg-config = { workspace = true } + +[dependencies] +glib-sys = { workspace = true } +gobject-sys = "0.19.5" diff --git a/crates/vdo-sys/build.rs b/crates/vdo-sys/build.rs new file mode 100644 index 00000000..9f450272 --- /dev/null +++ b/crates/vdo-sys/build.rs @@ -0,0 +1,29 @@ +use std::{env, path}; + +fn populated_bindings(dst: &path::PathBuf) { + let library = pkg_config::Config::new().probe("vdo").unwrap(); + let mut bindings = bindgen::Builder::default() + .header("wrapper.h") + .allowlist_recursively(false) + .allowlist_function("^(vdo.*)$") + .allowlist_type("^(_?Vdo.*)$") + .allowlist_var("^(VDO_ERROR.*)$") + .blocklist_function("vdo_stream_enqueue_buffer") + .default_enum_style(bindgen::EnumVariation::NewType { + is_global: false, + is_bitfield: true, + }) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .layout_tests(false); + for path in library.include_paths { + bindings = bindings.clang_args(&["-F", path.to_str().unwrap()]); + } + bindings.generate().unwrap().write_to_file(dst).unwrap(); +} + +fn main() { + let dst = path::PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs"); + if env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default() != "x86_64" { + populated_bindings(&dst); + } +} diff --git a/crates/vdo-sys/src/bindings.rs b/crates/vdo-sys/src/bindings.rs new file mode 100644 index 00000000..a92f253d --- /dev/null +++ b/crates/vdo-sys/src/bindings.rs @@ -0,0 +1,1796 @@ +/* automatically generated by rust-bindgen 0.69.4 */ + +#[repr(C)] +#[derive(Default)] +pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); +impl __IncompleteArrayField { + #[inline] + pub const fn new() -> Self { + __IncompleteArrayField(::std::marker::PhantomData, []) + } + #[inline] + pub fn as_ptr(&self) -> *const T { + self as *const _ as *const T + } + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut T { + self as *mut _ as *mut T + } + #[inline] + pub unsafe fn as_slice(&self, len: usize) -> &[T] { + ::std::slice::from_raw_parts(self.as_ptr(), len) + } + #[inline] + pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { + ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) + } +} +impl ::std::fmt::Debug for __IncompleteArrayField { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + fmt.write_str("__IncompleteArrayField") + } +} +#[repr(C)] +pub struct __BindgenUnionField(::std::marker::PhantomData); +impl __BindgenUnionField { + #[inline] + pub const fn new() -> Self { + __BindgenUnionField(::std::marker::PhantomData) + } + #[inline] + pub unsafe fn as_ref(&self) -> &T { + ::std::mem::transmute(self) + } + #[inline] + pub unsafe fn as_mut(&mut self) -> &mut T { + ::std::mem::transmute(self) + } +} +impl ::std::default::Default for __BindgenUnionField { + #[inline] + fn default() -> Self { + Self::new() + } +} +impl ::std::clone::Clone for __BindgenUnionField { + #[inline] + fn clone(&self) -> Self { + *self + } +} +impl ::std::marker::Copy for __BindgenUnionField {} +impl ::std::fmt::Debug for __BindgenUnionField { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + fmt.write_str("__BindgenUnionField") + } +} +impl ::std::hash::Hash for __BindgenUnionField { + fn hash(&self, _state: &mut H) {} +} +impl ::std::cmp::PartialEq for __BindgenUnionField { + fn eq(&self, _other: &__BindgenUnionField) -> bool { + true + } +} +impl ::std::cmp::Eq for __BindgenUnionField {} +impl VdoWdrMode { + pub const VDO_WDR_MODE_NONE: VdoWdrMode = VdoWdrMode(-1); +} +impl VdoWdrMode { + pub const VDO_WDR_MODE_LINEAR: VdoWdrMode = VdoWdrMode(0); +} +impl VdoWdrMode { + pub const VDO_WDR_MODE_2X: VdoWdrMode = VdoWdrMode(1); +} +impl VdoWdrMode { + pub const VDO_WDR_MODE_3X: VdoWdrMode = VdoWdrMode(2); +} +impl VdoWdrMode { + pub const VDO_WDR_MODE_4X: VdoWdrMode = VdoWdrMode(3); +} +impl VdoWdrMode { + pub const VDO_WDR_MODE_SENSOR: VdoWdrMode = VdoWdrMode(4); +} +impl VdoWdrMode { + pub const VDO_WDR_MODE_OFF: VdoWdrMode = VdoWdrMode(5); +} +impl ::std::ops::BitOr for VdoWdrMode { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoWdrMode(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoWdrMode { + #[inline] + fn bitor_assign(&mut self, rhs: VdoWdrMode) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoWdrMode { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoWdrMode(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoWdrMode { + #[inline] + fn bitand_assign(&mut self, rhs: VdoWdrMode) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoWdrMode(pub ::std::os::raw::c_int); +impl VdoFormat { + pub const VDO_FORMAT_NONE: VdoFormat = VdoFormat(-1); +} +impl VdoFormat { + pub const VDO_FORMAT_H264: VdoFormat = VdoFormat(0); +} +impl VdoFormat { + pub const VDO_FORMAT_H265: VdoFormat = VdoFormat(1); +} +impl VdoFormat { + pub const VDO_FORMAT_JPEG: VdoFormat = VdoFormat(2); +} +impl VdoFormat { + pub const VDO_FORMAT_YUV: VdoFormat = VdoFormat(3); +} +impl VdoFormat { + pub const VDO_FORMAT_BAYER: VdoFormat = VdoFormat(4); +} +impl VdoFormat { + pub const VDO_FORMAT_IVS: VdoFormat = VdoFormat(5); +} +impl VdoFormat { + pub const VDO_FORMAT_RAW: VdoFormat = VdoFormat(6); +} +impl VdoFormat { + pub const VDO_FORMAT_RGBA: VdoFormat = VdoFormat(7); +} +impl VdoFormat { + pub const VDO_FORMAT_RGB: VdoFormat = VdoFormat(8); +} +impl VdoFormat { + pub const VDO_FORMAT_PLANAR_RGB: VdoFormat = VdoFormat(9); +} +impl VdoFormat { + pub const VDO_FORMAT_AV1: VdoFormat = VdoFormat(10); +} +impl ::std::ops::BitOr for VdoFormat { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoFormat(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoFormat { + #[inline] + fn bitor_assign(&mut self, rhs: VdoFormat) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoFormat { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoFormat(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoFormat { + #[inline] + fn bitand_assign(&mut self, rhs: VdoFormat) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoFormat(pub ::std::os::raw::c_int); +impl VdoH264Profile { + pub const VDO_H264_PROFILE_NONE: VdoH264Profile = VdoH264Profile(-1); +} +impl VdoH264Profile { + pub const VDO_H264_PROFILE_BASELINE: VdoH264Profile = VdoH264Profile(0); +} +impl VdoH264Profile { + pub const VDO_H264_PROFILE_MAIN: VdoH264Profile = VdoH264Profile(1); +} +impl VdoH264Profile { + pub const VDO_H264_PROFILE_HIGH: VdoH264Profile = VdoH264Profile(2); +} +impl ::std::ops::BitOr for VdoH264Profile { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoH264Profile(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoH264Profile { + #[inline] + fn bitor_assign(&mut self, rhs: VdoH264Profile) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoH264Profile { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoH264Profile(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoH264Profile { + #[inline] + fn bitand_assign(&mut self, rhs: VdoH264Profile) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoH264Profile(pub ::std::os::raw::c_int); +impl VdoH265Profile { + pub const VDO_H265_PROFILE_NONE: VdoH265Profile = VdoH265Profile(-1); +} +impl VdoH265Profile { + pub const VDO_H265_PROFILE_MAIN: VdoH265Profile = VdoH265Profile(0); +} +impl VdoH265Profile { + pub const VDO_H265_PROFILE_MAIN_10: VdoH265Profile = VdoH265Profile(1); +} +impl ::std::ops::BitOr for VdoH265Profile { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoH265Profile(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoH265Profile { + #[inline] + fn bitor_assign(&mut self, rhs: VdoH265Profile) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoH265Profile { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoH265Profile(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoH265Profile { + #[inline] + fn bitand_assign(&mut self, rhs: VdoH265Profile) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoH265Profile(pub ::std::os::raw::c_int); +impl VdoAV1Profile { + pub const VDO_AV1_PROFILE_NONE: VdoAV1Profile = VdoAV1Profile(-1); +} +impl VdoAV1Profile { + pub const VDO_AV1_PROFILE_MAIN: VdoAV1Profile = VdoAV1Profile(0); +} +impl VdoAV1Profile { + pub const VDO_AV1_PROFILE_MAIN_10: VdoAV1Profile = VdoAV1Profile(1); +} +impl ::std::ops::BitOr for VdoAV1Profile { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoAV1Profile(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoAV1Profile { + #[inline] + fn bitor_assign(&mut self, rhs: VdoAV1Profile) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoAV1Profile { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoAV1Profile(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoAV1Profile { + #[inline] + fn bitand_assign(&mut self, rhs: VdoAV1Profile) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoAV1Profile(pub ::std::os::raw::c_int); +impl VdoRateControlMode { + pub const VDO_RATE_CONTROL_MODE_NONE: VdoRateControlMode = VdoRateControlMode(-1); +} +impl VdoRateControlMode { + pub const VDO_RATE_CONTROL_MODE_CBR: VdoRateControlMode = VdoRateControlMode(0); +} +impl VdoRateControlMode { + pub const VDO_RATE_CONTROL_MODE_VBR: VdoRateControlMode = VdoRateControlMode(1); +} +impl VdoRateControlMode { + pub const VDO_RATE_CONTROL_MODE_MBR: VdoRateControlMode = VdoRateControlMode(2); +} +impl VdoRateControlMode { + pub const VDO_RATE_CONTROL_MODE_ABR: VdoRateControlMode = VdoRateControlMode(3); +} +impl ::std::ops::BitOr for VdoRateControlMode { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoRateControlMode(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoRateControlMode { + #[inline] + fn bitor_assign(&mut self, rhs: VdoRateControlMode) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoRateControlMode { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoRateControlMode(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoRateControlMode { + #[inline] + fn bitand_assign(&mut self, rhs: VdoRateControlMode) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoRateControlMode(pub ::std::os::raw::c_int); +impl VdoRateControlPriority { + pub const VDO_RATE_CONTROL_PRIORITY_NONE: VdoRateControlPriority = VdoRateControlPriority(-1); +} +impl VdoRateControlPriority { + pub const VDO_RATE_CONTROL_PRIORITY_FRAMERATE: VdoRateControlPriority = + VdoRateControlPriority(0); +} +impl VdoRateControlPriority { + pub const VDO_RATE_CONTROL_PRIORITY_QUALITY: VdoRateControlPriority = VdoRateControlPriority(1); +} +impl VdoRateControlPriority { + pub const VDO_RATE_CONTROL_PRIORITY_FULL_FRAMERATE: VdoRateControlPriority = + VdoRateControlPriority(2); +} +impl ::std::ops::BitOr for VdoRateControlPriority { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoRateControlPriority(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoRateControlPriority { + #[inline] + fn bitor_assign(&mut self, rhs: VdoRateControlPriority) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoRateControlPriority { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoRateControlPriority(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoRateControlPriority { + #[inline] + fn bitand_assign(&mut self, rhs: VdoRateControlPriority) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoRateControlPriority(pub ::std::os::raw::c_int); +impl VdoFrameType { + pub const VDO_FRAME_TYPE_NONE: VdoFrameType = VdoFrameType(0); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H264_SPS: VdoFrameType = VdoFrameType(1); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H264_PPS: VdoFrameType = VdoFrameType(2); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H264_SEI: VdoFrameType = VdoFrameType(3); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H264_IDR: VdoFrameType = VdoFrameType(4); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H264_I: VdoFrameType = VdoFrameType(5); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H264_P: VdoFrameType = VdoFrameType(6); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H264_B: VdoFrameType = VdoFrameType(7); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H265_SPS: VdoFrameType = VdoFrameType(8); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H265_PPS: VdoFrameType = VdoFrameType(9); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H265_VPS: VdoFrameType = VdoFrameType(10); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H265_SEI: VdoFrameType = VdoFrameType(11); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H265_IDR: VdoFrameType = VdoFrameType(12); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H265_I: VdoFrameType = VdoFrameType(13); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H265_P: VdoFrameType = VdoFrameType(14); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_H265_B: VdoFrameType = VdoFrameType(15); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_JPEG: VdoFrameType = VdoFrameType(16); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_YUV: VdoFrameType = VdoFrameType(17); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_RAW: VdoFrameType = VdoFrameType(18); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_RGBA: VdoFrameType = VdoFrameType(19); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_RGB: VdoFrameType = VdoFrameType(20); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_PLANAR_RGB: VdoFrameType = VdoFrameType(21); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_AV1_KEY: VdoFrameType = VdoFrameType(22); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_AV1_INTER: VdoFrameType = VdoFrameType(23); +} +impl VdoFrameType { + pub const VDO_FRAME_TYPE_AV1_BIDI: VdoFrameType = VdoFrameType(24); +} +impl ::std::ops::BitOr for VdoFrameType { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoFrameType(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoFrameType { + #[inline] + fn bitor_assign(&mut self, rhs: VdoFrameType) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoFrameType { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoFrameType(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoFrameType { + #[inline] + fn bitand_assign(&mut self, rhs: VdoFrameType) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoFrameType(pub ::std::os::raw::c_uint); +impl VdoZipStreamProfile { + pub const VDO_ZIPSTREAM_PROFILE_NONE: VdoZipStreamProfile = VdoZipStreamProfile(-1); +} +impl VdoZipStreamProfile { + pub const VDO_ZIPSTREAM_PROFILE_CLASSIC: VdoZipStreamProfile = VdoZipStreamProfile(0); +} +impl VdoZipStreamProfile { + pub const VDO_ZIPSTREAM_PROFILE_STORAGE: VdoZipStreamProfile = VdoZipStreamProfile(1); +} +impl VdoZipStreamProfile { + pub const VDO_ZIPSTREAM_PROFILE_LIVE: VdoZipStreamProfile = VdoZipStreamProfile(2); +} +impl ::std::ops::BitOr for VdoZipStreamProfile { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoZipStreamProfile(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoZipStreamProfile { + #[inline] + fn bitor_assign(&mut self, rhs: VdoZipStreamProfile) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoZipStreamProfile { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoZipStreamProfile(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoZipStreamProfile { + #[inline] + fn bitand_assign(&mut self, rhs: VdoZipStreamProfile) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoZipStreamProfile(pub ::std::os::raw::c_int); +impl VdoChunkType { + pub const VDO_CHUNK_NONE: VdoChunkType = VdoChunkType(0); +} +impl VdoChunkType { + pub const VDO_CHUNK_ERROR: VdoChunkType = VdoChunkType(2147483648); +} +impl ::std::ops::BitOr for VdoChunkType { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoChunkType(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoChunkType { + #[inline] + fn bitor_assign(&mut self, rhs: VdoChunkType) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoChunkType { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoChunkType(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoChunkType { + #[inline] + fn bitand_assign(&mut self, rhs: VdoChunkType) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoChunkType(pub ::std::os::raw::c_uint); +impl VdoChunkOption { + pub const VDO_CHUNK_OPTION_NONE: VdoChunkOption = VdoChunkOption(0); +} +impl VdoChunkOption { + pub const VDO_CHUNK_OPTION_MMAP: VdoChunkOption = VdoChunkOption(2147483648); +} +impl ::std::ops::BitOr for VdoChunkOption { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoChunkOption(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoChunkOption { + #[inline] + fn bitor_assign(&mut self, rhs: VdoChunkOption) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoChunkOption { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoChunkOption(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoChunkOption { + #[inline] + fn bitand_assign(&mut self, rhs: VdoChunkOption) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoChunkOption(pub ::std::os::raw::c_uint); +#[repr(C)] +pub struct VdoChunk { + pub data: gpointer, + pub size: gsize, + pub type_: VdoChunkType, + pub offset: gint64, +} +impl VdoOverlayAlign { + pub const VDO_OVERLAY_ALIGN_NONE: VdoOverlayAlign = VdoOverlayAlign(-1); +} +impl VdoOverlayAlign { + pub const VDO_OVERLAY_ALIGN_TOP: VdoOverlayAlign = VdoOverlayAlign(0); +} +impl VdoOverlayAlign { + pub const VDO_OVERLAY_ALIGN_BOTTOM: VdoOverlayAlign = VdoOverlayAlign(1); +} +impl ::std::ops::BitOr for VdoOverlayAlign { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoOverlayAlign(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoOverlayAlign { + #[inline] + fn bitor_assign(&mut self, rhs: VdoOverlayAlign) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoOverlayAlign { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoOverlayAlign(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoOverlayAlign { + #[inline] + fn bitand_assign(&mut self, rhs: VdoOverlayAlign) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoOverlayAlign(pub ::std::os::raw::c_int); +impl VdoOverlayColor { + pub const VDO_OVERLAY_COLOR_TRANSPARENT: VdoOverlayColor = VdoOverlayColor(0); +} +impl VdoOverlayColor { + pub const VDO_OVERLAY_COLOR_BLACK: VdoOverlayColor = VdoOverlayColor(61440); +} +impl VdoOverlayColor { + pub const VDO_OVERLAY_COLOR_WHITE: VdoOverlayColor = VdoOverlayColor(65535); +} +impl ::std::ops::BitOr for VdoOverlayColor { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoOverlayColor(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoOverlayColor { + #[inline] + fn bitor_assign(&mut self, rhs: VdoOverlayColor) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoOverlayColor { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoOverlayColor(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoOverlayColor { + #[inline] + fn bitand_assign(&mut self, rhs: VdoOverlayColor) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoOverlayColor(pub ::std::os::raw::c_uint); +impl VdoOverlayTextSize { + pub const VDO_OVERLAY_TEXT_SIZE_SMALL: VdoOverlayTextSize = VdoOverlayTextSize(16); +} +impl VdoOverlayTextSize { + pub const VDO_OVERLAY_TEXT_SIZE_MEDIUM: VdoOverlayTextSize = VdoOverlayTextSize(32); +} +impl VdoOverlayTextSize { + pub const VDO_OVERLAY_TEXT_SIZE_LARGE: VdoOverlayTextSize = VdoOverlayTextSize(48); +} +impl ::std::ops::BitOr for VdoOverlayTextSize { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoOverlayTextSize(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoOverlayTextSize { + #[inline] + fn bitor_assign(&mut self, rhs: VdoOverlayTextSize) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoOverlayTextSize { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoOverlayTextSize(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoOverlayTextSize { + #[inline] + fn bitand_assign(&mut self, rhs: VdoOverlayTextSize) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoOverlayTextSize(pub ::std::os::raw::c_uint); +impl VdoStreamTimestamp { + pub const VDO_TIMESTAMP_NONE: VdoStreamTimestamp = VdoStreamTimestamp(0); +} +impl VdoStreamTimestamp { + pub const VDO_TIMESTAMP_UTC: VdoStreamTimestamp = VdoStreamTimestamp(1); +} +impl VdoStreamTimestamp { + pub const VDO_TIMESTAMP_ZIPSTREAM: VdoStreamTimestamp = VdoStreamTimestamp(2); +} +impl VdoStreamTimestamp { + pub const VDO_TIMESTAMP_DIFF: VdoStreamTimestamp = VdoStreamTimestamp(4); +} +impl VdoStreamTimestamp { + pub const VDO_TIMESTAMP_MONO_CAPTURE: VdoStreamTimestamp = VdoStreamTimestamp(8); +} +impl VdoStreamTimestamp { + pub const VDO_TIMESTAMP_MONO_SERVER: VdoStreamTimestamp = VdoStreamTimestamp(16); +} +impl VdoStreamTimestamp { + pub const VDO_TIMESTAMP_MONO_CLIENT: VdoStreamTimestamp = VdoStreamTimestamp(32); +} +impl VdoStreamTimestamp { + pub const VDO_TIMESTAMP_MONO_CLIENT_SERVER_DIFF: VdoStreamTimestamp = VdoStreamTimestamp(52); +} +impl VdoStreamTimestamp { + pub const VDO_TIMESTAMP_MONO_CLIENT_CAPTURE_DIFF: VdoStreamTimestamp = VdoStreamTimestamp(44); +} +impl ::std::ops::BitOr for VdoStreamTimestamp { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoStreamTimestamp(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoStreamTimestamp { + #[inline] + fn bitor_assign(&mut self, rhs: VdoStreamTimestamp) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoStreamTimestamp { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoStreamTimestamp(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoStreamTimestamp { + #[inline] + fn bitand_assign(&mut self, rhs: VdoStreamTimestamp) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoStreamTimestamp(pub ::std::os::raw::c_uint); +impl VdoIntent { + pub const VDO_INTENT_NONE: VdoIntent = VdoIntent(0); +} +impl VdoIntent { + pub const VDO_INTENT_CONTROL: VdoIntent = VdoIntent(1); +} +impl VdoIntent { + pub const VDO_INTENT_MONITOR: VdoIntent = VdoIntent(2); +} +impl VdoIntent { + pub const VDO_INTENT_CONSUME: VdoIntent = VdoIntent(4); +} +impl VdoIntent { + pub const VDO_INTENT_PRODUCE: VdoIntent = VdoIntent(8); +} +impl VdoIntent { + pub const VDO_INTENT_DEFAULT: VdoIntent = VdoIntent(5); +} +impl VdoIntent { + pub const VDO_INTENT_EVENTFD: VdoIntent = VdoIntent(16); +} +impl VdoIntent { + pub const VDO_INTENT_UNIVERSE: VdoIntent = VdoIntent(4294967295); +} +impl ::std::ops::BitOr for VdoIntent { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoIntent(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoIntent { + #[inline] + fn bitor_assign(&mut self, rhs: VdoIntent) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoIntent { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoIntent(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoIntent { + #[inline] + fn bitand_assign(&mut self, rhs: VdoIntent) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoIntent(pub ::std::os::raw::c_uint); +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_NONE: VdoStreamEvent = VdoStreamEvent(0); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_STARTED: VdoStreamEvent = VdoStreamEvent(1); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_STOPPED: VdoStreamEvent = VdoStreamEvent(2); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_RESOURCE: VdoStreamEvent = VdoStreamEvent(16); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_QUOTA_SOFT: VdoStreamEvent = VdoStreamEvent(17); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_QUOTA_HARD: VdoStreamEvent = VdoStreamEvent(18); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_ZIPSTREAM: VdoStreamEvent = VdoStreamEvent(32); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_BUFFERING: VdoStreamEvent = VdoStreamEvent(64); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_BUFFERING_WARN: VdoStreamEvent = VdoStreamEvent(65); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_BUFFERING_FAIL: VdoStreamEvent = VdoStreamEvent(66); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_CREATED: VdoStreamEvent = VdoStreamEvent(80); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_CLOSED: VdoStreamEvent = VdoStreamEvent(81); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_EXISTING: VdoStreamEvent = VdoStreamEvent(82); +} +impl VdoStreamEvent { + pub const VDO_STREAM_EVENT_INVALID: VdoStreamEvent = VdoStreamEvent(4294967295); +} +impl ::std::ops::BitOr for VdoStreamEvent { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoStreamEvent(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoStreamEvent { + #[inline] + fn bitor_assign(&mut self, rhs: VdoStreamEvent) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoStreamEvent { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoStreamEvent(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoStreamEvent { + #[inline] + fn bitand_assign(&mut self, rhs: VdoStreamEvent) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoStreamEvent(pub ::std::os::raw::c_uint); +impl VdoBufferAccess { + pub const VDO_BUFFER_ACCESS_NONE: VdoBufferAccess = VdoBufferAccess(0); +} +impl VdoBufferAccess { + pub const VDO_BUFFER_ACCESS_CPU_RD: VdoBufferAccess = VdoBufferAccess(1); +} +impl VdoBufferAccess { + pub const VDO_BUFFER_ACCESS_DEV_RD: VdoBufferAccess = VdoBufferAccess(2); +} +impl VdoBufferAccess { + pub const VDO_BUFFER_ACCESS_ANY_RD: VdoBufferAccess = VdoBufferAccess(3); +} +impl VdoBufferAccess { + pub const VDO_BUFFER_ACCESS_CPU_WR: VdoBufferAccess = VdoBufferAccess(256); +} +impl VdoBufferAccess { + pub const VDO_BUFFER_ACCESS_DEV_WR: VdoBufferAccess = VdoBufferAccess(512); +} +impl VdoBufferAccess { + pub const VDO_BUFFER_ACCESS_ANY_WR: VdoBufferAccess = VdoBufferAccess(768); +} +impl VdoBufferAccess { + pub const VDO_BUFFER_ACCESS_CPU_RW: VdoBufferAccess = VdoBufferAccess(257); +} +impl VdoBufferAccess { + pub const VDO_BUFFER_ACCESS_DEV_RW: VdoBufferAccess = VdoBufferAccess(514); +} +impl VdoBufferAccess { + pub const VDO_BUFFER_ACCESS_ANY_RW: VdoBufferAccess = VdoBufferAccess(771); +} +impl ::std::ops::BitOr for VdoBufferAccess { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoBufferAccess(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoBufferAccess { + #[inline] + fn bitor_assign(&mut self, rhs: VdoBufferAccess) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoBufferAccess { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoBufferAccess(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoBufferAccess { + #[inline] + fn bitand_assign(&mut self, rhs: VdoBufferAccess) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoBufferAccess(pub ::std::os::raw::c_uint); +impl VdoBufferStrategy { + pub const VDO_BUFFER_STRATEGY_NONE: VdoBufferStrategy = VdoBufferStrategy(0); +} +impl VdoBufferStrategy { + pub const VDO_BUFFER_STRATEGY_INPUT: VdoBufferStrategy = VdoBufferStrategy(1); +} +impl VdoBufferStrategy { + pub const VDO_BUFFER_STRATEGY_EXTERNAL: VdoBufferStrategy = VdoBufferStrategy(2); +} +impl VdoBufferStrategy { + pub const VDO_BUFFER_STRATEGY_EXPLICIT: VdoBufferStrategy = VdoBufferStrategy(3); +} +impl VdoBufferStrategy { + pub const VDO_BUFFER_STRATEGY_INFINITE: VdoBufferStrategy = VdoBufferStrategy(4); +} +impl ::std::ops::BitOr for VdoBufferStrategy { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + VdoBufferStrategy(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for VdoBufferStrategy { + #[inline] + fn bitor_assign(&mut self, rhs: VdoBufferStrategy) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for VdoBufferStrategy { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + VdoBufferStrategy(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for VdoBufferStrategy { + #[inline] + fn bitand_assign(&mut self, rhs: VdoBufferStrategy) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct VdoBufferStrategy(pub ::std::os::raw::c_uint); +#[repr(C)] +pub struct VdoMemChunk { + pub data: gpointer, + pub data_size: gsize, +} +#[repr(C)] +pub struct VdoResolution { + pub width: guint32, + pub height: guint32, +} +#[repr(C)] +pub struct VdoResolutionSet { + pub count: gsize, + pub resolutions: __IncompleteArrayField, +} +#[repr(C)] +pub struct VdoRect { + pub width: guint, + pub height: guint, + pub x: guint, + pub y: guint, +} +#[repr(C)] +pub struct VdoPair32i { + pub __bindgen_anon_1: __BindgenUnionField, + pub __bindgen_anon_2: __BindgenUnionField, + pub __bindgen_anon_3: __BindgenUnionField, + pub val: __BindgenUnionField<[gint32; 2usize]>, + pub bindgen_union_field: [u32; 2usize], +} +#[repr(C)] +pub struct VdoPair32i__bindgen_ty_1 { + pub x: gint32, + pub y: gint32, +} +#[repr(C)] +pub struct VdoPair32i__bindgen_ty_2 { + pub w: gint32, + pub h: gint32, +} +#[repr(C)] +pub struct VdoPair32i__bindgen_ty_3 { + pub num: gint32, + pub den: gint32, +} +#[repr(C)] +pub struct VdoPair32u { + pub __bindgen_anon_1: __BindgenUnionField, + pub __bindgen_anon_2: __BindgenUnionField, + pub __bindgen_anon_3: __BindgenUnionField, + pub res: __BindgenUnionField, + pub val: __BindgenUnionField<[guint32; 2usize]>, + pub bindgen_union_field: [u32; 2usize], +} +#[repr(C)] +pub struct VdoPair32u__bindgen_ty_1 { + pub x: guint32, + pub y: guint32, +} +#[repr(C)] +pub struct VdoPair32u__bindgen_ty_2 { + pub w: guint32, + pub h: guint32, +} +#[repr(C)] +pub struct VdoPair32u__bindgen_ty_3 { + pub num: guint32, + pub den: guint32, +} +extern "C" { + pub fn vdo_wdr_mode_get_type() -> GType; +} +extern "C" { + pub fn vdo_format_get_type() -> GType; +} +extern "C" { + pub fn vdo_h264_profile_get_type() -> GType; +} +extern "C" { + pub fn vdo_h265_profile_get_type() -> GType; +} +extern "C" { + pub fn vdo_av1_profile_get_type() -> GType; +} +extern "C" { + pub fn vdo_zipstream_profile_get_type() -> GType; +} +extern "C" { + pub fn vdo_rate_control_mode_get_type() -> GType; +} +extern "C" { + pub fn vdo_rate_control_priority_get_type() -> GType; +} +extern "C" { + pub fn vdo_frame_type_get_type() -> GType; +} +extern "C" { + pub fn vdo_color_get_type() -> GType; +} +extern "C" { + pub fn vdo_timestamp_get_type() -> GType; +} +extern "C" { + pub fn vdo_intent_get_type() -> GType; +} +extern "C" { + pub fn vdo_buffer_access_get_type() -> GType; +} +extern "C" { + pub fn vdo_buffer_strategy_get_type() -> GType; +} +extern "C" { + pub fn vdo_format_to_str(format: VdoFormat) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn vdo_map_get_type() -> GType; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _VdoMap { + _unused: [u8; 0], +} +pub type VdoMap = _VdoMap; +#[repr(C)] +pub struct VdoMapClass { + pub parent_class: GObjectClass, +} +pub type VdoMap_autoptr = *mut VdoMap; +pub type VdoMap_listautoptr = *mut GList; +pub type VdoMap_slistautoptr = *mut GSList; +pub type VdoMap_queueautoptr = *mut GQueue; +pub type VdoMapClass_autoptr = *mut VdoMapClass; +pub type VdoMapClass_listautoptr = *mut GList; +pub type VdoMapClass_slistautoptr = *mut GSList; +pub type VdoMapClass_queueautoptr = *mut GQueue; +extern "C" { + pub fn vdo_map_new() -> *mut VdoMap; +} +extern "C" { + pub fn vdo_map_new_from_variant(dictionary: *mut GVariant) -> *mut VdoMap; +} +extern "C" { + pub fn vdo_map_empty(self_: *const VdoMap) -> gboolean; +} +extern "C" { + pub fn vdo_map_size(self_: *const VdoMap) -> gsize; +} +extern "C" { + pub fn vdo_map_swap(lhs: *mut VdoMap, rhs: *mut VdoMap); +} +extern "C" { + pub fn vdo_map_contains(self_: *const VdoMap, name: *const gchar) -> gboolean; +} +extern "C" { + pub fn vdo_map_contains_va(self_: *const VdoMap, ...) -> gboolean; +} +extern "C" { + pub fn vdo_map_contains_strv(self_: *const VdoMap, names: *const *const gchar) -> gboolean; +} +extern "C" { + pub fn vdo_map_entry_equals( + self_: *const VdoMap, + map: *const VdoMap, + name: *const gchar, + ) -> gboolean; +} +extern "C" { + pub fn vdo_map_entry_updates( + self_: *const VdoMap, + map: *const VdoMap, + name: *const gchar, + ) -> gboolean; +} +extern "C" { + pub fn vdo_map_equals(self_: *const VdoMap, map: *const VdoMap) -> gboolean; +} +extern "C" { + pub fn vdo_map_equals_va(self_: *const VdoMap, map: *const VdoMap, ...) -> gboolean; +} +extern "C" { + pub fn vdo_map_equals_strv( + self_: *const VdoMap, + map: *const VdoMap, + names: *const *const gchar, + ) -> gboolean; +} +extern "C" { + pub fn vdo_map_remove(self_: *mut VdoMap, name: *const gchar); +} +extern "C" { + pub fn vdo_map_remove_va(self_: *mut VdoMap, ...); +} +extern "C" { + pub fn vdo_map_remove_strv(self_: *mut VdoMap, names: *const *const gchar); +} +extern "C" { + pub fn vdo_map_clear(self_: *mut VdoMap); +} +extern "C" { + pub fn vdo_map_filter_prefix(self_: *const VdoMap, prefix: *const gchar) -> *mut VdoMap; +} +extern "C" { + pub fn vdo_map_filter_va(self_: *const VdoMap, ...) -> *mut VdoMap; +} +extern "C" { + pub fn vdo_map_filter_strv(self_: *const VdoMap, names: *const *const gchar) -> *mut VdoMap; +} +extern "C" { + pub fn vdo_map_merge(self_: *mut VdoMap, map: *const VdoMap); +} +extern "C" { + pub fn vdo_map_copy_value(self_: *mut VdoMap, src: *const gchar, dst: *const gchar); +} +extern "C" { + pub fn vdo_map_to_variant(self_: *const VdoMap) -> *mut GVariant; +} +extern "C" { + pub fn vdo_map_dump(self_: *const VdoMap); +} +extern "C" { + pub fn vdo_map_get_byte(self_: *const VdoMap, name: *const gchar, def: guchar) -> guchar; +} +extern "C" { + pub fn vdo_map_get_int16(self_: *const VdoMap, name: *const gchar, def: gint16) -> gint16; +} +extern "C" { + pub fn vdo_map_get_uint16(self_: *const VdoMap, name: *const gchar, def: guint16) -> guint16; +} +extern "C" { + pub fn vdo_map_get_uint32x2( + self_: *const VdoMap, + name: *const gchar, + def: *mut guint32, + ) -> *mut guint32; +} +extern "C" { + pub fn vdo_map_get_uint32x4( + self_: *const VdoMap, + name: *const gchar, + def: *mut guint32, + ) -> *mut guint32; +} +extern "C" { + pub fn vdo_map_get_doublex4( + self_: *const VdoMap, + name: *const gchar, + def: *mut gdouble, + ) -> *mut gdouble; +} +extern "C" { + pub fn vdo_map_get_variant( + self_: *const VdoMap, + name: *const gchar, + def: *mut GVariant, + ) -> *mut GVariant; +} +extern "C" { + pub fn vdo_map_get_boolean(self_: *const VdoMap, name: *const gchar, def: gboolean) + -> gboolean; +} +extern "C" { + pub fn vdo_map_get_int32(self_: *const VdoMap, name: *const gchar, def: gint32) -> gint32; +} +extern "C" { + pub fn vdo_map_get_uint32(self_: *const VdoMap, name: *const gchar, def: guint32) -> guint32; +} +extern "C" { + pub fn vdo_map_get_int64(self_: *const VdoMap, name: *const gchar, def: gint64) -> gint64; +} +extern "C" { + pub fn vdo_map_get_uint64(self_: *const VdoMap, name: *const gchar, def: guint64) -> guint64; +} +extern "C" { + pub fn vdo_map_get_double(self_: *const VdoMap, name: *const gchar, def: gdouble) -> gdouble; +} +extern "C" { + pub fn vdo_map_get_string( + self_: *const VdoMap, + name: *const gchar, + size: *mut gsize, + def: *const gchar, + ) -> *const gchar; +} +extern "C" { + pub fn vdo_map_dup_string( + self_: *const VdoMap, + name: *const gchar, + def: *const gchar, + ) -> *mut gchar; +} +extern "C" { + pub fn vdo_map_get_pair32i( + self_: *const VdoMap, + name: *const gchar, + def: VdoPair32i, + ) -> VdoPair32i; +} +extern "C" { + pub fn vdo_map_get_pair32u( + self_: *const VdoMap, + name: *const gchar, + def: VdoPair32u, + ) -> VdoPair32u; +} +extern "C" { + pub fn vdo_map_set_byte(self_: *mut VdoMap, name: *const gchar, value: guchar); +} +extern "C" { + pub fn vdo_map_set_int16(self_: *mut VdoMap, name: *const gchar, value: gint16); +} +extern "C" { + pub fn vdo_map_set_uint16(self_: *mut VdoMap, name: *const gchar, value: guint16); +} +extern "C" { + pub fn vdo_map_set_uint32x2(self_: *mut VdoMap, name: *const gchar, value: *const guint32); +} +extern "C" { + pub fn vdo_map_set_uint32x4(self_: *mut VdoMap, name: *const gchar, value: *const guint32); +} +extern "C" { + pub fn vdo_map_set_doublex4(self_: *mut VdoMap, name: *const gchar, value: *const gdouble); +} +extern "C" { + pub fn vdo_map_set_boolean(self_: *mut VdoMap, name: *const gchar, value: gboolean); +} +extern "C" { + pub fn vdo_map_set_int32(self_: *mut VdoMap, name: *const gchar, value: gint32); +} +extern "C" { + pub fn vdo_map_set_uint32(self_: *mut VdoMap, name: *const gchar, value: guint32); +} +extern "C" { + pub fn vdo_map_set_int64(self_: *mut VdoMap, name: *const gchar, value: gint64); +} +extern "C" { + pub fn vdo_map_set_uint64(self_: *mut VdoMap, name: *const gchar, value: guint64); +} +extern "C" { + pub fn vdo_map_set_double(self_: *mut VdoMap, name: *const gchar, value: gdouble); +} +extern "C" { + pub fn vdo_map_set_string(self_: *mut VdoMap, name: *const gchar, value: *const gchar); +} +extern "C" { + pub fn vdo_map_set_pair32i(self_: *mut VdoMap, name: *const gchar, value: VdoPair32i); +} +extern "C" { + pub fn vdo_map_set_pair32u(self_: *mut VdoMap, name: *const gchar, value: VdoPair32u); +} +extern "C" { + pub fn vdo_channel_get_type() -> GType; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _VdoChannel { + _unused: [u8; 0], +} +pub type VdoChannel = _VdoChannel; +#[repr(C)] +pub struct VdoChannelClass { + pub parent_class: GObjectClass, +} +pub type VdoChannel_autoptr = *mut VdoChannel; +pub type VdoChannel_listautoptr = *mut GList; +pub type VdoChannel_slistautoptr = *mut GSList; +pub type VdoChannel_queueautoptr = *mut GQueue; +pub type VdoChannelClass_autoptr = *mut VdoChannelClass; +pub type VdoChannelClass_listautoptr = *mut GList; +pub type VdoChannelClass_slistautoptr = *mut GSList; +pub type VdoChannelClass_queueautoptr = *mut GQueue; +extern "C" { + pub fn vdo_channel_get(channel_nbr: guint, error: *mut *mut GError) -> *mut VdoChannel; +} +extern "C" { + pub fn vdo_channel_get_ex(desc: *mut VdoMap, error: *mut *mut GError) -> *mut VdoChannel; +} +extern "C" { + pub fn vdo_channel_get_all(error: *mut *mut GError) -> *mut GList; +} +extern "C" { + pub fn vdo_channel_get_filtered(filter: *mut VdoMap, error: *mut *mut GError) -> *mut GList; +} +extern "C" { + pub fn vdo_channel_get_info(self_: *mut VdoChannel, error: *mut *mut GError) -> *mut VdoMap; +} +extern "C" { + pub fn vdo_channel_get_settings(self_: *mut VdoChannel, error: *mut *mut GError) + -> *mut VdoMap; +} +extern "C" { + pub fn vdo_channel_set_settings( + self_: *mut VdoChannel, + settings: *mut VdoMap, + error: *mut *mut GError, + ) -> gboolean; +} +extern "C" { + pub fn vdo_channel_get_stream_profile( + self_: *mut VdoChannel, + profile: *const gchar, + format: VdoFormat, + error: *mut *mut GError, + ) -> *mut VdoMap; +} +extern "C" { + pub fn vdo_channel_get_resolutions( + self_: *mut VdoChannel, + filter: *mut VdoMap, + error: *mut *mut GError, + ) -> *mut VdoResolutionSet; +} +extern "C" { + pub fn vdo_channel_get_id(self_: *mut VdoChannel) -> guint; +} +extern "C" { + pub fn vdo_channel_set_stream_profile( + self_: *mut VdoChannel, + profile: *const gchar, + format: VdoFormat, + settings: *mut VdoMap, + error: *mut *mut GError, + ) -> gboolean; +} +extern "C" { + pub fn vdo_channel_set_crop_dptz( + self_: *mut VdoChannel, + x: guint, + y: guint, + width: guint, + height: guint, + error: *mut *mut GError, + ) -> gboolean; +} +extern "C" { + pub fn vdo_channel_apply_alpha_blending( + self_: *mut VdoChannel, + fd: gint, + error: *mut *mut GError, + ) -> gboolean; +} +extern "C" { + pub fn vdo_channel_set_framerate( + self_: *mut VdoChannel, + framerate: gdouble, + error: *mut *mut GError, + ) -> gboolean; +} +extern "C" { + pub fn vdo_frame_get_type() -> GType; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _VdoFrame { + _unused: [u8; 0], +} +pub type VdoFrame = _VdoFrame; +#[repr(C)] +pub struct VdoFrameClass { + pub parent_class: GObjectClass, +} +pub type VdoFrame_autoptr = *mut VdoFrame; +pub type VdoFrame_listautoptr = *mut GList; +pub type VdoFrame_slistautoptr = *mut GSList; +pub type VdoFrame_queueautoptr = *mut GQueue; +pub type VdoFrameClass_autoptr = *mut VdoFrameClass; +pub type VdoFrameClass_listautoptr = *mut GList; +pub type VdoFrameClass_slistautoptr = *mut GSList; +pub type VdoFrameClass_queueautoptr = *mut GQueue; +pub type VdoFrameFinalizer = ::std::option::Option; +extern "C" { + pub fn vdo_frame_get_frame_type(self_: *mut VdoFrame) -> VdoFrameType; +} +extern "C" { + pub fn vdo_frame_is_key(self_: *mut VdoFrame) -> gboolean; +} +extern "C" { + pub fn vdo_frame_shown(self_: *mut VdoFrame) -> gboolean; +} +extern "C" { + pub fn vdo_frame_get_sequence_nbr(self_: *mut VdoFrame) -> guint; +} +extern "C" { + pub fn vdo_frame_get_timestamp(self_: *mut VdoFrame) -> guint64; +} +extern "C" { + pub fn vdo_frame_get_custom_timestamp(self_: *mut VdoFrame) -> gint64; +} +extern "C" { + pub fn vdo_frame_get_size(self_: *mut VdoFrame) -> gsize; +} +extern "C" { + pub fn vdo_frame_get_header_size(self_: *mut VdoFrame) -> gssize; +} +extern "C" { + pub fn vdo_frame_get_fd(self_: *mut VdoFrame) -> gint; +} +extern "C" { + pub fn vdo_frame_get_extra_info(self_: *mut VdoFrame) -> *mut VdoMap; +} +extern "C" { + pub fn vdo_frame_get_opaque(self_: *mut VdoFrame) -> gpointer; +} +extern "C" { + pub fn vdo_frame_get_is_last_buffer(self_: *mut VdoFrame) -> gboolean; +} +extern "C" { + pub fn vdo_frame_set_size(self_: *mut VdoFrame, size: gsize); +} +extern "C" { + pub fn vdo_frame_set_frame_type(self_: *mut VdoFrame, type_: VdoFrameType); +} +extern "C" { + pub fn vdo_frame_set_sequence_nbr(self_: *mut VdoFrame, seqnum: guint); +} +extern "C" { + pub fn vdo_frame_set_timestamp(self_: *mut VdoFrame, timestamp: guint64); +} +extern "C" { + pub fn vdo_frame_set_custom_timestamp(self_: *mut VdoFrame, timestamp: gint64); +} +extern "C" { + pub fn vdo_frame_set_is_last_buffer(self_: *mut VdoFrame, is_last_buffer: gboolean); +} +extern "C" { + pub fn vdo_frame_set_extra_info(self_: *mut VdoFrame, extra_info: *mut VdoMap); +} +extern "C" { + pub fn vdo_frame_set_header_size(self_: *mut VdoFrame, size: gssize); +} +extern "C" { + pub fn vdo_frame_memmap(self_: *mut VdoFrame) -> gpointer; +} +extern "C" { + pub fn vdo_frame_unmap(self_: *mut VdoFrame); +} +extern "C" { + pub fn vdo_frame_take_chunk(self_: *mut VdoFrame, error: *mut *mut GError) -> VdoChunk; +} +extern "C" { + pub fn vdo_frame_take_chunk_ex( + self_: *mut VdoFrame, + options: VdoChunkOption, + error: *mut *mut GError, + ) -> VdoChunk; +} +pub type VdoBuffer = VdoFrame; +pub type VdoBuffer_autoptr = *mut VdoBuffer; +pub type VdoBuffer_listautoptr = *mut GList; +pub type VdoBuffer_slistautoptr = *mut GSList; +pub type VdoBuffer_queueautoptr = *mut GQueue; +pub type VdoBufferFinalizer = ::std::option::Option; +extern "C" { + pub fn vdo_buffer_new( + fd: gint, + capacity: gsize, + offset: guint64, + opaque: gpointer, + ) -> *mut VdoBuffer; +} +extern "C" { + pub fn vdo_buffer_new_full( + fd: gint, + capacity: gsize, + offset: guint64, + opaque: gpointer, + settings: *mut VdoMap, + ) -> *mut VdoBuffer; +} +extern "C" { + pub fn vdo_buffer_get_id(self_: *mut VdoBuffer) -> guint32; +} +extern "C" { + pub fn vdo_buffer_get_fd(self_: *mut VdoBuffer) -> gint; +} +extern "C" { + pub fn vdo_buffer_get_offset(self_: *mut VdoBuffer) -> gint64; +} +extern "C" { + pub fn vdo_buffer_get_capacity(self_: *mut VdoBuffer) -> gsize; +} +extern "C" { + pub fn vdo_buffer_is_complete(self_: *mut VdoBuffer) -> gboolean; +} +extern "C" { + pub fn vdo_buffer_get_opaque(self_: *mut VdoBuffer) -> gpointer; +} +extern "C" { + pub fn vdo_buffer_get_data(self_: *mut VdoBuffer) -> gpointer; +} +extern "C" { + pub fn vdo_buffer_get_frame(self_: *mut VdoBuffer) -> *mut VdoFrame; +} +extern "C" { + pub fn vdo_stream_get_type() -> GType; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _VdoStream { + _unused: [u8; 0], +} +pub type VdoStream = _VdoStream; +#[repr(C)] +pub struct VdoStreamClass { + pub parent_class: GObjectClass, +} +pub type VdoStream_autoptr = *mut VdoStream; +pub type VdoStream_listautoptr = *mut GList; +pub type VdoStream_slistautoptr = *mut GSList; +pub type VdoStream_queueautoptr = *mut GQueue; +pub type VdoStreamClass_autoptr = *mut VdoStreamClass; +pub type VdoStreamClass_listautoptr = *mut GList; +pub type VdoStreamClass_slistautoptr = *mut GSList; +pub type VdoStreamClass_queueautoptr = *mut GQueue; +extern "C" { + pub fn vdo_stream_new( + settings: *mut VdoMap, + fin: VdoBufferFinalizer, + error: *mut *mut GError, + ) -> *mut VdoStream; +} +extern "C" { + pub fn vdo_stream_get(id: guint, error: *mut *mut GError) -> *mut VdoStream; +} +extern "C" { + pub fn vdo_stream_get_all(error: *mut *mut GError) -> *mut GList; +} +extern "C" { + pub fn vdo_stream_get_id(self_: *mut VdoStream) -> guint; +} +extern "C" { + pub fn vdo_stream_get_fd(self_: *mut VdoStream, error: *mut *mut GError) -> gint; +} +extern "C" { + pub fn vdo_stream_get_event_fd(self_: *mut VdoStream, error: *mut *mut GError) -> gint; +} +extern "C" { + pub fn vdo_stream_get_info(self_: *mut VdoStream, error: *mut *mut GError) -> *mut VdoMap; +} +extern "C" { + pub fn vdo_stream_get_settings(self_: *mut VdoStream, error: *mut *mut GError) -> *mut VdoMap; +} +extern "C" { + pub fn vdo_stream_set_settings( + self_: *mut VdoStream, + settings: *mut VdoMap, + error: *mut *mut GError, + ) -> gboolean; +} +extern "C" { + pub fn vdo_stream_set_framerate( + self_: *mut VdoStream, + framerate: gdouble, + error: *mut *mut GError, + ) -> gboolean; +} +extern "C" { + pub fn vdo_stream_attach( + self_: *mut VdoStream, + intent: *mut VdoMap, + error: *mut *mut GError, + ) -> gboolean; +} +extern "C" { + pub fn vdo_stream_start(self_: *mut VdoStream, error: *mut *mut GError) -> gboolean; +} +extern "C" { + pub fn vdo_stream_play( + self_: *mut VdoStream, + settings: *mut VdoMap, + error: *mut *mut GError, + ) -> gboolean; +} +extern "C" { + pub fn vdo_stream_stop(self_: *mut VdoStream); +} +extern "C" { + pub fn vdo_stream_force_key_frame(self_: *mut VdoStream, error: *mut *mut GError) -> gboolean; +} +extern "C" { + pub fn vdo_stream_buffer_alloc( + self_: *mut VdoStream, + opaque: gpointer, + error: *mut *mut GError, + ) -> *mut VdoBuffer; +} +extern "C" { + pub fn vdo_stream_buffer_unref( + self_: *mut VdoStream, + buffer: *mut *mut VdoBuffer, + error: *mut *mut GError, + ) -> gboolean; +} +extern "C" { + pub fn vdo_stream_buffer_enqueue( + self_: *mut VdoStream, + buffer: *mut VdoBuffer, + error: *mut *mut GError, + ) -> gboolean; +} +extern "C" { + pub fn vdo_stream_get_buffer(self_: *mut VdoStream, error: *mut *mut GError) -> *mut VdoBuffer; +} +extern "C" { + pub fn vdo_stream_to_fd( + settings: *mut VdoMap, + data_fd: ::std::os::raw::c_int, + meta_fd: ::std::os::raw::c_int, + error: *mut *mut GError, + ) -> *mut VdoStream; +} +extern "C" { + pub fn vdo_stream_snapshot(settings: *mut VdoMap, error: *mut *mut GError) -> *mut VdoBuffer; +} +extern "C" { + pub fn vdo_stream_encode( + self_: *mut VdoStream, + in_buf: *mut *mut VdoBuffer, + settings: *mut VdoMap, + error: *mut *mut GError, + ) -> gboolean; +} +extern "C" { + pub fn vdo_stream_get_event(self_: *mut VdoStream, error: *mut *mut GError) -> *mut VdoMap; +} +pub const VDO_ERROR_NOT_FOUND: _bindgen_ty_24 = _bindgen_ty_24(1); +pub const VDO_ERROR_EXISTS: _bindgen_ty_24 = _bindgen_ty_24(2); +pub const VDO_ERROR_INVALID_ARGUMENT: _bindgen_ty_24 = _bindgen_ty_24(3); +pub const VDO_ERROR_PERMISSION_DENIED: _bindgen_ty_24 = _bindgen_ty_24(4); +pub const VDO_ERROR_NOT_SUPPORTED: _bindgen_ty_24 = _bindgen_ty_24(5); +pub const VDO_ERROR_CLOSED: _bindgen_ty_24 = _bindgen_ty_24(6); +pub const VDO_ERROR_BUSY: _bindgen_ty_24 = _bindgen_ty_24(7); +pub const VDO_ERROR_IO: _bindgen_ty_24 = _bindgen_ty_24(8); +pub const VDO_ERROR_HAL: _bindgen_ty_24 = _bindgen_ty_24(9); +pub const VDO_ERROR_DBUS: _bindgen_ty_24 = _bindgen_ty_24(10); +pub const VDO_ERROR_OOM: _bindgen_ty_24 = _bindgen_ty_24(11); +pub const VDO_ERROR_IDLE: _bindgen_ty_24 = _bindgen_ty_24(12); +pub const VDO_ERROR_NO_DATA: _bindgen_ty_24 = _bindgen_ty_24(13); +pub const VDO_ERROR_NO_BUFFER_SPACE: _bindgen_ty_24 = _bindgen_ty_24(14); +pub const VDO_ERROR_BUFFER_FAILURE: _bindgen_ty_24 = _bindgen_ty_24(15); +pub const VDO_ERROR_INTERFACE_DOWN: _bindgen_ty_24 = _bindgen_ty_24(16); +pub const VDO_ERROR_FAILED: _bindgen_ty_24 = _bindgen_ty_24(17); +pub const VDO_ERROR_FATAL: _bindgen_ty_24 = _bindgen_ty_24(18); +pub const VDO_ERROR_NOT_CONTROLLED: _bindgen_ty_24 = _bindgen_ty_24(19); +pub const VDO_ERROR_NO_EVENT: _bindgen_ty_24 = _bindgen_ty_24(20); +pub const VDO_ERROR_NO_VIDEO: _bindgen_ty_24 = _bindgen_ty_24(21); +impl ::std::ops::BitOr<_bindgen_ty_24> for _bindgen_ty_24 { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + _bindgen_ty_24(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for _bindgen_ty_24 { + #[inline] + fn bitor_assign(&mut self, rhs: _bindgen_ty_24) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd<_bindgen_ty_24> for _bindgen_ty_24 { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + _bindgen_ty_24(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for _bindgen_ty_24 { + #[inline] + fn bitand_assign(&mut self, rhs: _bindgen_ty_24) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct _bindgen_ty_24(pub ::std::os::raw::c_uint); +extern "C" { + pub fn vdo_error_quark() -> GQuark; +} +extern "C" { + pub fn vdo_error_is_expected(error: *mut *mut GError) -> gboolean; +} +extern "C" { + pub fn vdo_error_is_resource_limitation(error: *mut *mut GError) -> gboolean; +} diff --git a/crates/vdo-sys/src/lib.rs b/crates/vdo-sys/src/lib.rs new file mode 100644 index 00000000..e4a83645 --- /dev/null +++ b/crates/vdo-sys/src/lib.rs @@ -0,0 +1,31 @@ +//! Fairly nasty binding for VdoResolutionSet due to "Flexible Array Member" +//! https://rust-lang.github.io/rust-bindgen/using-fam.html +//! https://github.com/rust-lang/rust-bindgen/issues/1680#issuecomment-554296347 +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +use glib_sys::*; +use gobject_sys::*; + +type gchar = core::ffi::c_char; +type guchar = core::ffi::c_uchar; +type gdouble = core::ffi::c_double; + +type gint = core::ffi::c_int; +type guint = core::ffi::c_uint; +type gint16 = i16; +type guint16 = u16; +type gint32 = i32; +type guint32 = u32; +type gint64 = i64; +type guint64 = u64; + +type gsize = usize; +type gssize = isize; + +#[cfg(not(target_arch = "x86_64"))] +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + +#[cfg(target_arch = "x86_64")] +include!("bindings.rs"); diff --git a/crates/vdo-sys/wrapper.h b/crates/vdo-sys/wrapper.h new file mode 100644 index 00000000..6d5328f6 --- /dev/null +++ b/crates/vdo-sys/wrapper.h @@ -0,0 +1,5 @@ +#include +#include +#include +#include +#include diff --git a/crates/vdo/Cargo.toml b/crates/vdo/Cargo.toml new file mode 100644 index 00000000..c1bc3558 --- /dev/null +++ b/crates/vdo/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "vdo" +version = "0.1.0" +edition.workspace = true + +[dependencies] +vdo-sys = { workspace = true } +log.workspace = true +anyhow.workspace = true +glib.workspace = true +glib-sys.workspace = true +gobject-sys = "0.19.5" +thiserror.workspace = true + +[features] +device-tests = [] + +[[example]] +name = "basic" + +[dev-dependencies] +env_logger.workspace = true diff --git a/crates/vdo/examples/basic.rs b/crates/vdo/examples/basic.rs new file mode 100644 index 00000000..15936e3b --- /dev/null +++ b/crates/vdo/examples/basic.rs @@ -0,0 +1,25 @@ +use anyhow::{Error, Result}; +use vdo::{Stream, VdoBufferStrategy, VdoFormat}; + +fn main() -> Result<()> { + let mut stream = Stream::builder() + .channel(0) + .format(VdoFormat::VDO_FORMAT_PLANAR_RGB) + .width(1920) + .height(1080) + .buffer_strategy(VdoBufferStrategy::VDO_BUFFER_STRATEGY_EXPLICIT) + .build() + .expect("Unable to create stream"); + stream + .allocate_buffers(5) + .expect("failed to allocate buffers"); + let mut running_stream = stream.start().expect("failed to start stream"); + for (idx, buffer) in running_stream.iter().enumerate() { + let frame = buffer.frame().expect("failed to get frame from buffer"); + println!("frame size: {}", frame.size()); + if idx > 5 { + break; + } + } + Ok(()) +} diff --git a/crates/vdo/src/lib.rs b/crates/vdo/src/lib.rs new file mode 100644 index 00000000..9b53dedb --- /dev/null +++ b/crates/vdo/src/lib.rs @@ -0,0 +1,778 @@ +//! Stream buffer strategy seems to be round robin. Allocate N buffers with +//! `vod_stream_buffer_alloc`, enqueue the buffers with, +//! `vdo_stream_buffer_alloc`, and VDO will round robin the buffers and place +//! frame data in them. +//! + +use glib_sys::{GError, GTRUE}; +use gobject_sys::{g_object_unref, GObject}; +use log::error; +use std::ffi::{CStr, CString}; +use std::fmt::{Debug, Display}; +use std::marker::PhantomData; +use std::mem; +use std::ptr; +use vdo_sys::*; +pub use vdo_sys::{VdoBufferStrategy, VdoFormat}; + +macro_rules! try_func { + ($func:ident $(,)?) => {{ + let mut error: *mut GError = ptr::null_mut(); + let success = $func(&mut error); + if error.is_null() { + (success, None) + } else { + (success, Some(Error::VDOError(VDOError::from_gerror(error)))) + } + }}; + ($func:ident, $($arg:expr),+ $(,)?) => {{ + let mut error: *mut GError = ptr::null_mut(); + let success = $func($( $arg ),+, &mut error); + if error.is_null() { + (success, None) + } else { + (success, Some(Error::VDOError(VDOError::from_gerror(error)))) + } + + }} +} + +#[derive(Default)] +pub struct VDOError { + code: i32, + message: String, +} + +impl Display for VDOError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "VDOError {{ code: {}, phrase: {}, message: {} }}", + self.code, + self.get_code_message(), + self.message + ) + } +} + +impl VDOError { + fn get_code_message(&self) -> &str { + let code_u = u32::try_from(self.code).unwrap_or(0); + if code_u == VDO_ERROR_NOT_FOUND as u32 { + "VDO_ERROR_NOT_FOUND" + } else if code_u == VDO_ERROR_EXISTS as u32 { + "VDO_ERROR_EXISTS" + } else if code_u == VDO_ERROR_INVALID_ARGUMENT as u32 { + "VDO_ERROR_INVALID_ARGUMENT" + } else if code_u == VDO_ERROR_PERMISSION_DENIED as u32 { + "VDO_ERROR_PERMISSION_DENIED" + } else if code_u == VDO_ERROR_NOT_SUPPORTED as u32 { + "VDO_ERROR_NOT_SUPPORTED" + } else if code_u == VDO_ERROR_CLOSED as u32 { + "VDO_ERROR_CLOSED" + } else if code_u == VDO_ERROR_BUSY as u32 { + "VDO_ERROR_BUSY" + } else if code_u == VDO_ERROR_IO as u32 { + "VDO_ERROR_IO" + } else if code_u == VDO_ERROR_HAL as u32 { + "VDO_ERROR_HAL" + } else if code_u == VDO_ERROR_DBUS as u32 { + "VDO_ERROR_DBUS" + } else if code_u == VDO_ERROR_OOM as u32 { + "VDO_ERROR_OOM" + } else if code_u == VDO_ERROR_IDLE as u32 { + "VDO_ERROR_IDLE" + } else if code_u == VDO_ERROR_NO_DATA as u32 { + "VDO_ERROR_NO_DATA" + } else if code_u == VDO_ERROR_NO_BUFFER_SPACE as u32 { + "VDO_ERROR_NO_BUFFER_SPACE" + } else if code_u == VDO_ERROR_BUFFER_FAILURE as u32 { + "VDO_ERROR_BUFFER_FAILURE" + } else if code_u == VDO_ERROR_INTERFACE_DOWN as u32 { + "VDO_ERROR_INTERFACE_DOWN" + } else if code_u == VDO_ERROR_FAILED as u32 { + "VDO_ERROR_FAILED" + } else if code_u == VDO_ERROR_FATAL as u32 { + "VDO_ERROR_FATAL" + } else if code_u == VDO_ERROR_NOT_CONTROLLED as u32 { + "VDO_ERROR_NOT_CONTROLLED" + } else if code_u == VDO_ERROR_NO_EVENT as u32 { + "VDO_ERROR_NO_EVENT" + } else { + "VDO_ERROR_FAILED" + } + } + + fn from_gerror(gerror: *mut GError) -> Self { + if !gerror.is_null() { + let g_error = unsafe { *gerror }; + if !g_error.message.is_null() { + let msg = unsafe { CStr::from_ptr(g_error.message) }; + VDOError { + code: g_error.code, + message: String::from(msg.to_str().unwrap_or("Invalid message")), + } + } else { + VDOError { + code: g_error.code, + message: String::from("Invalid message"), + } + } + } else { + VDOError::default() + } + } +} + +impl std::error::Error for VDOError {} + +impl Debug for VDOError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self) + } +} + +type Result = std::result::Result; +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + VDOError(#[from] VDOError), + #[error("libvdo returned an unexpected null pointer")] + NullPointer, + #[error("could not allocate memory for CString")] + CStringAllocation, + #[error("missing error data from libvdo")] + MissingVDOError, + #[error("poisoned pointer to stream")] + PoisonedStream, + #[error("no buffers are allocated for the stream")] + NoBuffersAllocated, +} + +pub struct Map { + raw: *mut VdoMap, +} + +impl Map { + /// Create a new larodMap object + pub fn new() -> Result { + let map = unsafe { vdo_map_new() }; + if !map.is_null() { + Ok(Self { raw: map }) + } else { + Err(Error::NullPointer) + } + } + + pub fn set_u32(&self, key: &str, value: u32) -> Result<()> { + let Ok(key_cstr) = CString::new(key) else { + return Err(Error::CStringAllocation); + }; + unsafe { + vdo_map_set_uint32(self.raw, key_cstr.as_ptr(), value); + } + Ok(()) + } + + pub fn dump(&self) { + unsafe { + vdo_map_dump(self.raw); + } + } +} + +impl Drop for Map { + // using g_object_unref is sourced from the vdo-larod examples + // https://github.com/AxisCommunications/acap-native-sdk-examples/blob/36800ed4c28dd96a2b659db3cb2c8a937c61d6d0/vdo-larod/app/imgprovider.c#L355 + fn drop(&mut self) { + unsafe { g_object_unref(self.raw as *mut GObject) } + } +} + +#[allow(dead_code)] +pub struct StreamBuilder { + format: VdoFormat, + buffer_access: u32, + buffer_count: u32, + buffer_strategy: VdoBufferStrategy, + input: u32, + channel: u32, + width: u32, + height: u32, + framerate: u32, + compression: u32, + rotation: u32, + horizontal_flip: bool, + monochrome: bool, + dynamic_gop: bool, + dynamic_bitrate: bool, + dynamic_framerate: bool, + dynamic_compression: bool, + qp_i: u32, + qp_p: u32, + bitrate: u32, + rc_mode: VdoRateControlMode, + rc_prio: VdoRateControlPriority, + gop_length: u32, + overlays: Option, +} + +impl Default for StreamBuilder { + /// VdoBufferStrategy::VDO_BUFFER_STRATEGY_EXPLICIT only works for VdoFormat::VDO_FORMAT_YUV and RGB + /// VdoBufferStrategy::VDO_BUFFER_STRATEGY_INFINITE works for all VdoFormat's. + fn default() -> Self { + StreamBuilder { + format: VdoFormat::VDO_FORMAT_H264, + buffer_access: 0, + buffer_count: 0, + buffer_strategy: VdoBufferStrategy::VDO_BUFFER_STRATEGY_INFINITE, + input: 0, + channel: 0, + width: 0, + height: 0, + framerate: 0, + compression: 0, + rotation: 0, + horizontal_flip: false, + monochrome: false, + dynamic_gop: false, + dynamic_bitrate: false, + dynamic_framerate: false, + dynamic_compression: false, + qp_i: 0, + qp_p: 0, + bitrate: 0, + rc_mode: VdoRateControlMode::VDO_RATE_CONTROL_MODE_NONE, + rc_prio: VdoRateControlPriority::VDO_RATE_CONTROL_PRIORITY_NONE, + gop_length: 0, + overlays: None, + } + } +} + +impl StreamBuilder { + pub fn new() -> Self { + StreamBuilder::default() + } + + /// Set the number of buffers to use for the stream. + /// For VdoFormat::VDO_FORMAT_YUV and RGB, the default number of buffers is 3. + /// For VdoFormat::VDO_FORMAT_JPEG and h26x this number is ignored. + pub fn buffers(mut self, num_buffers: u32) -> Self { + self.buffer_count = num_buffers; + self + } + + pub fn channel(mut self, chan: u32) -> Self { + self.channel = chan; + self + } + pub fn format(mut self, format: VdoFormat) -> Self { + self.format = format; + self + } + + /// Set the resolution for the stream. + pub fn resolution(mut self, width: u32, height: u32) -> Self { + self.width = width; + self.height = height; + self + } + + pub fn framerate(mut self, framerate: u32) -> Self { + self.framerate = framerate; + self + } + + pub fn build(self) -> Result { + let map = Map::new()?; + map.set_u32("channel", self.channel)?; + map.set_u32("format", self.format as u32)?; + map.set_u32("width", self.width)?; + map.set_u32("height", self.height)?; + map.set_u32("framerate", self.framerate)?; + map.set_u32("buffer.count", self.buffer_count)?; + map.set_u32("buffer.strategy", self.buffer_strategy as u32)?; + let (stream_raw, maybe_error) = unsafe { try_func!(vdo_stream_new, map.raw, None) }; + if !stream_raw.is_null() { + debug_assert!( + maybe_error.is_none(), + "vdo_stream_new returned an stream pointer AND returned an error!" + ); + Ok(Stream { + raw: StreamWrapper(stream_raw), + buffers: Vec::new(), + }) + } else { + Err(maybe_error.unwrap_or(Error::MissingVDOError)) + } + } +} + +pub struct Frame<'a> { + raw: *mut VdoFrame, + phantom: PhantomData<&'a Buffer>, +} + +impl<'a> Frame<'a> { + /// Returns the type of the frame + pub fn get_type(&self) -> VdoFrameType { + unsafe { vdo_frame_get_frame_type(self.raw) } + } + + /// Returns the sequence number of the frame. + /// The sequence number starts at 0. The point at which the sequence number + /// wraps around is undefined. + pub fn sequence_number(&self) -> u32 { + unsafe { vdo_frame_get_sequence_nbr(self.raw) } + } + + /// Return the timestamp of the frame. The time stamp is the number of + /// microseconds since boot. + pub fn timestamp(&self) -> u64 { + unsafe { vdo_frame_get_timestamp(self.raw) } + } + + /// Return the custom timestamp of the frame. + pub fn custom_timestamp(&self) -> i64 { + unsafe { vdo_frame_get_custom_timestamp(self.raw) } + } + + /// Return the size of the frame in bytes. + pub fn size(&self) -> usize { + unsafe { vdo_frame_get_size(self.raw) } + } + + pub fn header_size(&self) -> isize { + unsafe { vdo_frame_get_header_size(self.raw) } + } + + pub fn file_descriptor(&self) -> std::os::fd::BorrowedFd { + unsafe { + let fd = vdo_frame_get_fd(self.raw); + std::os::fd::BorrowedFd::borrow_raw(fd) + } + } + + pub fn is_last_buffer(&self) -> bool { + unsafe { vdo_frame_get_is_last_buffer(self.raw) != 0 } + } +} + +pub struct Buffer { + raw: *mut VdoBuffer, +} + +pub struct StreamBuffer<'a> { + buffer: Buffer, + stream: &'a Stream, +} + +impl<'a> StreamBuffer<'a> { + pub fn capacity(&self) -> usize { + unsafe { vdo_buffer_get_capacity(self.buffer.raw) } + } + pub fn as_slice(&self) -> Result<&[u8]> { + let buffer_data = unsafe { vdo_buffer_get_data(self.buffer.raw) }; + if !buffer_data.is_null() { + let slice = + unsafe { std::slice::from_raw_parts(buffer_data as *mut u8, self.capacity()) } as _; + Ok(slice) + } else { + Err(Error::NullPointer) + } + } + + pub fn as_mut_slice(&self) -> Result<&mut [u8]> { + let buffer_data = unsafe { vdo_buffer_get_data(self.buffer.raw) }; + if !buffer_data.is_null() { + let slice = + unsafe { std::slice::from_raw_parts_mut(buffer_data as *mut u8, self.capacity()) } + as _; + Ok(slice) + } else { + Err(Error::NullPointer) + } + } + + pub fn frame(&self) -> Result { + let frame = unsafe { vdo_buffer_get_frame(self.buffer.raw) }; + Ok(Frame { + raw: frame, + phantom: PhantomData, + }) + } +} + +impl<'a> Drop for StreamBuffer<'a> { + fn drop(&mut self) { + let (_success, _maybe_error) = unsafe { + try_func!( + vdo_stream_buffer_unref, + self.stream.raw.0, + &mut self.buffer.raw + ) + }; + } +} + +// unsafe impl Send for Buffer {} + +unsafe impl Send for StreamWrapper {} + +struct StreamWrapper(*mut VdoStream); +pub struct Stream { + raw: StreamWrapper, + buffers: Vec<*mut VdoBuffer>, +} + +pub struct StreamIterator<'a> { + stream: &'a Stream, +} + +impl<'a> Iterator for StreamIterator<'a> { + type Item = StreamBuffer<'a>; + fn next(&mut self) -> Option { + let (buffer_ptr, maybe_error) = + unsafe { try_func!(vdo_stream_get_buffer, self.stream.raw.0) }; + if !buffer_ptr.is_null() { + debug_assert!( + maybe_error.is_none(), + "vdo_stream_get_buffer returned an stream pointer AND returned an error!" + ); + Some(StreamBuffer { + buffer: Buffer { raw: buffer_ptr }, + stream: self.stream, + }) + } else { + None + } + } +} + +pub struct RunningStream<'a> { + stream: &'a mut Stream, +} + +impl<'a> RunningStream<'a> { + pub fn iter(&mut self) -> StreamIterator { + StreamIterator { + stream: self.stream, + } + } + pub fn stop(&mut self) -> Result<()> { + unsafe { vdo_stream_stop(self.stream.raw.0) }; + Ok(()) + } +} + +impl<'a> IntoIterator for &'a RunningStream<'a> { + type Item = StreamBuffer<'a>; + type IntoIter = StreamIterator<'a>; + + fn into_iter(self) -> Self::IntoIter { + StreamIterator { + stream: self.stream, + } + } +} + +impl Stream { + pub fn builder() -> StreamBuilder { + StreamBuilder::new() + } + + pub fn new() -> Result { + StreamBuilder::new().build() + } + + pub fn info(&self) -> Result { + let (map_raw, maybe_error) = unsafe { try_func!(vdo_stream_get_info, self.raw.0) }; + if !map_raw.is_null() { + debug_assert!( + maybe_error.is_none(), + "vdo_stream_get_info returned a pointer AND returned an error!" + ); + Ok(Map { raw: map_raw }) + } else { + Err(maybe_error.unwrap_or(Error::MissingVDOError)) + } + } + + pub fn settings(&self) -> Result { + let (map_raw, maybe_error) = unsafe { try_func!(vdo_stream_get_settings, self.raw.0) }; + if !map_raw.is_null() { + debug_assert!( + maybe_error.is_none(), + "vdo_stream_get_settings returned a pointer AND returned an error!" + ); + Ok(Map { raw: map_raw }) + } else { + Err(maybe_error.unwrap_or(Error::MissingVDOError)) + } + } + + /// Request the Larod service to start fetching frames and passing back buffers. + pub fn start(&mut self) -> Result { + let (success_start, maybe_error) = unsafe { try_func!(vdo_stream_start, self.raw.0) }; + if success_start == GTRUE { + debug_assert!( + maybe_error.is_none(), + "vdo_stream_new returned an stream pointer AND returned an error!" + ); + Ok(RunningStream { stream: self }) + } else { + Err(maybe_error.unwrap_or(Error::MissingVDOError)) + } + } + + // Do we want to spawn a fetcher thread? + // pub fn start_with_channel(&mut self) -> Result<()> { + // let Ok(raw_stream_ptr) = self.raw.lock() else { + // return Err(Error::PoisonedStream); + // }; + // for buffer in self.buffers.iter() { + // let (success_enqueue, maybe_error) = + // unsafe { try_func!(vdo_stream_buffer_enqueue, raw_stream_ptr.0, buffer.raw) }; + // if success_enqueue == GTRUE { + // debug!("enqueued buffer to stream"); + // debug_assert!( + // maybe_error.is_none(), + // "vdo_stream_buffer_enqueue indicated success AND returned an error!" + // ); + // } else { + // return Err(maybe_error.unwrap_or(Error::MissingVDOError)); + // } + // } + // let (success_start, maybe_error) = unsafe { try_func!(vdo_stream_start, raw_stream_ptr.0) }; + // drop(raw_stream_ptr); + // if success_start == GTRUE { + // debug_assert!( + // maybe_error.is_none(), + // "vdo_stream_new returned an stream pointer AND returned an error!" + // ); + // } else { + // return Err(maybe_error.unwrap_or(Error::MissingVDOError)); + // } + // let (sender, receiver) = mpsc::channel(); + // let stream_c = self.raw.clone(); + // self.rx_channel = Some(receiver); + // self.fetcher_thread = Some(thread::spawn(move || { + // debug!("starting frame fetcher thread"); + // let Ok(raw_stream_ptr) = stream_c.lock() else { + // return Err(StreamError::PoisonedStream); + // }; + // let (buffer_ptr, maybe_error) = + // unsafe { try_func!(vdo_stream_get_buffer, raw_stream_ptr.0) }; + // if !buffer_ptr.is_null() { + // debug_assert!( + // maybe_error.is_none(), + // "vdo_stream_get_buffer returned an stream pointer AND returned an error!" + // ); + // debug!("fetched buffer from vdo stream"); + // sender.send(Buffer { raw: buffer_ptr }); + // } else { + // error!("error while fetching buffer: {}", maybe_error.unwrap()); + // } + // Ok(()) + // })); + // Ok(()) + // } +} + +impl Drop for Stream { + fn drop(&mut self) { + unsafe { + vdo_stream_stop(self.raw.0); + } + for mut buffer in mem::take(&mut self.buffers).into_iter() { + let (_success, _maybe_error) = + unsafe { try_func!(vdo_stream_buffer_unref, self.raw.0, &mut buffer) }; + } + } +} + +#[cfg(all(test, target_arch = "aarch64", feature = "device-tests"))] +mod tests { + use super::*; + use anyhow::Context; + + #[test] + fn stream_starts_without_explicit_buffers() -> anyhow::Result<()> { + env_logger::builder().is_test(true).try_init(); + let mut stream = Stream::builder() + .channel(0) + .format(VdoFormat::VDO_FORMAT_PLANAR_RGB) + .resolution(1920, 1080) + .build() + .context("Unable to create stream")?; + let mut r = stream.start().context("Unable to start stream")?; + r.stop()?; + Ok(()) + } + + #[test] + fn stream_starts_with_explicit_buffers() -> anyhow::Result<()> { + env_logger::builder().is_test(true).try_init(); + let mut stream = Stream::builder() + .channel(0) + .format(VdoFormat::VDO_FORMAT_PLANAR_RGB) + .resolution(1920, 1080) + .buffers(5) + .build() + .context("Unable to create stream")?; + let mut r = stream.start().context("Unable to start stream")?; + for _ in 0..10 { + let buff = r.iter().next().context("failed to fetch frame")?; + let size = buff + .frame() + .context("error fetching frame for buffer")? + .size(); + info!("frame size: {}", size); + assert!(size > 0); + } + r.stop()?; + Ok(()) + } + + #[test] + fn stream_starts_with_rgb() -> anyhow::Result<()> { + env_logger::builder().is_test(true).try_init(); + let mut stream = Stream::builder() + .channel(0) + .format(VdoFormat::VDO_FORMAT_PLANAR_RGB) + .resolution(1920, 1080) + .build() + .context("Unable to create stream")?; + let mut r = stream.start().context("starting stream returned error")?; + for _ in 0..10 { + let buff = r.iter().next().context("failed to fetch frame")?; + let size = buff + .frame() + .context("error fetching frame for buffer")? + .size(); + info!("frame size: {}", size); + assert!(size > 0); + } + r.stop().context("Unable to stop stream")?; + Ok(()) + } + + #[test] + fn stream_starts_with_jpeg() -> anyhow::Result<()> { + env_logger::builder().is_test(true).try_init(); + let mut stream = Stream::builder() + .channel(0) + .format(VdoFormat::VDO_FORMAT_JPEG) + .resolution(1920, 1080) + .build() + .context("Unable to create stream")?; + let mut r = stream.start().context("starting stream returned error")?; + for _ in 0..10 { + let buff = r.iter().next().context("failed to fetch frame")?; + let size = buff + .frame() + .context("error fetching frame for buffer")? + .size(); + info!("frame size: {}", size); + assert!(size > 0); + } + r.stop().context("Unable to stop stream")?; + Ok(()) + } + + #[test] + fn stream_starts_with_yuv() -> anyhow::Result<()> { + env_logger::builder().is_test(true).try_init(); + let mut stream = Stream::builder() + .channel(0) + .format(VdoFormat::VDO_FORMAT_YUV) + .resolution(1920, 1080) + .build() + .context("Unable to create stream")?; + let mut r = stream.start().context("starting stream returned error")?; + for _ in 0..10 { + let buff = r.iter().next().context("failed to fetch frame")?; + let size = buff + .frame() + .context("error fetching frame for buffer")? + .size(); + info!("frame size: {}", size); + assert!(size > 0); + } + r.stop().context("Unable to stop stream")?; + Ok(()) + } + + #[test] + fn stream_starts_with_h264() -> anyhow::Result<()> { + env_logger::builder().is_test(true).try_init(); + let mut stream = Stream::builder() + .channel(0) + .format(VdoFormat::VDO_FORMAT_H264) + .resolution(1920, 1080) + .build() + .context("Unable to create stream")?; + let mut r = stream.start().context("starting stream returned error")?; + for _ in 0..10 { + let buff = r.iter().next().context("failed to fetch frame")?; + let size = buff + .frame() + .context("error fetching frame for buffer")? + .size(); + info!("frame size: {}", size); + assert!(size > 0); + } + r.stop().context("Unable to stop stream")?; + Ok(()) + } + + #[test] + fn stream_starts_with_h265() -> anyhow::Result<()> { + env_logger::builder().is_test(true).try_init(); + let mut stream = Stream::builder() + .channel(0) + .format(VdoFormat::VDO_FORMAT_H265) + .resolution(1920, 1080) + .build() + .context("Unable to create stream")?; + let mut r = stream.start().context("starting stream returned error")?; + for _ in 0..10 { + let buff = r.iter().next().context("failed to fetch frame")?; + let size = buff + .frame() + .context("error fetching frame for buffer")? + .size(); + info!("frame size: {}", size); + assert!(size > 0); + } + r.stop().context("Unable to stop stream")?; + Ok(()) + } + + #[test] + fn stream_fetches_frames_infinitely() -> anyhow::Result<()> { + env_logger::builder().is_test(true).try_init(); + let mut stream = Stream::builder() + .channel(0) + .format(VdoFormat::VDO_FORMAT_PLANAR_RGB) + .resolution(1920, 1080) + .buffers(5) + .build() + .context("Unable to create stream")?; + let mut r = stream.start().context("starting stream returned error")?; + + for _ in 0..10 { + let buff = r.iter().next().context("failed to fetch frame")?; + let size = buff + .frame() + .context("error fetching frame for buffer")? + .size(); + info!("frame size: {}", size); + assert!(size > 0); + } + + r.stop().context("Unable to stop stream")?; + Ok(()) + } +}