gstreamer_video/auto/video_overlay.rs
1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
4// DO NOT EDIT
5
6use crate::ffi;
7use glib::{prelude::*, translate::*};
8
9glib::wrapper! {
10 /// The [`VideoOverlay`][crate::VideoOverlay] interface is used for 2 main purposes :
11 ///
12 /// * To get a grab on the Window where the video sink element is going to render.
13 /// This is achieved by either being informed about the Window identifier that
14 /// the video sink element generated, or by forcing the video sink element to use
15 /// a specific Window identifier for rendering.
16 /// * To force a redrawing of the latest video frame the video sink element
17 /// displayed on the Window. Indeed if the [`gst::Pipeline`][crate::gst::Pipeline] is in [`gst::State::Paused`][crate::gst::State::Paused]
18 /// state, moving the Window around will damage its content. Application
19 /// developers will want to handle the Expose events themselves and force the
20 /// video sink element to refresh the Window's content.
21 ///
22 /// Using the Window created by the video sink is probably the simplest scenario,
23 /// in some cases, though, it might not be flexible enough for application
24 /// developers if they need to catch events such as mouse moves and button
25 /// clicks.
26 ///
27 /// Setting a specific Window identifier on the video sink element is the most
28 /// flexible solution but it has some issues. Indeed the application needs to set
29 /// its Window identifier at the right time to avoid internal Window creation
30 /// from the video sink element. To solve this issue a [`gst::Message`][crate::gst::Message] is posted on
31 /// the bus to inform the application that it should set the Window identifier
32 /// immediately. Here is an example on how to do that correctly:
33 ///
34 /// ```text
35 /// static GstBusSyncReply
36 /// create_window (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
37 /// {
38 /// // ignore anything but 'prepare-window-handle' element messages
39 /// if (!gst_is_video_overlay_prepare_window_handle_message (message))
40 /// return GST_BUS_PASS;
41 ///
42 /// win = XCreateSimpleWindow (disp, root, 0, 0, 320, 240, 0, 0, 0);
43 ///
44 /// XSetWindowBackgroundPixmap (disp, win, None);
45 ///
46 /// XMapRaised (disp, win);
47 ///
48 /// XSync (disp, FALSE);
49 ///
50 /// gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)),
51 /// win);
52 ///
53 /// gst_message_unref (message);
54 ///
55 /// return GST_BUS_DROP;
56 /// }
57 /// ...
58 /// int
59 /// main (int argc, char **argv)
60 /// {
61 /// ...
62 /// bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
63 /// gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, pipeline,
64 /// NULL);
65 /// ...
66 /// }
67 /// ```
68 ///
69 /// ## Two basic usage scenarios
70 ///
71 /// There are two basic usage scenarios: in the simplest case, the application
72 /// uses `playbin` or `playsink` or knows exactly what particular element is used
73 /// for video output, which is usually the case when the application creates
74 /// the videosink to use (e.g. `xvimagesink`, `ximagesink`, etc.) itself; in this
75 /// case, the application can just create the videosink element, create and
76 /// realize the window to render the video on and then
77 /// call [`VideoOverlayExtManual::set_window_handle()`][crate::prelude::VideoOverlayExtManual::set_window_handle()] directly with the XID or native
78 /// window handle, before starting up the pipeline.
79 /// As `playbin` and `playsink` implement the video overlay interface and proxy
80 /// it transparently to the actual video sink even if it is created later, this
81 /// case also applies when using these elements.
82 ///
83 /// In the other and more common case, the application does not know in advance
84 /// what GStreamer video sink element will be used for video output. This is
85 /// usually the case when an element such as `autovideosink` is used.
86 /// In this case, the video sink element itself is created
87 /// asynchronously from a GStreamer streaming thread some time after the
88 /// pipeline has been started up. When that happens, however, the video sink
89 /// will need to know right then whether to render onto an already existing
90 /// application window or whether to create its own window. This is when it
91 /// posts a prepare-window-handle message, and that is also why this message needs
92 /// to be handled in a sync bus handler which will be called from the streaming
93 /// thread directly (because the video sink will need an answer right then).
94 ///
95 /// As response to the prepare-window-handle element message in the bus sync
96 /// handler, the application may use [`VideoOverlayExtManual::set_window_handle()`][crate::prelude::VideoOverlayExtManual::set_window_handle()] to tell
97 /// the video sink to render onto an existing window surface. At this point the
98 /// application should already have obtained the window handle / XID, so it
99 /// just needs to set it. It is generally not advisable to call any GUI toolkit
100 /// functions or window system functions from the streaming thread in which the
101 /// prepare-window-handle message is handled, because most GUI toolkits and
102 /// windowing systems are not thread-safe at all and a lot of care would be
103 /// required to co-ordinate the toolkit and window system calls of the
104 /// different threads (Gtk+ users please note: prior to Gtk+ 2.18
105 /// `GDK_WINDOW_XID` was just a simple structure access, so generally fine to do
106 /// within the bus sync handler; this macro was changed to a function call in
107 /// Gtk+ 2.18 and later, which is likely to cause problems when called from a
108 /// sync handler; see below for a better approach without `GDK_WINDOW_XID`
109 /// used in the callback).
110 ///
111 /// ## GstVideoOverlay and Gtk+
112 ///
113 ///
114 /// ```text
115 /// #include <gst/video/videooverlay.h>
116 /// #include <gtk/gtk.h>
117 /// #ifdef GDK_WINDOWING_X11
118 /// #include <gdk/gdkx.h> // for GDK_WINDOW_XID
119 /// #endif
120 /// #ifdef GDK_WINDOWING_WIN32
121 /// #include <gdk/gdkwin32.h> // for GDK_WINDOW_HWND
122 /// #endif
123 /// ...
124 /// static guintptr video_window_handle = 0;
125 /// ...
126 /// static GstBusSyncReply
127 /// bus_sync_handler (GstBus * bus, GstMessage * message, gpointer user_data)
128 /// {
129 /// // ignore anything but 'prepare-window-handle' element messages
130 /// if (!gst_is_video_overlay_prepare_window_handle_message (message))
131 /// return GST_BUS_PASS;
132 ///
133 /// if (video_window_handle != 0) {
134 /// GstVideoOverlay *overlay;
135 ///
136 /// // GST_MESSAGE_SRC (message) will be the video sink element
137 /// overlay = GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message));
138 /// gst_video_overlay_set_window_handle (overlay, video_window_handle);
139 /// } else {
140 /// g_warning ("Should have obtained video_window_handle by now!");
141 /// }
142 ///
143 /// gst_message_unref (message);
144 /// return GST_BUS_DROP;
145 /// }
146 /// ...
147 /// static void
148 /// video_widget_realize_cb (GtkWidget * widget, gpointer data)
149 /// {
150 /// #if GTK_CHECK_VERSION(2,18,0)
151 /// // Tell Gtk+/Gdk to create a native window for this widget instead of
152 /// // drawing onto the parent widget.
153 /// // This is here just for pedagogical purposes, GDK_WINDOW_XID will call
154 /// // it as well in newer Gtk versions
155 /// if (!gdk_window_ensure_native (widget->window))
156 /// g_error ("Couldn't create native window needed for GstVideoOverlay!");
157 /// #endif
158 ///
159 /// #ifdef GDK_WINDOWING_X11
160 /// {
161 /// gulong xid = GDK_WINDOW_XID (gtk_widget_get_window (video_window));
162 /// video_window_handle = xid;
163 /// }
164 /// #endif
165 /// #ifdef GDK_WINDOWING_WIN32
166 /// {
167 /// HWND wnd = GDK_WINDOW_HWND (gtk_widget_get_window (video_window));
168 /// video_window_handle = (guintptr) wnd;
169 /// }
170 /// #endif
171 /// }
172 /// ...
173 /// int
174 /// main (int argc, char **argv)
175 /// {
176 /// GtkWidget *video_window;
177 /// GtkWidget *app_window;
178 /// ...
179 /// app_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
180 /// ...
181 /// video_window = gtk_drawing_area_new ();
182 /// g_signal_connect (video_window, "realize",
183 /// G_CALLBACK (video_widget_realize_cb), NULL);
184 /// gtk_widget_set_double_buffered (video_window, FALSE);
185 /// ...
186 /// // usually the video_window will not be directly embedded into the
187 /// // application window like this, but there will be many other widgets
188 /// // and the video window will be embedded in one of them instead
189 /// gtk_container_add (GTK_CONTAINER (ap_window), video_window);
190 /// ...
191 /// // show the GUI
192 /// gtk_widget_show_all (app_window);
193 ///
194 /// // realize window now so that the video window gets created and we can
195 /// // obtain its XID/HWND before the pipeline is started up and the videosink
196 /// // asks for the XID/HWND of the window to render onto
197 /// gtk_widget_realize (video_window);
198 ///
199 /// // we should have the XID/HWND now
200 /// g_assert (video_window_handle != 0);
201 /// ...
202 /// // set up sync handler for setting the xid once the pipeline is started
203 /// bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
204 /// gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bus_sync_handler, NULL,
205 /// NULL);
206 /// gst_object_unref (bus);
207 /// ...
208 /// gst_element_set_state (pipeline, GST_STATE_PLAYING);
209 /// ...
210 /// }
211 /// ```
212 ///
213 /// ## GstVideoOverlay and Qt
214 ///
215 ///
216 /// ```text
217 /// #include <glib.h>;
218 /// #include <gst/gst.h>;
219 /// #include <gst/video/videooverlay.h>;
220 ///
221 /// #include <QApplication>;
222 /// #include <QTimer>;
223 /// #include <QWidget>;
224 ///
225 /// int main(int argc, char *argv[])
226 /// {
227 /// if (!g_thread_supported ())
228 /// g_thread_init (NULL);
229 ///
230 /// gst_init (&argc, &argv);
231 /// QApplication app(argc, argv);
232 /// app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit ()));
233 ///
234 /// // prepare the pipeline
235 ///
236 /// GstElement *pipeline = gst_pipeline_new ("xvoverlay");
237 /// GstElement *src = gst_element_factory_make ("videotestsrc", NULL);
238 /// GstElement *sink = gst_element_factory_make ("xvimagesink", NULL);
239 /// gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
240 /// gst_element_link (src, sink);
241 ///
242 /// // prepare the ui
243 ///
244 /// QWidget window;
245 /// window.resize(320, 240);
246 /// window.show();
247 ///
248 /// WId xwinid = window.winId();
249 /// gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (sink), xwinid);
250 ///
251 /// // run the pipeline
252 ///
253 /// GstStateChangeReturn sret = gst_element_set_state (pipeline,
254 /// GST_STATE_PLAYING);
255 /// if (sret == GST_STATE_CHANGE_FAILURE) {
256 /// gst_element_set_state (pipeline, GST_STATE_NULL);
257 /// gst_object_unref (pipeline);
258 /// // Exit application
259 /// QTimer::singleShot(0, QApplication::activeWindow(), SLOT(quit()));
260 /// }
261 ///
262 /// int ret = app.exec();
263 ///
264 /// window.hide();
265 /// gst_element_set_state (pipeline, GST_STATE_NULL);
266 /// gst_object_unref (pipeline);
267 ///
268 /// return ret;
269 /// }
270 /// ```
271 ///
272 /// # Implements
273 ///
274 /// [`VideoOverlayExt`][trait@crate::prelude::VideoOverlayExt], [`VideoOverlayExtManual`][trait@crate::prelude::VideoOverlayExtManual]
275 #[doc(alias = "GstVideoOverlay")]
276 pub struct VideoOverlay(Interface<ffi::GstVideoOverlay, ffi::GstVideoOverlayInterface>);
277
278 match fn {
279 type_ => || ffi::gst_video_overlay_get_type(),
280 }
281}
282
283impl VideoOverlay {
284 pub const NONE: Option<&'static VideoOverlay> = None;
285
286 //#[doc(alias = "gst_video_overlay_install_properties")]
287 //pub fn install_properties(oclass: /*Ignored*/&mut glib::ObjectClass, last_prop_id: i32) {
288 // unsafe { TODO: call ffi:gst_video_overlay_install_properties() }
289 //}
290}
291
292unsafe impl Send for VideoOverlay {}
293unsafe impl Sync for VideoOverlay {}
294
295/// Trait containing all [`struct@VideoOverlay`] methods.
296///
297/// # Implementors
298///
299/// [`VideoOverlay`][struct@crate::VideoOverlay]
300pub trait VideoOverlayExt: IsA<VideoOverlay> + 'static {
301 /// Tell an overlay that it has been exposed. This will redraw the current frame
302 /// in the drawable even if the pipeline is PAUSED.
303 #[doc(alias = "gst_video_overlay_expose")]
304 fn expose(&self) {
305 unsafe {
306 ffi::gst_video_overlay_expose(self.as_ref().to_glib_none().0);
307 }
308 }
309
310 //#[doc(alias = "gst_video_overlay_got_window_handle")]
311 //fn got_window_handle(&self, handle: /*Unimplemented*/Basic: UIntPtr) {
312 // unsafe { TODO: call ffi:gst_video_overlay_got_window_handle() }
313 //}
314
315 /// Tell an overlay that it should handle events from the window system. These
316 /// events are forwarded upstream as navigation events. In some window system,
317 /// events are not propagated in the window hierarchy if a client is listening
318 /// for them. This method allows you to disable events handling completely
319 /// from the [`VideoOverlay`][crate::VideoOverlay].
320 /// ## `handle_events`
321 /// a `gboolean` indicating if events should be handled or not.
322 #[doc(alias = "gst_video_overlay_handle_events")]
323 fn handle_events(&self, handle_events: bool) {
324 unsafe {
325 ffi::gst_video_overlay_handle_events(
326 self.as_ref().to_glib_none().0,
327 handle_events.into_glib(),
328 );
329 }
330 }
331
332 /// This will post a "prepare-window-handle" element message on the bus
333 /// to give applications an opportunity to call
334 /// [`VideoOverlayExtManual::set_window_handle()`][crate::prelude::VideoOverlayExtManual::set_window_handle()] before a plugin creates its own
335 /// window.
336 ///
337 /// This function should only be used by video overlay plugin developers.
338 #[doc(alias = "gst_video_overlay_prepare_window_handle")]
339 fn prepare_window_handle(&self) {
340 unsafe {
341 ffi::gst_video_overlay_prepare_window_handle(self.as_ref().to_glib_none().0);
342 }
343 }
344
345 /// Configure a subregion as a video target within the window set by
346 /// [`VideoOverlayExtManual::set_window_handle()`][crate::prelude::VideoOverlayExtManual::set_window_handle()]. If this is not used or not supported
347 /// the video will fill the area of the window set as the overlay to 100%.
348 /// By specifying the rectangle, the video can be overlayed to a specific region
349 /// of that window only. After setting the new rectangle one should call
350 /// [`expose()`][Self::expose()] to force a redraw. To unset the region pass -1 for
351 /// the `width` and `height` parameters.
352 ///
353 /// This method is needed for non fullscreen video overlay in UI toolkits that
354 /// do not support subwindows.
355 /// ## `x`
356 /// the horizontal offset of the render area inside the window
357 /// ## `y`
358 /// the vertical offset of the render area inside the window
359 /// ## `width`
360 /// the width of the render area inside the window
361 /// ## `height`
362 /// the height of the render area inside the window
363 ///
364 /// # Returns
365 ///
366 /// [`false`] if not supported by the sink.
367 #[doc(alias = "gst_video_overlay_set_render_rectangle")]
368 fn set_render_rectangle(
369 &self,
370 x: i32,
371 y: i32,
372 width: i32,
373 height: i32,
374 ) -> Result<(), glib::error::BoolError> {
375 unsafe {
376 glib::result_from_gboolean!(
377 ffi::gst_video_overlay_set_render_rectangle(
378 self.as_ref().to_glib_none().0,
379 x,
380 y,
381 width,
382 height
383 ),
384 "Failed to set render rectangle"
385 )
386 }
387 }
388}
389
390impl<O: IsA<VideoOverlay>> VideoOverlayExt for O {}