diff --git a/Gir_GstVideo.toml b/Gir_GstVideo.toml index 5fc3a6350..94eed290d 100644 --- a/Gir_GstVideo.toml +++ b/Gir_GstVideo.toml @@ -64,6 +64,7 @@ manual = [ "Gst.FlowReturn", "Gst.TagList", "Gst.TagMergeMode", + "GstBase.BaseSink", "GstBase.BaseTransform", "GstVideo.VideoCodecState", "GstVideo.VideoCodecFrame", @@ -247,4 +248,13 @@ name = "GstVideo.VideoFormat" status = "generate" [[object.derive]] - name = "Debug, Eq, PartialEq, Hash" \ No newline at end of file + name = "Debug, Eq, PartialEq, Hash" + +[[object]] +name = "GstVideo.VideoSink" +status = "generate" + + [[object.function]] + name = "center_rect" + # Implemented in video_rectangle + ignore = true diff --git a/gstreamer-video/src/auto/mod.rs b/gstreamer-video/src/auto/mod.rs index 80b3eb9e3..edd6ed9c7 100644 --- a/gstreamer-video/src/auto/mod.rs +++ b/gstreamer-video/src/auto/mod.rs @@ -20,6 +20,10 @@ mod video_overlay; pub use self::video_overlay::VideoOverlayExt; pub use self::video_overlay::{VideoOverlay, NONE_VIDEO_OVERLAY}; +mod video_sink; +pub use self::video_sink::VideoSinkExt; +pub use self::video_sink::{VideoSink, VideoSinkClass, NONE_VIDEO_SINK}; + mod enums; #[cfg(any(feature = "v1_18", feature = "dox"))] pub use self::enums::VideoAFDSpec; @@ -63,4 +67,5 @@ pub mod traits { pub use super::VideoDecoderExt; pub use super::VideoEncoderExt; pub use super::VideoOverlayExt; + pub use super::VideoSinkExt; } diff --git a/gstreamer-video/src/auto/versions.txt b/gstreamer-video/src/auto/versions.txt index 9f53a6200..2a1c25cc3 100644 --- a/gstreamer-video/src/auto/versions.txt +++ b/gstreamer-video/src/auto/versions.txt @@ -1,2 +1,2 @@ Generated by gir (https://github.com/gtk-rs/gir @ 882e09b) -from gir-files (https://github.com/gtk-rs/gir-files @ 38361831) +from gir-files (https://github.com/gtk-rs/gir-files @ 1a54d3bc) diff --git a/gstreamer-video/src/auto/video_sink.rs b/gstreamer-video/src/auto/video_sink.rs new file mode 100644 index 000000000..e249d8b08 --- /dev/null +++ b/gstreamer-video/src/auto/video_sink.rs @@ -0,0 +1,99 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use glib::object::Cast; +use glib::object::IsA; +use glib::signal::connect_raw; +use glib::signal::SignalHandlerId; +use glib::translate::*; +use glib::StaticType; +use glib::Value; +use glib_sys; +use gobject_sys; +use gst; +use gst_base; +use gst_video_sys; +use std::boxed::Box as Box_; +use std::mem::transmute; + +glib_wrapper! { + pub struct VideoSink(Object) @extends gst_base::BaseSink, gst::Element, gst::Object; + + match fn { + get_type => || gst_video_sys::gst_video_sink_get_type(), + } +} + +unsafe impl Send for VideoSink {} +unsafe impl Sync for VideoSink {} + +pub const NONE_VIDEO_SINK: Option<&VideoSink> = None; + +pub trait VideoSinkExt: 'static { + fn get_property_show_preroll_frame(&self) -> bool; + + fn set_property_show_preroll_frame(&self, show_preroll_frame: bool); + + fn connect_property_show_preroll_frame_notify( + &self, + f: F, + ) -> SignalHandlerId; +} + +impl> VideoSinkExt for O { + fn get_property_show_preroll_frame(&self) -> bool { + unsafe { + let mut value = Value::from_type(::static_type()); + gobject_sys::g_object_get_property( + self.to_glib_none().0 as *mut gobject_sys::GObject, + b"show-preroll-frame\0".as_ptr() as *const _, + value.to_glib_none_mut().0, + ); + value + .get() + .expect("Return Value for property `show-preroll-frame` getter") + .unwrap() + } + } + + fn set_property_show_preroll_frame(&self, show_preroll_frame: bool) { + unsafe { + gobject_sys::g_object_set_property( + self.to_glib_none().0 as *mut gobject_sys::GObject, + b"show-preroll-frame\0".as_ptr() as *const _, + Value::from(&show_preroll_frame).to_glib_none().0, + ); + } + } + + fn connect_property_show_preroll_frame_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_show_preroll_frame_trampoline< + P, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut gst_video_sys::GstVideoSink, + _param_spec: glib_sys::gpointer, + f: glib_sys::gpointer, + ) where + P: IsA, + { + let f: &F = &*(f as *const F); + f(&VideoSink::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::show-preroll-frame\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_show_preroll_frame_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} diff --git a/gstreamer-video/src/subclass/mod.rs b/gstreamer-video/src/subclass/mod.rs index afd70a6ad..5567c61c1 100644 --- a/gstreamer-video/src/subclass/mod.rs +++ b/gstreamer-video/src/subclass/mod.rs @@ -9,8 +9,10 @@ mod video_decoder; mod video_encoder; +mod video_sink; pub mod prelude { pub use super::video_decoder::{VideoDecoderImpl, VideoDecoderImplExt}; pub use super::video_encoder::{VideoEncoderImpl, VideoEncoderImplExt}; + pub use super::video_sink::{VideoSinkImpl, VideoSinkImplExt}; } diff --git a/gstreamer-video/src/subclass/video_sink.rs b/gstreamer-video/src/subclass/video_sink.rs new file mode 100644 index 000000000..0dad9a58a --- /dev/null +++ b/gstreamer-video/src/subclass/video_sink.rs @@ -0,0 +1,93 @@ +// Copyright (C) 2020 François Laignel +// +// 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 gst_sys; +use gst_video_sys; + +use glib::translate::*; + +use glib::subclass::prelude::*; +use gst; +use gst::subclass::prelude::*; +use gst_base::subclass::prelude::*; + +use VideoSink; +use VideoSinkClass; + +pub trait VideoSinkImpl: + VideoSinkImplExt + BaseSinkImpl + ElementImpl + Send + Sync + 'static +{ + fn show_frame( + &self, + element: &VideoSink, + buffer: &gst::Buffer, + ) -> Result { + self.parent_show_frame(element, buffer) + } +} + +pub trait VideoSinkImplExt { + fn parent_show_frame( + &self, + element: &VideoSink, + buffer: &gst::Buffer, + ) -> Result; +} + +impl VideoSinkImplExt for T { + fn parent_show_frame( + &self, + element: &VideoSink, + buffer: &gst::Buffer, + ) -> Result { + unsafe { + let data = self.get_type_data(); + let parent_class = + data.as_ref().get_parent_class() as *mut gst_video_sys::GstVideoSinkClass; + (*parent_class) + .show_frame + .map(|f| { + gst::FlowReturn::from_glib(f(element.to_glib_none().0, buffer.to_glib_none().0)) + }) + .unwrap_or(gst::FlowReturn::Error) + .into_result() + } + } +} + +unsafe impl IsSubclassable for VideoSinkClass +where + ::Instance: PanicPoison, +{ + fn override_vfuncs(&mut self) { + >::override_vfuncs(self); + unsafe { + let klass = &mut *(self as *mut Self as *mut gst_video_sys::GstVideoSinkClass); + klass.show_frame = Some(video_sink_show_frame::); + } + } +} + +unsafe extern "C" fn video_sink_show_frame( + ptr: *mut gst_video_sys::GstVideoSink, + buffer: *mut gst_sys::GstBuffer, +) -> gst_sys::GstFlowReturn +where + T: VideoSinkImpl, + T::Instance: PanicPoison, +{ + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Borrowed = from_glib_borrow(ptr); + let buffer = from_glib_borrow(buffer); + + gst_panic_to_error!(&wrap, &instance.panicked(), gst::FlowReturn::Error, { + imp.show_frame(&wrap, &buffer).into() + }) + .to_glib() +}