diff --git a/cidre/src/cv/buffer.rs b/cidre/src/cv/buffer.rs index c190145c..87585437 100644 --- a/cidre/src/cv/buffer.rs +++ b/cidre/src/cv/buffer.rs @@ -13,6 +13,12 @@ define_cf_type!( Buf(cf::Type) ); +impl Drop for Buf { + fn drop(&mut self) { + unsafe { CVBufferRelease(self) } + } +} + impl Buf { #[inline] pub fn attach<'a>( @@ -27,7 +33,7 @@ impl Buf { pub fn set_attach(&mut self, key: &cf::String, val: &cf::Type, attachment_mode: AttachMode) { unsafe { CVBufferSetAttachment(self, key, val, attachment_mode) } } - + #[inline] pub fn remove_attach(&mut self, key: &cf::String) { unsafe { CVBufferRemoveAttachment(self, key) } @@ -125,6 +131,7 @@ extern "C-unwind" { value: &cf::Type, attachment_mode: AttachMode, ); + pub fn CVBufferRelease(buffer: &mut Buf); fn CVBufferRemoveAttachment(buffer: &mut Buf, key: &cf::String); fn CVBufferRemoveAllAttachments(buffer: &mut Buf); fn CVBufferSetAttachments( diff --git a/cidre/src/cv/pixel_buffer.rs b/cidre/src/cv/pixel_buffer.rs index 03bed0a0..e5ef200e 100644 --- a/cidre/src/cv/pixel_buffer.rs +++ b/cidre/src/cv/pixel_buffer.rs @@ -1,3 +1,5 @@ +use std::ffi::c_void; + use crate::{arc, cf, cv, define_opts, four_cc_to_str, os}; #[cfg(feature = "io")] @@ -5,6 +7,9 @@ use crate::io; pub type PixelBuf = cv::ImageBuf; +pub type ReleaseCallback = + extern "C" fn(releaseRefCon: *mut c_void, baseAddress: *const *const c_void); + impl PixelBuf { #[inline] pub fn type_id() -> cf::TypeId { @@ -82,6 +87,33 @@ impl PixelBuf { unsafe { r.to_result_unchecked(pixel_buffer_out) } } + pub fn new_with_bytes( + width: usize, + height: usize, + base_address: *mut c_void, + bytes_per_row: usize, + release_callback: ReleaseCallback, + release_ref_con: *mut c_void, + pixel_format_type: cv::PixelFormat, + pixel_buffer_attributes: Option<&cf::Dictionary>, + ) -> Result, cv::Return> { + let mut pixel_buf_out = None; + + let r = Self::create_with_bytes( + width, + height, + pixel_format_type, + base_address, + bytes_per_row, + release_callback, + release_ref_con, + pixel_buffer_attributes, + &mut pixel_buf_out, + None, + ); + unsafe { r.to_result_unchecked(pixel_buf_out) } + } + pub fn create_in( width: usize, height: usize, @@ -102,6 +134,34 @@ impl PixelBuf { } } + pub fn create_with_bytes( + width: usize, + height: usize, + pixel_format_type: cv::PixelFormat, + base_address: *mut c_void, + bytes_per_row: usize, + release_callback: ReleaseCallback, + release_ref_con: *mut c_void, + pixel_buf_attrs: Option<&cf::Dictionary>, + pixel_buf_out: *mut Option>, + allocator: Option<&cf::Allocator>, + ) -> cv::Return { + unsafe { + CVPixelBufferCreateWithBytes( + allocator, + width, + height, + pixel_format_type, + base_address, + bytes_per_row, + release_callback, + release_ref_con, + pixel_buf_attrs, + pixel_buf_out, + ) + } + } + #[doc(alias = "CVPixelBufferLockBaseAddress")] #[inline] pub unsafe fn lock_base_addr(&self, flags: LockFlags) -> cv::Return { @@ -578,6 +638,19 @@ extern "C-unwind" { pixel_buffer_out: *mut Option>, ) -> cv::Return; + fn CVPixelBufferCreateWithBytes( + allocator: Option<&cf::Allocator>, + width: usize, + height: usize, + pixel_format_type: PixelFormat, + base_address: *mut c_void, + bytes_per_row: usize, + releaseCallback: ReleaseCallback, + releaseRefCon: *mut c_void, + pixel_buffer_attributes: Option<&cf::Dictionary>, + pixel_buffer_out: *mut Option>, + ) -> cv::Return; + fn CVPixelBufferGetWidth(pixel_buffer: &PixelBuf) -> usize; fn CVPixelBufferGetHeight(pixel_buffer: &PixelBuf) -> usize; fn CVPixelBufferGetPixelFormatType(pixel_buffer: &PixelBuf) -> PixelFormat;