Skip to content

Commit

Permalink
Fix ID issue refcount (#31)
Browse files Browse the repository at this point in the history
* Fix ID issue refcount

* Fix ID issue refcount
  • Loading branch information
1313 authored Jan 16, 2024
1 parent 7c1774d commit dbcc7f0
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 21 deletions.
42 changes: 27 additions & 15 deletions screencapturekit-sys/src/cm_sample_buffer_ref.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
use objc::{runtime::Object, *};
use objc_id::{Id, ShareId};
use std::alloc;
use std::ffi::c_void;
use std::ptr::null_mut;
use objc::{runtime::Object, *};
use objc_id::Id;

use crate::cm_format_description_ref::CMFormatDescriptionRef;
use crate::{
cv_image_buffer_ref::CVImageBufferRef, macros::declare_ref_type, os_types::base::CMTime,
sc_stream_frame_info::SCStreamFrameInfo,
};
use crate::cm_format_description_ref::CMFormatDescriptionRef;

use crate::audio_buffer::{AudioBufferList, CopiedAudioBuffer, kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment};
use crate::audio_buffer::{
kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, AudioBufferList, CopiedAudioBuffer,
};
use crate::cm_block_buffer_ref::CMBlockBufferRef;

declare_ref_type!(CMSampleBufferRef);
Expand All @@ -32,14 +34,14 @@ impl CMSampleBufferRef {
unsafe {
let ptr = CMSampleBufferGetFormatDescription(self);
if ptr.is_null() {
return None
return None;
}
Some(Id::from_ptr(ptr))
}
}

pub fn get_av_audio_buffer_list(&self) -> Vec<CopiedAudioBuffer> {
unsafe {
unsafe {
let mut buffer_size = 0;
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(
self,
Expand Down Expand Up @@ -81,7 +83,10 @@ impl CMSampleBufferRef {
}
}

fn copy_audio_buffers(&self, audio_buffer_list_ptr: *mut AudioBufferList) -> Vec<CopiedAudioBuffer> {
fn copy_audio_buffers(
&self,
audio_buffer_list_ptr: *mut AudioBufferList,
) -> Vec<CopiedAudioBuffer> {
let audio_buffer_list = unsafe { *audio_buffer_list_ptr };
let number_buffers = audio_buffer_list.number_buffers;
let mut buffers = Vec::new();
Expand All @@ -90,20 +95,24 @@ impl CMSampleBufferRef {
buffers.push(CopiedAudioBuffer {
number_channels: number_buffers,
data: unsafe {
std::slice::from_raw_parts(audio_buffer.data, audio_buffer.data_bytes_size as usize)
}.to_vec(),
std::slice::from_raw_parts(
audio_buffer.data,
audio_buffer.data_bytes_size as usize,
)
}
.to_vec(),
});
}
buffers
}

pub fn get_image_buffer(&self) -> Option<Id<CVImageBufferRef>> {
pub fn get_image_buffer(&self) -> Option<ShareId<CVImageBufferRef>> {
unsafe {
let img_buf_ptr = CMSampleBufferGetImageBuffer(self);
if img_buf_ptr.is_null() {
return None
return None;
}
Some(Id::from_ptr(img_buf_ptr))
Some(Id::from_ptr(img_buf_ptr).share())
}
}
}
Expand All @@ -116,7 +125,9 @@ extern "C" {
pub fn CMSampleBufferGetImageBuffer(sample: *const CMSampleBufferRef) -> *mut CVImageBufferRef;
pub fn CMSampleBufferGetPresentationTimeStamp(sample: *const CMSampleBufferRef) -> CMTime;
pub fn CMSampleBufferGetDataBuffer(sample: *const CMSampleBufferRef) -> *mut CMBlockBufferRef;
pub fn CMSampleBufferGetFormatDescription(sample: *const CMSampleBufferRef) -> *mut CMFormatDescriptionRef;
pub fn CMSampleBufferGetFormatDescription(
sample: *const CMSampleBufferRef,
) -> *mut CMFormatDescriptionRef;

fn CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(
sbuf: *const CMSampleBufferRef,
Expand All @@ -126,7 +137,8 @@ extern "C" {
block_buffer_structure_allocator: *mut c_void,
block_buffer_block_allocator: *mut c_void,
flags: u32,
block_buffer_out: &mut *mut CMBlockBufferRef) -> i32;
block_buffer_out: &mut *mut CMBlockBufferRef,
) -> i32;

fn CFRelease(cf : *mut c_void);
fn CFRelease(cf: *mut c_void);
}
2 changes: 1 addition & 1 deletion screencapturekit-sys/src/cv_image_buffer_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ declare_ref_type!(CVImageBufferRef);

impl CVImageBufferRef {
pub fn as_pixel_buffer(&self) -> ShareId<CVPixelBufferRef> {
unsafe { ShareId::from_retained_ptr(self.as_mut_ptr().cast()) }
unsafe { ShareId::from_ptr(self.as_mut_ptr().cast()) }
}
pub fn get_jpeg_data(&self) -> ShareId<NSData> {
unsafe {
Expand Down
77 changes: 77 additions & 0 deletions screencapturekit/examples/segfault.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use std::{path::PathBuf, thread, time};

use screencapturekit::{
cm_sample_buffer::CMSampleBuffer,
sc_content_filter::{InitParams, SCContentFilter},
sc_error_handler::StreamErrorHandler,
sc_output_handler::{SCStreamOutputType, StreamOutput},
sc_shareable_content::SCShareableContent,
sc_stream::SCStream,
sc_stream_configuration::SCStreamConfiguration,
};
use screencapturekit_sys::os_types::geometry::{CGPoint, CGRect, CGSize};

struct ErrorHandler;
impl StreamErrorHandler for ErrorHandler {
fn on_error(&self) {
println!("Error!");
}
}

pub struct Capturer {}

impl Capturer {
pub fn new() -> Self {
println!("Capturer initialized");
Capturer {}
}
}

impl StreamErrorHandler for Capturer {
fn on_error(&self) {
eprintln!("ERROR!");
}
}

impl StreamOutput for Capturer {
fn did_output_sample_buffer(&self, sample: CMSampleBuffer, of_type: SCStreamOutputType) {
println!("New frame recvd");
}
}
fn main() {
println!("Starting");

let content = SCShareableContent::current();
let displays = content.displays;

let display = displays.first().unwrap_or_else(|| {
panic!("Main display not found");
});
let display = display.to_owned();

let width = display.width;
let height = display.height;

let params = InitParams::Display(display);
let filter = SCContentFilter::new(params);

let stream_config = SCStreamConfiguration {
width,
height,
..Default::default()
};

let mut stream = SCStream::new(filter, stream_config, ErrorHandler);
let capturer = Capturer::new();
stream.add_output(capturer, SCStreamOutputType::Screen);

stream.start_capture();

let ten_millis = time::Duration::from_millis(10000);

thread::sleep(ten_millis);

stream.stop_capture();

println!("Ended");
}
14 changes: 9 additions & 5 deletions screencapturekit/src/cm_sample_buffer.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use screencapturekit_sys::{
cm_sample_buffer_ref::CMSampleBufferRef, cv_image_buffer_ref::CVImageBufferRef,
os_types::rc::Id, sc_stream_frame_info::SCFrameStatus,
cm_sample_buffer_ref::CMSampleBufferRef,
cv_image_buffer_ref::CVImageBufferRef,
os_types::rc::{Id, ShareId},
sc_stream_frame_info::SCFrameStatus,
};

use crate::cv_pixel_buffer::CVPixelBuffer;

#[derive(Debug)]
pub struct CMSampleBuffer {
pub sys_ref: Id<CMSampleBufferRef>,
pub image_buf_ref: Option<Id<CVImageBufferRef>>,
pub image_buf_ref: Option<ShareId<CVImageBufferRef>>,
pub pixel_buffer: Option<CVPixelBuffer>,
pub frame_status: SCFrameStatus,
}
Expand All @@ -17,11 +19,13 @@ impl CMSampleBuffer {
pub fn new(sys_ref: Id<CMSampleBufferRef>) -> Self {
let frame_status = sys_ref.get_frame_info().status();
let image_buf_ref = sys_ref.get_image_buffer();
let pixel_buffer = image_buf_ref.as_ref().map(|i| CVPixelBuffer::new(i.as_pixel_buffer()));
let pixel_buffer = image_buf_ref
.as_ref()
.map(|i| CVPixelBuffer::new(i.clone().as_pixel_buffer()));
Self {
sys_ref,
image_buf_ref,
pixel_buffer,
image_buf_ref,
frame_status,
}
}
Expand Down

0 comments on commit dbcc7f0

Please sign in to comment.