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