use orbbec_sys::{ob_stream_profile, ob_stream_profile_list};
use crate::error::{check_error, Error};
use crate::pipeline::StreamType;
const ANY_WIDTH: u32 = 0;
const ANY_HEIGHT: u32 = 0;
const ANY_FPS: u32 = 0;
const ANY_FORMAT: i32 = -1;
pub struct StreamProfile {
raw: *mut ob_stream_profile,
}
unsafe impl Send for StreamProfile {}
impl StreamProfile {
pub(crate) unsafe fn from_raw(raw: *mut ob_stream_profile) -> Self {
Self { raw }
}
pub fn as_raw(&self) -> *const ob_stream_profile {
self.raw
}
pub fn stream_type(&self) -> StreamType {
let t = unsafe { check_error(|e| orbbec_sys::ob_stream_profile_get_type(self.raw, e)) }
.unwrap_or(0);
StreamType::from_raw(t)
}
pub fn format(&self) -> i32 {
unsafe { check_error(|e| orbbec_sys::ob_stream_profile_get_format(self.raw, e)) }
.unwrap_or(0)
}
pub fn width(&self) -> u32 {
unsafe { check_error(|e| orbbec_sys::ob_video_stream_profile_get_width(self.raw, e)) }
.unwrap_or(0)
}
pub fn height(&self) -> u32 {
unsafe { check_error(|e| orbbec_sys::ob_video_stream_profile_get_height(self.raw, e)) }
.unwrap_or(0)
}
pub fn fps(&self) -> u32 {
unsafe { check_error(|e| orbbec_sys::ob_video_stream_profile_get_fps(self.raw, e)) }
.unwrap_or(0)
}
}
impl std::fmt::Debug for StreamProfile {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("StreamProfile")
.field("stream_type", &self.stream_type())
.field("width", &self.width())
.field("height", &self.height())
.field("fps", &self.fps())
.field("format", &self.format())
.finish()
}
}
impl Drop for StreamProfile {
fn drop(&mut self) {
let _ = unsafe { check_error(|e| orbbec_sys::ob_delete_stream_profile(self.raw, e)) };
}
}
pub struct StreamProfileList {
raw: *mut ob_stream_profile_list,
}
unsafe impl Send for StreamProfileList {}
impl StreamProfileList {
pub(crate) unsafe fn from_raw(raw: *mut ob_stream_profile_list) -> Self {
Self { raw }
}
pub fn count(&self) -> u32 {
unsafe { check_error(|e| orbbec_sys::ob_stream_profile_list_get_count(self.raw, e)) }
.unwrap_or(0)
}
pub fn profile(&self, index: u32) -> Result<StreamProfile, Error> {
let raw = unsafe {
check_error(|e| {
orbbec_sys::ob_stream_profile_list_get_profile(self.raw, index as i32, e)
})?
};
Ok(unsafe { StreamProfile::from_raw(raw) })
}
pub fn match_video(
&self,
width: Option<u32>,
height: Option<u32>,
format: Option<i32>,
fps: Option<u32>,
) -> Result<Option<StreamProfile>, Error> {
let raw = unsafe {
check_error(|e| {
orbbec_sys::ob_stream_profile_list_get_video_stream_profile(
self.raw,
width.unwrap_or(ANY_WIDTH) as i32,
height.unwrap_or(ANY_HEIGHT) as i32,
format.unwrap_or(ANY_FORMAT),
fps.unwrap_or(ANY_FPS) as i32,
e,
)
})?
};
if raw.is_null() {
Ok(None)
} else {
Ok(Some(unsafe { StreamProfile::from_raw(raw) }))
}
}
pub fn collect(&self) -> Vec<StreamProfile> {
(0..self.count())
.filter_map(|i| self.profile(i).ok())
.collect()
}
}
impl Drop for StreamProfileList {
fn drop(&mut self) {
let _ = unsafe { check_error(|e| orbbec_sys::ob_delete_stream_profile_list(self.raw, e)) };
}
}