use std::{
ffi::{CStr, CString},
io,
marker::PhantomData,
ptr::NonNull,
};
use libcamera_sys::*;
use crate::{camera::Camera, logging::LoggingLevel, utils::handle_result};
pub struct CameraManager {
ptr: NonNull<libcamera_camera_manager_t>,
}
impl CameraManager {
pub fn new() -> io::Result<Self> {
let ptr = NonNull::new(unsafe { libcamera_camera_manager_create() }).unwrap();
let ret = unsafe { libcamera_camera_manager_start(ptr.as_ptr()) };
handle_result(ret)?;
Ok(CameraManager { ptr })
}
pub fn version(&self) -> &str {
unsafe { CStr::from_ptr(libcamera_camera_manager_version(self.ptr.as_ptr())) }
.to_str()
.unwrap()
}
pub fn cameras(&self) -> CameraList<'_> {
unsafe { CameraList::from_ptr(NonNull::new(libcamera_camera_manager_cameras(self.ptr.as_ptr())).unwrap()) }
}
pub fn log_set_level(&self, category: &str, level: LoggingLevel) {
let category = CString::new(category).expect("category contains null byte");
let level: &CStr = level.into();
unsafe {
libcamera_log_set_level(category.as_ptr(), level.as_ptr());
}
}
}
impl Drop for CameraManager {
fn drop(&mut self) {
unsafe {
libcamera_camera_manager_stop(self.ptr.as_ptr());
libcamera_camera_manager_destroy(self.ptr.as_ptr());
}
}
}
pub struct CameraList<'d> {
ptr: NonNull<libcamera_camera_list_t>,
_phantom: PhantomData<&'d ()>,
}
impl<'d> CameraList<'d> {
pub(crate) unsafe fn from_ptr(ptr: NonNull<libcamera_camera_list_t>) -> Self {
Self {
ptr,
_phantom: Default::default(),
}
}
pub fn len(&self) -> usize {
unsafe { libcamera_camera_list_size(self.ptr.as_ptr()) }
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, index: usize) -> Option<Camera<'_>> {
let cam_ptr = unsafe { libcamera_camera_list_get(self.ptr.as_ptr(), index as _) };
NonNull::new(cam_ptr).map(|p| unsafe { Camera::from_ptr(p) })
}
}
impl<'d> Drop for CameraList<'d> {
fn drop(&mut self) {
unsafe {
libcamera_camera_list_destroy(self.ptr.as_ptr());
}
}
}