From 062403bdacf0658b719731bc38b570dcf500366e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 25 Apr 2018 11:08:44 +0300 Subject: [PATCH] appsrc need-data and all appsink callbacks can only be called from a single thread at a time As such, make them FnMut and remove the Sync requirement from them. We can only do this for the callbacks and not the signals, because the signals can in theory be emitted from anybody (outside the object!) at any time. --- gstreamer-app/src/app_sink.rs | 25 +++++++++++++------------ gstreamer-app/src/app_src.rs | 11 ++++++----- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/gstreamer-app/src/app_sink.rs b/gstreamer-app/src/app_sink.rs index 7c08efad9..8e82690ad 100644 --- a/gstreamer-app/src/app_sink.rs +++ b/gstreamer-app/src/app_sink.rs @@ -14,11 +14,12 @@ use glib_ffi::gpointer; use gst; use gst_ffi; use std::ptr; +use std::cell::RefCell; pub struct AppSinkCallbacks { - eos: Option>, - new_preroll: Option gst::FlowReturn + Send + Sync + 'static>>, - new_sample: Option gst::FlowReturn + Send + Sync + 'static>>, + eos: Option>>, + new_preroll: Option gst::FlowReturn + Send + 'static>>>, + new_sample: Option gst::FlowReturn + Send + 'static>>>, callbacks: ffi::GstAppSinkCallbacks, } @@ -37,15 +38,15 @@ impl AppSinkCallbacks { } pub struct AppSinkCallbacksBuilder { - eos: Option>, - new_preroll: Option gst::FlowReturn + Send + Sync + 'static>>, - new_sample: Option gst::FlowReturn + Send + Sync + 'static>>, + eos: Option>>, + new_preroll: Option gst::FlowReturn + Send + 'static>>>, + new_sample: Option gst::FlowReturn + Send + 'static>>>, } impl AppSinkCallbacksBuilder { pub fn eos(self, eos: F) -> Self { Self { - eos: Some(Box::new(eos)), + eos: Some(RefCell::new(Box::new(eos))), ..self } } @@ -55,7 +56,7 @@ impl AppSinkCallbacksBuilder { new_preroll: F, ) -> Self { Self { - new_preroll: Some(Box::new(new_preroll)), + new_preroll: Some(RefCell::new(Box::new(new_preroll))), ..self } } @@ -65,7 +66,7 @@ impl AppSinkCallbacksBuilder { new_sample: F, ) -> Self { Self { - new_sample: Some(Box::new(new_sample)), + new_sample: Some(RefCell::new(Box::new(new_sample))), ..self } } @@ -109,7 +110,7 @@ unsafe extern "C" fn trampoline_eos(appsink: *mut ffi::GstAppSink, callbacks: gp callbacks .eos .as_ref() - .map(|f| f(&from_glib_borrow(appsink))); + .map(|f| (&mut *f.borrow_mut())(&from_glib_borrow(appsink))); } unsafe extern "C" fn trampoline_new_preroll( @@ -122,7 +123,7 @@ unsafe extern "C" fn trampoline_new_preroll( callbacks .new_preroll .as_ref() - .map(|f| f(&from_glib_borrow(appsink))) + .map(|f| (&mut *f.borrow_mut())(&from_glib_borrow(appsink))) .unwrap_or(gst::FlowReturn::Error) .to_glib() } @@ -137,7 +138,7 @@ unsafe extern "C" fn trampoline_new_sample( callbacks .new_sample .as_ref() - .map(|f| f(&from_glib_borrow(appsink))) + .map(|f| (&mut *f.borrow_mut())(&from_glib_borrow(appsink))) .unwrap_or(gst::FlowReturn::Error) .to_glib() } diff --git a/gstreamer-app/src/app_src.rs b/gstreamer-app/src/app_src.rs index b0f7fefd1..9a808172b 100644 --- a/gstreamer-app/src/app_src.rs +++ b/gstreamer-app/src/app_src.rs @@ -14,9 +14,10 @@ use glib_ffi::{gboolean, gpointer}; use gst; use std::mem; use std::ptr; +use std::cell::RefCell; pub struct AppSrcCallbacks { - need_data: Option>, + need_data: Option>>, enough_data: Option>, seek_data: Option bool + Send + Sync + 'static>>, callbacks: ffi::GstAppSrcCallbacks, @@ -38,15 +39,15 @@ impl AppSrcCallbacks { } pub struct AppSrcCallbacksBuilder { - need_data: Option>, + need_data: Option>>, enough_data: Option>, seek_data: Option bool + Send + Sync + 'static>>, } impl AppSrcCallbacksBuilder { - pub fn need_data(self, need_data: F) -> Self { + pub fn need_data(self, need_data: F) -> Self { Self { - need_data: Some(Box::new(need_data)), + need_data: Some(RefCell::new(Box::new(need_data))), ..self } } @@ -115,7 +116,7 @@ unsafe extern "C" fn trampoline_need_data( callbacks .need_data .as_ref() - .map(|f| f(&from_glib_borrow(appsrc), length)); + .map(|f| (&mut *f.borrow_mut())(&from_glib_borrow(appsrc), length)); } unsafe extern "C" fn trampoline_enough_data(appsrc: *mut ffi::GstAppSrc, callbacks: gpointer) {