use super::prelude::FrameCategory;
use crate::kind::Rs2StreamKind;
use realsense_sys as sys;
use std::{
convert::{TryFrom, TryInto},
ptr::NonNull,
};
#[derive(Debug)]
pub struct CompositeFrame {
pub ptr: NonNull<sys::rs2_frame>,
}
impl Drop for CompositeFrame {
fn drop(&mut self) {
unsafe {
sys::rs2_release_frame(self.ptr.as_ptr());
}
}
}
impl From<NonNull<sys::rs2_frame>> for CompositeFrame {
fn from(frame_ptr: NonNull<sys::rs2_frame>) -> Self {
Self { ptr: frame_ptr }
}
}
impl CompositeFrame {
pub fn count(&self) -> usize {
unsafe {
let mut err: *mut sys::rs2_error = std::ptr::null_mut::<sys::rs2_error>();
let count = sys::rs2_embedded_frames_count(self.ptr.as_ptr(), &mut err);
if err.as_ref().is_none() {
count as usize
} else {
sys::rs2_free_error(err);
0
}
}
}
pub fn is_empty(&self) -> bool {
self.count() == 0
}
pub fn frames_of_type<F>(&self) -> Vec<F>
where
F: TryFrom<NonNull<sys::rs2_frame>> + FrameCategory,
{
let mut frames = Vec::new();
for i in 0..self.count() {
unsafe {
let mut err = std::ptr::null_mut::<sys::rs2_error>();
let frame_ptr =
sys::rs2_extract_frame(self.ptr.as_ptr(), i as std::os::raw::c_int, &mut err);
if err.as_ref().is_some() {
sys::rs2_free_error(err);
continue;
}
let nonnull_frame_ptr = NonNull::new(frame_ptr).unwrap();
let is_extendable_to = sys::rs2_is_frame_extendable_to(
nonnull_frame_ptr.as_ptr(),
#[allow(clippy::useless_conversion)]
(F::extension() as i32).try_into().unwrap(),
&mut err,
);
if err.as_ref().is_none() {
if is_extendable_to != 0 {
if let Ok(f) = F::try_from(nonnull_frame_ptr) {
let kind_for_frame = F::kind();
if kind_for_frame == Rs2StreamKind::Any || f.has_correct_kind() {
frames.push(f);
}
continue;
}
}
} else {
sys::rs2_free_error(err);
}
sys::rs2_release_frame(nonnull_frame_ptr.as_ptr());
}
}
frames
}
}