From ffa474e1e975113dabf38ec87c7024b3a009a298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 1 Aug 2017 15:42:15 +0100 Subject: [PATCH] Finish appsrc bindings --- Gir_GstApp.toml | 46 +++++++++++++ gstreamer-app/src/app_src.rs | 105 ++++++++++++++++++++++++++++++ gstreamer-app/src/auto/app_src.rs | 98 ---------------------------- gstreamer-app/src/lib.rs | 1 + 4 files changed, 152 insertions(+), 98 deletions(-) create mode 100644 gstreamer-app/src/app_src.rs diff --git a/Gir_GstApp.toml b/Gir_GstApp.toml index 732b8e4f6..f60101b55 100644 --- a/Gir_GstApp.toml +++ b/Gir_GstApp.toml @@ -37,6 +37,52 @@ name = "GstApp.AppSrc" status = "generate" trait = false + [[object.function]] + name = "push_buffer" + # Pass by value + ignore = true + + [[object.signal]] + name = "end-of-stream" + # Action signal + ignore = true + + [[object.signal]] + name = "push-buffer" + # Action signal + ignore = true + + [[object.signal]] + name = "push-sample" + # Action signal + ignore = true + + [[object.property]] + name = "current-level-bytes" + # Has getter function + ignore = true + + [[object.property]] + name = "duration" + # Has getter function + ignore = true + + [[object.property]] + name = "max-latency" + # Has getter function + ignore = true + + [[object.property]] + name = "min-latency" + # Has getter function + ignore = true + + [[object.property]] + name = "stream-type" + # Has getter function + ignore = true + + [[object]] name = "Gst.Caps" status = "manual" diff --git a/gstreamer-app/src/app_src.rs b/gstreamer-app/src/app_src.rs new file mode 100644 index 000000000..9bb7a6e81 --- /dev/null +++ b/gstreamer-app/src/app_src.rs @@ -0,0 +1,105 @@ +// 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 AppSrc; +use ffi; +use glib::translate::*; +use gst; +use std::mem::transmute; +use glib::source::CallbackGuard; +use glib_ffi::{gboolean, gpointer}; +use std::ptr; + +pub struct AppSrcCallbacks { + need_data: Box, + enough_data: Box, + seek_data: Box bool + Send + Sync + 'static>, + callbacks: ffi::GstAppSrcCallbacks, +} + +impl AppSrcCallbacks { + pub fn new(need_data: F, enough_data: G, seek_data: H) -> Self + where + F: Fn(&AppSrc, u32) + Send + Sync + 'static, + G: Fn(&AppSrc) + Send + Sync + 'static, + H: Fn(&AppSrc, u64) -> bool + Send + Sync + 'static, + { + AppSrcCallbacks { + need_data: Box::new(need_data), + enough_data: Box::new(enough_data), + seek_data: Box::new(seek_data), + callbacks: ffi::GstAppSrcCallbacks { + need_data: Some(trampoline_need_data), + enough_data: Some(trampoline_enough_data), + seek_data: Some(trampoline_seek_data), + _gst_reserved: [ + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + ], + }, + } + } +} + +unsafe extern "C" fn trampoline_need_data( + appsrc: *mut ffi::GstAppSrc, + length: u32, + callbacks: gpointer, +) { + let _guard = CallbackGuard::new(); + let callbacks: &AppSrcCallbacks = transmute(callbacks); + + (callbacks.need_data)(&from_glib_none(appsrc), length); +} + +unsafe extern "C" fn trampoline_enough_data(appsrc: *mut ffi::GstAppSrc, callbacks: gpointer) { + let _guard = CallbackGuard::new(); + let callbacks: &AppSrcCallbacks = transmute(callbacks); + + (callbacks.enough_data)(&from_glib_none(appsrc)); +} + +unsafe extern "C" fn trampoline_seek_data( + appsrc: *mut ffi::GstAppSrc, + offset: u64, + callbacks: gpointer, +) -> gboolean { + let _guard = CallbackGuard::new(); + let callbacks: &AppSrcCallbacks = transmute(callbacks); + + (callbacks.seek_data)(&from_glib_none(appsrc), offset).to_glib() +} + +unsafe extern "C" fn destroy_callbacks(ptr: gpointer) { + let _guard = CallbackGuard::new(); + Box::>::from_raw(ptr as *mut _); +} + +impl AppSrc { + pub fn push_buffer(&self, buffer: gst::Buffer) -> gst::FlowReturn { + unsafe { + from_glib(ffi::gst_app_src_push_buffer( + self.to_glib_none().0, + buffer.into_ptr(), + )) + } + } + + pub fn set_callbacks(&self, callbacks: AppSrcCallbacks) { + unsafe { + ffi::gst_app_src_set_callbacks( + self.to_glib_none().0, + mut_override(&callbacks.callbacks), + Box::into_raw(Box::new(callbacks)) as *mut _, + Some(destroy_callbacks), + ); + } + } +} diff --git a/gstreamer-app/src/auto/app_src.rs b/gstreamer-app/src/auto/app_src.rs index 765148960..1bf24ecfb 100644 --- a/gstreamer-app/src/auto/app_src.rs +++ b/gstreamer-app/src/auto/app_src.rs @@ -86,12 +86,6 @@ impl AppSrc { } } - pub fn push_buffer(&self, buffer: &gst::Buffer) -> gst::FlowReturn { - unsafe { - from_glib(ffi::gst_app_src_push_buffer(self.to_glib_none().0, buffer.to_glib_full())) - } - } - pub fn push_sample(&self, sample: &gst::Sample) -> gst::FlowReturn { unsafe { from_glib(ffi::gst_app_src_push_sample(self.to_glib_none().0, sample.to_glib_none().0)) @@ -159,28 +153,6 @@ impl AppSrc { } } - pub fn get_property_current_level_bytes(&self) -> u64 { - let mut value = Value::from(&0u64); - unsafe { - gobject_ffi::g_object_get_property(self.to_glib_none().0, "current-level-bytes".to_glib_none().0, value.to_glib_none_mut().0); - } - value.get().unwrap() - } - - pub fn get_property_duration(&self) -> u64 { - let mut value = Value::from(&0u64); - unsafe { - gobject_ffi::g_object_get_property(self.to_glib_none().0, "duration".to_glib_none().0, value.to_glib_none_mut().0); - } - value.get().unwrap() - } - - pub fn set_property_duration(&self, duration: u64) { - unsafe { - gobject_ffi::g_object_set_property(self.to_glib_none().0, "duration".to_glib_none().0, Value::from(&duration).to_glib_none().0); - } - } - pub fn get_property_format(&self) -> gst::Format { let mut value = Value::from(&0); unsafe { @@ -210,34 +182,6 @@ impl AppSrc { } } - pub fn get_property_max_latency(&self) -> i64 { - let mut value = Value::from(&0i64); - unsafe { - gobject_ffi::g_object_get_property(self.to_glib_none().0, "max-latency".to_glib_none().0, value.to_glib_none_mut().0); - } - value.get().unwrap() - } - - pub fn set_property_max_latency(&self, max_latency: i64) { - unsafe { - gobject_ffi::g_object_set_property(self.to_glib_none().0, "max-latency".to_glib_none().0, Value::from(&max_latency).to_glib_none().0); - } - } - - pub fn get_property_min_latency(&self) -> i64 { - let mut value = Value::from(&0i64); - unsafe { - gobject_ffi::g_object_get_property(self.to_glib_none().0, "min-latency".to_glib_none().0, value.to_glib_none_mut().0); - } - value.get().unwrap() - } - - pub fn set_property_min_latency(&self, min_latency: i64) { - unsafe { - gobject_ffi::g_object_set_property(self.to_glib_none().0, "min-latency".to_glib_none().0, Value::from(&min_latency).to_glib_none().0); - } - } - pub fn get_property_min_percent(&self) -> u32 { let mut value = Value::from(&0u32); unsafe { @@ -252,14 +196,6 @@ impl AppSrc { } } - pub fn connect_end_of_stream gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { - unsafe { - let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); - connect(self.to_glib_none().0, "end-of-stream", - transmute(end_of_stream_trampoline as usize), Box_::into_raw(f) as *mut _) - } - } - pub fn connect_enough_data(&self, f: F) -> u64 { unsafe { let f: Box_> = Box_::new(Box_::new(f)); @@ -276,22 +212,6 @@ impl AppSrc { } } - pub fn connect_push_buffer gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { - unsafe { - let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); - connect(self.to_glib_none().0, "push-buffer", - transmute(push_buffer_trampoline as usize), Box_::into_raw(f) as *mut _) - } - } - - pub fn connect_push_sample gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { - unsafe { - let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); - connect(self.to_glib_none().0, "push-sample", - transmute(push_sample_trampoline as usize), Box_::into_raw(f) as *mut _) - } - } - pub fn connect_seek_data bool + Send + Sync + 'static>(&self, f: F) -> u64 { unsafe { let f: Box_ bool + Send + Sync + 'static>> = Box_::new(Box_::new(f)); @@ -304,12 +224,6 @@ impl AppSrc { unsafe impl Send for AppSrc {} unsafe impl Sync for AppSrc {} -unsafe extern "C" fn end_of_stream_trampoline(this: *mut ffi::GstAppSrc, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn { - callback_guard!(); - let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); - f(&from_glib_none(this)).to_glib() -} - unsafe extern "C" fn enough_data_trampoline(this: *mut ffi::GstAppSrc, f: glib_ffi::gpointer) { callback_guard!(); let f: &Box_ = transmute(f); @@ -322,18 +236,6 @@ unsafe extern "C" fn need_data_trampoline(this: *mut ffi::GstAppSrc, length: lib f(&from_glib_none(this), length) } -unsafe extern "C" fn push_buffer_trampoline(this: *mut ffi::GstAppSrc, buffer: *mut gst_ffi::GstBuffer, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn { - callback_guard!(); - let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); - f(&from_glib_none(this), &from_glib_none(buffer)).to_glib() -} - -unsafe extern "C" fn push_sample_trampoline(this: *mut ffi::GstAppSrc, sample: *mut gst_ffi::GstSample, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn { - callback_guard!(); - let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); - f(&from_glib_none(this), &from_glib_none(sample)).to_glib() -} - unsafe extern "C" fn seek_data_trampoline(this: *mut ffi::GstAppSrc, offset: u64, f: glib_ffi::gpointer) -> glib_ffi::gboolean { callback_guard!(); let f: &Box_ bool + Send + Sync + 'static> = transmute(f); diff --git a/gstreamer-app/src/lib.rs b/gstreamer-app/src/lib.rs index 3af0f16c2..db4723048 100644 --- a/gstreamer-app/src/lib.rs +++ b/gstreamer-app/src/lib.rs @@ -34,3 +34,4 @@ mod auto; pub use auto::*; pub use auto::traits::*; +mod app_src;