use std::ptr::NonNull;
use crate::{
AVBufferRef, AVHWDeviceType, AvError, av_buffer_unref as ffi_av_buffer_unref,
av_hwdevice_ctx_create as ffi_av_hwdevice_ctx_create,
};
#[derive(Debug)]
pub struct HwDeviceContext {
ptr: NonNull<AVBufferRef>,
}
impl HwDeviceContext {
pub fn new(device_type: AVHWDeviceType) -> Result<Self, AvError> {
let mut ptr: *mut AVBufferRef = std::ptr::null_mut();
let ret = unsafe {
ffi_av_hwdevice_ctx_create(
std::ptr::addr_of_mut!(ptr),
device_type,
std::ptr::null(),
std::ptr::null_mut(),
0,
)
};
if ret < 0 {
return Err(AvError::new(ret));
}
NonNull::new(ptr)
.ok_or_else(|| AvError::new(crate::error_codes::ENOMEM))
.map(|ptr| Self { ptr })
}
pub(crate) fn as_raw(&self) -> *mut AVBufferRef {
self.ptr.as_ptr()
}
}
impl Drop for HwDeviceContext {
fn drop(&mut self) {
unsafe {
let mut raw = self.ptr.as_ptr();
ffi_av_buffer_unref(std::ptr::addr_of_mut!(raw));
}
}
}
unsafe impl Send for HwDeviceContext {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_should_return_a_result_without_panicking() {
match HwDeviceContext::new(crate::AVHWDeviceType_AV_HWDEVICE_TYPE_CUDA) {
Ok(ctx) => {
assert!(!ctx.as_raw().is_null());
}
Err(e) => {
assert!(e.code() < 0);
}
}
}
}