From e6992345cca46e21c4501f48cc06401c9481e757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 10 Feb 2019 11:47:28 +0200 Subject: [PATCH] Add gst_video::convert_frame_async_local() without Send bound on the closure --- gstreamer-video/src/functions.rs | 51 +++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/gstreamer-video/src/functions.rs b/gstreamer-video/src/functions.rs index 3865d2a09..675fdcb15 100644 --- a/gstreamer-video/src/functions.rs +++ b/gstreamer-video/src/functions.rs @@ -46,16 +46,41 @@ pub fn convert_sample_async( func: F, ) where F: FnOnce(Result) + Send + 'static, +{ + unsafe { convert_sample_async_unsafe(sample, caps, timeout, func) } +} + +pub fn convert_sample_async_local( + sample: &gst::Sample, + caps: &gst::Caps, + timeout: gst::ClockTime, + func: F, +) where + F: FnOnce(Result) + Send + 'static, +{ + unsafe { + assert!(glib::MainContext::ref_thread_default().is_owner()); + convert_sample_async_unsafe(sample, caps, timeout, func) + } +} + +unsafe fn convert_sample_async_unsafe( + sample: &gst::Sample, + caps: &gst::Caps, + timeout: gst::ClockTime, + func: F, +) where + F: FnOnce(Result) + 'static, { unsafe extern "C" fn convert_sample_async_trampoline( sample: *mut gst_ffi::GstSample, error: *mut glib_ffi::GError, user_data: glib_ffi::gpointer, ) where - F: FnOnce(Result) + Send + 'static, + F: FnOnce(Result) + 'static, { #[cfg_attr(feature = "cargo-clippy", allow(transmute_ptr_to_ref))] - let callback: &mut Option = mem::transmute(user_data); + let callback: &mut Option = &mut *(user_data as *mut Option); let callback = callback.take().unwrap(); if error.is_null() { @@ -66,23 +91,21 @@ pub fn convert_sample_async( } unsafe extern "C" fn convert_sample_async_free(user_data: glib_ffi::gpointer) where - F: FnOnce(Result) + Send + 'static, + F: FnOnce(Result) + 'static, { let _: Box> = Box::from_raw(user_data as *mut _); } - unsafe { - let user_data: Box> = Box::new(Some(func)); + let user_data: Box> = Box::new(Some(func)); - ffi::gst_video_convert_sample_async( - sample.to_glib_none().0, - caps.to_glib_none().0, - timeout.to_glib(), - Some(convert_sample_async_trampoline::), - Box::into_raw(user_data) as glib_ffi::gpointer, - Some(convert_sample_async_free::), - ); - } + ffi::gst_video_convert_sample_async( + sample.to_glib_none().0, + caps.to_glib_none().0, + timeout.to_glib(), + Some(convert_sample_async_trampoline::), + Box::into_raw(user_data) as glib_ffi::gpointer, + Some(mem::transmute(convert_sample_async_free:: as usize)), + ); } #[cfg(test)]