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