use std::os::raw::c_uint; use std::{mem::MaybeUninit, ffi::CStr}; use nvfbc_sys::_NVFBCSTATUS_NVFBC_SUCCESS as SUCCESS; use nvfbc_sys::NVFBC_SESSION_HANDLE; use crate::CaptureType; use crate::Error; use crate::Status; pub type Handle = NVFBC_SESSION_HANDLE; pub(crate) fn check_ret(handle: Handle, ret: nvfbc_sys::_NVFBCSTATUS) -> Result<(), Error> { if ret != SUCCESS { return Err(Error::new(ret, get_last_error(handle))); } Ok(()) } pub(crate) fn create_handle() -> Result { const MAGIC_PRIVATE_DATA: [u32; 4] = [0xAEF57AC5, 0x401D1A39, 0x1B856BBE, 0x9ED0CEBA]; let mut params: nvfbc_sys::_NVFBC_CREATE_HANDLE_PARAMS = unsafe { MaybeUninit::zeroed().assume_init() }; params.dwVersion = nvfbc_sys::NVFBC_CREATE_HANDLE_PARAMS_VER; params.privateData = MAGIC_PRIVATE_DATA.as_ptr() as _; params.privateDataSize = std::mem::size_of_val(&MAGIC_PRIVATE_DATA) as u32; let mut handle = 0; let ret = unsafe { nvfbc_sys::NvFBCCreateHandle( &mut handle, &mut params )}; if ret != SUCCESS { return Err(Error::new(ret, None)); } Ok(handle) } pub(crate) fn destroy_handle(handle: Handle) -> Result<(), Error> { let mut params: nvfbc_sys::_NVFBC_DESTROY_HANDLE_PARAMS = unsafe { MaybeUninit::zeroed().assume_init() }; params.dwVersion = nvfbc_sys::NVFBC_DESTROY_HANDLE_PARAMS_VER; check_ret(handle, unsafe { nvfbc_sys::NvFBCDestroyHandle(handle, &mut params) }) } pub(crate) fn get_last_error(handle: Handle) -> Option { let error = unsafe { nvfbc_sys::NvFBCGetLastErrorStr(handle) }; let error = unsafe { CStr::from_ptr(error) }; error.to_str().ok().map(|e| e.to_string()) } pub(crate) fn status(handle: Handle) -> Result { let mut params: nvfbc_sys::_NVFBC_GET_STATUS_PARAMS = unsafe { MaybeUninit::zeroed().assume_init() }; params.dwVersion = nvfbc_sys::NVFBC_GET_STATUS_PARAMS_VER; check_ret(handle, unsafe { nvfbc_sys::NvFBCGetStatus(handle, &mut params) })?; Ok(params.into()) } pub(crate) fn create_capture_session(handle: Handle, capture_type: CaptureType, sampling_rate: std::time::Duration) -> Result<(), Error> { let mut params: nvfbc_sys::_NVFBC_CREATE_CAPTURE_SESSION_PARAMS = unsafe { MaybeUninit::zeroed().assume_init() }; params.dwVersion = nvfbc_sys::NVFBC_CREATE_CAPTURE_SESSION_PARAMS_VER; params.eCaptureType = capture_type as c_uint; params.bWithCursor = nvfbc_sys::_NVFBC_BOOL_NVFBC_TRUE; params.frameSize = nvfbc_sys::NVFBC_SIZE { w: 0, h: 0 }; params.eTrackingType = nvfbc_sys::NVFBC_TRACKING_TYPE_NVFBC_TRACKING_DEFAULT; params.dwSamplingRateMs = sampling_rate.as_millis() as u32; check_ret(handle, unsafe { nvfbc_sys::NvFBCCreateCaptureSession(handle, &mut params) }) } pub(crate) fn destroy_capture_session(handle: Handle) -> Result<(), Error> { let mut params: nvfbc_sys::_NVFBC_DESTROY_CAPTURE_SESSION_PARAMS = unsafe { MaybeUninit::zeroed().assume_init() }; params.dwVersion = nvfbc_sys::NVFBC_DESTROY_CAPTURE_SESSION_PARAMS_VER; check_ret(handle, unsafe { nvfbc_sys::NvFBCDestroyCaptureSession(handle, &mut params) }) }