// Copyright (C) 2017 Sebastian Dröge // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use AppSink; use ffi; use gst_ffi; use glib::translate::*; use gst; use std::mem::transmute; use glib::source::CallbackGuard; use glib_ffi::gpointer; use std::ptr; pub struct AppSinkCallbacks { eos: Box, new_preroll: Box gst::FlowReturn + Send + Sync + 'static>, new_sample: Box gst::FlowReturn + Send + Sync + 'static>, callbacks: ffi::GstAppSinkCallbacks, } impl AppSinkCallbacks { pub fn new(eos: F, new_preroll: G, new_sample: H) -> Self where F: Fn(&AppSink) + Send + Sync + 'static, G: Fn(&AppSink) -> gst::FlowReturn + Send + Sync + 'static, H: Fn(&AppSink) -> gst::FlowReturn + Send + Sync + 'static, { AppSinkCallbacks { eos: Box::new(eos), new_preroll: Box::new(new_preroll), new_sample: Box::new(new_sample), callbacks: ffi::GstAppSinkCallbacks { eos: Some(trampoline_eos), new_preroll: Some(trampoline_new_preroll), new_sample: Some(trampoline_new_sample), _gst_reserved: [ ptr::null_mut(), ptr::null_mut(), ptr::null_mut(), ptr::null_mut(), ], }, } } } unsafe extern "C" fn trampoline_eos(appsink: *mut ffi::GstAppSink, callbacks: gpointer) { let _guard = CallbackGuard::new(); let callbacks: &AppSinkCallbacks = transmute(callbacks); (callbacks.eos)(&from_glib_none(appsink)); } unsafe extern "C" fn trampoline_new_preroll( appsink: *mut ffi::GstAppSink, callbacks: gpointer, ) -> gst_ffi::GstFlowReturn { let _guard = CallbackGuard::new(); let callbacks: &AppSinkCallbacks = transmute(callbacks); (callbacks.new_preroll)(&from_glib_none(appsink)).to_glib() } unsafe extern "C" fn trampoline_new_sample( appsink: *mut ffi::GstAppSink, callbacks: gpointer, ) -> gst_ffi::GstFlowReturn { let _guard = CallbackGuard::new(); let callbacks: &AppSinkCallbacks = transmute(callbacks); (callbacks.new_sample)(&from_glib_none(appsink)).to_glib() } unsafe extern "C" fn destroy_callbacks(ptr: gpointer) { let _guard = CallbackGuard::new(); Box::>::from_raw(ptr as *mut _); } impl AppSink { pub fn set_callbacks(&self, callbacks: AppSinkCallbacks) { unsafe { ffi::gst_app_sink_set_callbacks( self.to_glib_none().0, mut_override(&callbacks.callbacks), Box::into_raw(Box::new(callbacks)) as *mut _, Some(destroy_callbacks), ); } } }