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  * Conversion parameters:
26  * inFile  = GstBin.html
27  * outPack = gstreamer
28  * outFile = Bin
29  * strct   = GstBin
30  * realStrct=
31  * ctorStrct=GstElement
32  * clss    = Bin
33  * interf  = 
34  * class Code: Yes
35  * interface Code: No
36  * template for:
37  * extend  = 
38  * implements:
39  * prefixes:
40  * 	- gst_bin_
41  * omit structs:
42  * omit prefixes:
43  * omit code:
44  * omit signals:
45  * imports:
46  * 	- glib.Str
47  * 	- gstreamer.Element
48  * 	- gstreamer.Iterator
49  * 	- gstreamer.Pad
50  * structWrap:
51  * 	- GstElement* -> Element
52  * 	- GstIterator* -> Iterator
53  * 	- GstPad* -> Pad
54  * module aliases:
55  * local aliases:
56  * overrides:
57  */
58 
59 module gstreamer.Bin;
60 
61 public  import gstreamerc.gstreamertypes;
62 
63 private import gstreamerc.gstreamer;
64 private import glib.ConstructionException;
65 private import gobject.ObjectG;
66 
67 private import gobject.Signals;
68 public  import gtkc.gdktypes;
69 private import glib.Str;
70 private import gstreamer.Element;
71 private import gstreamer.Iterator;
72 private import gstreamer.Pad;
73 
74 
75 private import gstreamer.Element;
76 
77 /**
78  * GstBin is an element that can contain other GstElement, allowing them to be
79  * managed as a group.
80  * Pads from the child elements can be ghosted to the bin, see GstGhostPad.
81  * This makes the bin look like any other elements and enables creation of
82  * higher-level abstraction elements.
83  *
84  * A new GstBin is created with gst_bin_new(). Use a GstPipeline instead if you
85  * want to create a toplevel bin because a normal bin doesn't have a bus or
86  * handle clock distribution of its own.
87  *
88  * After the bin has been created you will typically add elements to it with
89  * gst_bin_add(). You can remove elements with gst_bin_remove().
90  *
91  * An element can be retrieved from a bin with gst_bin_get_by_name(), using the
92  * elements name. gst_bin_get_by_name_recurse_up() is mainly used for internal
93  * purposes and will query the parent bins when the element is not found in the
94  * current bin.
95  *
96  * An iterator of elements in a bin can be retrieved with
97  * gst_bin_iterate_elements(). Various other iterators exist to retrieve the
98  * elements in a bin.
99  *
100  * gst_object_unref() is used to drop your reference to the bin.
101  *
102  * The "element-added" signal is fired whenever a new element is added to
103  * the bin. Likewise the "element-removed" signal is fired whenever an
104  * element is removed from the bin.
105  *
106  * Notes
107  *
108  * A GstBin internally intercepts every GstMessage posted by its children and
109  * implements the following default behaviour for each of them:
110  *
111  * GST_MESSAGE_EOS
112  *
113  * This message is only posted by sinks in the PLAYING
114  *  state. If all sinks posted the EOS message, this bin will post and EOS
115  *  message upwards.
116  *
117  * GST_MESSAGE_SEGMENT_START
118  *
119  * just collected and never forwarded upwards.
120  *  The messages are used to decide when all elements have completed playback
121  *  of their segment.
122  *
123  * GST_MESSAGE_SEGMENT_DONE
124  *
125  *  Is posted by GstBin when all elements that posted
126  *  a SEGMENT_START have posted a SEGMENT_DONE.
127  *
128  * GST_MESSAGE_DURATION_CHANGED
129  *
130  *  Is posted by an element that detected a change
131  *  in the stream duration. The default bin behaviour is to clear any
132  *  cached duration values so that the next duration query will perform
133  *  a full duration recalculation. The duration change is posted to the
134  *  application so that it can refetch the new duration with a duration
135  *  query. Note that these messages can be posted before the bin is
136  *  prerolled, in which case the duration query might fail.
137  *
138  * GST_MESSAGE_CLOCK_LOST
139  *
140  *  This message is posted by an element when it
141  *  can no longer provide a clock. The default bin behaviour is to
142  *  check if the lost clock was the one provided by the bin. If so and
143  *  the bin is currently in the PLAYING state, the message is forwarded to
144  *  the bin parent.
145  *  This message is also generated when a clock provider is removed from
146  *  the bin. If this message is received by the application, it should
147  *  PAUSE the pipeline and set it back to PLAYING to force a new clock
148  *  distribution.
149  *
150  * GST_MESSAGE_CLOCK_PROVIDE
151  *
152  *  This message is generated when an element
153  *  can provide a clock. This mostly happens when a new clock
154  *  provider is added to the bin. The default behaviour of the bin is to
155  *  mark the currently selected clock as dirty, which will perform a clock
156  *  recalculation the next time the bin is asked to provide a clock.
157  *  This message is never sent tot the application but is forwarded to
158  *  the parent of the bin.
159  *
160  * OTHERS
161  *
162  *  posted upwards.
163  *
164  * A GstBin implements the following default behaviour for answering to a
165  * GstQuery:
166  *
167  * GST_QUERY_DURATION
168  *
169  * If the query has been asked before with the same format
170  *  and the bin is a toplevel bin (ie. has no parent),
171  *  use the cached previous value. If no previous value was cached, the
172  *  query is sent to all sink elements in the bin and the MAXIMUM of all
173  *  values is returned. If the bin is a toplevel bin the value is cached.
174  *  If no sinks are available in the bin, the query fails.
175  *
176  * GST_QUERY_POSITION
177  *
178  * The query is sent to all sink elements in the bin and the
179  *  MAXIMUM of all values is returned. If no sinks are available in the bin,
180  *  the query fails.
181  *
182  * OTHERS
183  *
184  * the query is forwarded to all sink elements, the result
185  *  of the first sink that answers the query successfully is returned. If no
186  *  sink is in the bin, the query fails.
187  *
188  * A GstBin will by default forward any event sent to it to all sink elements.
189  * If all the sinks return TRUE, the bin will also return TRUE, else FALSE is
190  * returned. If no sinks are in the bin, the event handler will return TRUE.
191  *
192  * Last reviewed on 2012-03-28 (0.11.3)
193  */
194 public class Bin : Element
195 {
196 	
197 	/** the main Gtk struct */
198 	protected GstBin* gstBin;
199 	
200 	
201 	/** Get the main Gtk struct */
202 	public GstBin* getBinStruct()
203 	{
204 		return gstBin;
205 	}
206 	
207 	
208 	/** the main Gtk struct as a void* */
209 	protected override void* getStruct()
210 	{
211 		return cast(void*)gstBin;
212 	}
213 	
214 	/**
215 	 * Sets our main struct and passes it to the parent class
216 	 */
217 	public this (GstBin* gstBin)
218 	{
219 		super(cast(GstElement*)gstBin);
220 		this.gstBin = gstBin;
221 	}
222 	
223 	protected override void setStruct(GObject* obj)
224 	{
225 		super.setStruct(obj);
226 		gstBin = cast(GstBin*)obj;
227 	}
228 	
229 	/** */
230 	public this(Element elem)
231 	{
232 		super( elem.getElementStruct() );
233 		this.gstBin = cast(GstBin*)elem.getElementStruct();
234 	}
235 	
236 	/**
237 	 */
238 	int[string] connectedSignals;
239 	
240 	bool delegate(Bin)[] onDoLatencyListeners;
241 	/**
242 	 * Will be emitted when the bin needs to perform latency calculations. This
243 	 * signal is only emited for toplevel bins or when async-handling is
244 	 * enabled.
245 	 * Only one signal handler is invoked. If no signals are connected, the
246 	 * default handler is invoked, which will query and distribute the lowest
247 	 * possible latency to all sinks.
248 	 * Connect to this signal if the default latency calculations are not
249 	 * sufficient, like when you need different latencies for different sinks in
250 	 * the same pipeline.
251 	 */
252 	void addOnDoLatency(bool delegate(Bin) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
253 	{
254 		if ( !("do-latency" in connectedSignals) )
255 		{
256 			Signals.connectData(
257 			getStruct(),
258 			"do-latency",
259 			cast(GCallback)&callBackDoLatency,
260 			cast(void*)this,
261 			null,
262 			connectFlags);
263 			connectedSignals["do-latency"] = 1;
264 		}
265 		onDoLatencyListeners ~= dlg;
266 	}
267 	extern(C) static gboolean callBackDoLatency(GstBin* binStruct, Bin _bin)
268 	{
269 		foreach ( bool delegate(Bin) dlg ; _bin.onDoLatencyListeners )
270 		{
271 			if ( dlg(_bin) )
272 			{
273 				return 1;
274 			}
275 		}
276 		
277 		return 0;
278 	}
279 	
280 	void delegate(Element, Bin)[] onElementAddedListeners;
281 	/**
282 	 * Will be emitted after the element was added to the bin.
283 	 */
284 	void addOnElementAdded(void delegate(Element, Bin) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
285 	{
286 		if ( !("element-added" in connectedSignals) )
287 		{
288 			Signals.connectData(
289 			getStruct(),
290 			"element-added",
291 			cast(GCallback)&callBackElementAdded,
292 			cast(void*)this,
293 			null,
294 			connectFlags);
295 			connectedSignals["element-added"] = 1;
296 		}
297 		onElementAddedListeners ~= dlg;
298 	}
299 	extern(C) static void callBackElementAdded(GstBin* binStruct, GstElement* element, Bin _bin)
300 	{
301 		foreach ( void delegate(Element, Bin) dlg ; _bin.onElementAddedListeners )
302 		{
303 			dlg(ObjectG.getDObject!(Element)(element), _bin);
304 		}
305 	}
306 	
307 	void delegate(Element, Bin)[] onElementRemovedListeners;
308 	/**
309 	 * Will be emitted after the element was removed from the bin.
310 	 */
311 	void addOnElementRemoved(void delegate(Element, Bin) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
312 	{
313 		if ( !("element-removed" in connectedSignals) )
314 		{
315 			Signals.connectData(
316 			getStruct(),
317 			"element-removed",
318 			cast(GCallback)&callBackElementRemoved,
319 			cast(void*)this,
320 			null,
321 			connectFlags);
322 			connectedSignals["element-removed"] = 1;
323 		}
324 		onElementRemovedListeners ~= dlg;
325 	}
326 	extern(C) static void callBackElementRemoved(GstBin* binStruct, GstElement* element, Bin _bin)
327 	{
328 		foreach ( void delegate(Element, Bin) dlg ; _bin.onElementRemovedListeners )
329 		{
330 			dlg(ObjectG.getDObject!(Element)(element), _bin);
331 		}
332 	}
333 	
334 	
335 	/**
336 	 * Creates a new bin with the given name.
337 	 * Params:
338 	 * name = the name of the new bin
339 	 * Throws: ConstructionException GTK+ fails to create the object.
340 	 */
341 	public this (string name)
342 	{
343 		// GstElement * gst_bin_new (const gchar *name);
344 		auto p = gst_bin_new(Str.toStringz(name));
345 		if(p is null)
346 		{
347 			throw new ConstructionException("null returned by gst_bin_new(Str.toStringz(name))");
348 		}
349 		this(cast(GstBin*) p);
350 	}
351 	
352 	/**
353 	 * Adds the given element to the bin. Sets the element's parent, and thus
354 	 * takes ownership of the element. An element can only be added to one bin.
355 	 * If the element's pads are linked to other pads, the pads will be unlinked
356 	 * before the element is added to the bin.
357 	 * Note
358 	 * When you add an element to an already-running pipeline, you will have to
359 	 * take care to set the state of the newly-added element to the desired
360 	 * state (usually PLAYING or PAUSED, same you set the pipeline to originally)
361 	 * with gst_element_set_state(), or use gst_element_sync_state_with_parent().
362 	 * The bin or pipeline will not take care of this for you.
363 	 * MT safe.
364 	 * Params:
365 	 * element = the GstElement to add. [transfer full]
366 	 * Returns: TRUE if the element could be added, FALSE if the bin does not want to accept the element.
367 	 */
368 	public int add(Element element)
369 	{
370 		// gboolean gst_bin_add (GstBin *bin,  GstElement *element);
371 		return gst_bin_add(gstBin, (element is null) ? null : element.getElementStruct());
372 	}
373 	
374 	/**
375 	 * Removes the element from the bin, unparenting it as well.
376 	 * Unparenting the element means that the element will be dereferenced,
377 	 * so if the bin holds the only reference to the element, the element
378 	 * will be freed in the process of removing it from the bin. If you
379 	 * want the element to still exist after removing, you need to call
380 	 * gst_object_ref() before removing it from the bin.
381 	 * If the element's pads are linked to other pads, the pads will be unlinked
382 	 * before the element is removed from the bin.
383 	 * MT safe.
384 	 * Params:
385 	 * element = the GstElement to remove. [transfer none]
386 	 * Returns: TRUE if the element could be removed, FALSE if the bin does not want to remove the element.
387 	 */
388 	public int remove(Element element)
389 	{
390 		// gboolean gst_bin_remove (GstBin *bin,  GstElement *element);
391 		return gst_bin_remove(gstBin, (element is null) ? null : element.getElementStruct());
392 	}
393 	
394 	/**
395 	 * Gets the element with the given name from a bin. This
396 	 * function recurses into child bins.
397 	 * Returns NULL if no element with the given name is found in the bin.
398 	 * MT safe. Caller owns returned reference.
399 	 * Params:
400 	 * name = the element name to search for
401 	 * Returns: the GstElement with the given name, or NULL. [transfer full]
402 	 */
403 	public Element getByName(string name)
404 	{
405 		// GstElement * gst_bin_get_by_name (GstBin *bin,  const gchar *name);
406 		auto p = gst_bin_get_by_name(gstBin, Str.toStringz(name));
407 		
408 		if(p is null)
409 		{
410 			return null;
411 		}
412 		
413 		return ObjectG.getDObject!(Element)(cast(GstElement*) p);
414 	}
415 	
416 	/**
417 	 * Gets the element with the given name from this bin. If the
418 	 * element is not found, a recursion is performed on the parent bin.
419 	 * Params:
420 	 * name = the element name to search for
421 	 * Returns: the GstElement with the given name, or NULL. [transfer full]
422 	 */
423 	public Element getByNameRecurseUp(string name)
424 	{
425 		// GstElement * gst_bin_get_by_name_recurse_up (GstBin *bin,  const gchar *name);
426 		auto p = gst_bin_get_by_name_recurse_up(gstBin, Str.toStringz(name));
427 		
428 		if(p is null)
429 		{
430 			return null;
431 		}
432 		
433 		return ObjectG.getDObject!(Element)(cast(GstElement*) p);
434 	}
435 	
436 	/**
437 	 * Looks for an element inside the bin that implements the given
438 	 * interface. If such an element is found, it returns the element.
439 	 * You can cast this element to the given interface afterwards. If you want
440 	 * all elements that implement the interface, use
441 	 * gst_bin_iterate_all_by_interface(). This function recurses into child bins.
442 	 * MT safe. Caller owns returned reference.
443 	 * Params:
444 	 * iface = the GType of an interface
445 	 * Returns: A GstElement inside the bin implementing the interface. [transfer full]
446 	 */
447 	public Element getByInterface(GType iface)
448 	{
449 		// GstElement * gst_bin_get_by_interface (GstBin *bin,  GType iface);
450 		auto p = gst_bin_get_by_interface(gstBin, iface);
451 		
452 		if(p is null)
453 		{
454 			return null;
455 		}
456 		
457 		return ObjectG.getDObject!(Element)(cast(GstElement*) p);
458 	}
459 	
460 	/**
461 	 * Gets an iterator for the elements in this bin.
462 	 * MT safe. Caller owns returned value.
463 	 * Returns: a GstIterator of GstElement, or NULL. [transfer full]
464 	 */
465 	public Iterator iterateElements()
466 	{
467 		// GstIterator * gst_bin_iterate_elements (GstBin *bin);
468 		auto p = gst_bin_iterate_elements(gstBin);
469 		
470 		if(p is null)
471 		{
472 			return null;
473 		}
474 		
475 		return ObjectG.getDObject!(Iterator)(cast(GstIterator*) p);
476 	}
477 	
478 	/**
479 	 * Gets an iterator for the elements in this bin.
480 	 * This iterator recurses into GstBin children.
481 	 * MT safe. Caller owns returned value.
482 	 * Returns: a GstIterator of GstElement, or NULL. [transfer full]
483 	 */
484 	public Iterator iterateRecurse()
485 	{
486 		// GstIterator * gst_bin_iterate_recurse (GstBin *bin);
487 		auto p = gst_bin_iterate_recurse(gstBin);
488 		
489 		if(p is null)
490 		{
491 			return null;
492 		}
493 		
494 		return ObjectG.getDObject!(Iterator)(cast(GstIterator*) p);
495 	}
496 	
497 	/**
498 	 * Gets an iterator for all elements in the bin that have the
499 	 * GST_ELEMENT_FLAG_SINK flag set.
500 	 * MT safe. Caller owns returned value.
501 	 * Returns: a GstIterator of GstElement, or NULL. [transfer full]
502 	 */
503 	public Iterator iterateSinks()
504 	{
505 		// GstIterator * gst_bin_iterate_sinks (GstBin *bin);
506 		auto p = gst_bin_iterate_sinks(gstBin);
507 		
508 		if(p is null)
509 		{
510 			return null;
511 		}
512 		
513 		return ObjectG.getDObject!(Iterator)(cast(GstIterator*) p);
514 	}
515 	
516 	/**
517 	 * Gets an iterator for the elements in this bin in topologically
518 	 * sorted order. This means that the elements are returned from
519 	 * the most downstream elements (sinks) to the sources.
520 	 * This function is used internally to perform the state changes
521 	 * of the bin elements and for clock selection.
522 	 * MT safe. Caller owns returned value.
523 	 * Returns: a GstIterator of GstElement, or NULL. [transfer full]
524 	 */
525 	public Iterator iterateSorted()
526 	{
527 		// GstIterator * gst_bin_iterate_sorted (GstBin *bin);
528 		auto p = gst_bin_iterate_sorted(gstBin);
529 		
530 		if(p is null)
531 		{
532 			return null;
533 		}
534 		
535 		return ObjectG.getDObject!(Iterator)(cast(GstIterator*) p);
536 	}
537 	
538 	/**
539 	 * Gets an iterator for all elements in the bin that have the
540 	 * GST_ELEMENT_FLAG_SOURCE flag set.
541 	 * MT safe. Caller owns returned value.
542 	 * Returns: a GstIterator of GstElement, or NULL. [transfer full]
543 	 */
544 	public Iterator iterateSources()
545 	{
546 		// GstIterator * gst_bin_iterate_sources (GstBin *bin);
547 		auto p = gst_bin_iterate_sources(gstBin);
548 		
549 		if(p is null)
550 		{
551 			return null;
552 		}
553 		
554 		return ObjectG.getDObject!(Iterator)(cast(GstIterator*) p);
555 	}
556 	
557 	/**
558 	 * Looks for all elements inside the bin that implements the given
559 	 * interface. You can safely cast all returned elements to the given interface.
560 	 * The function recurses inside child bins. The iterator will yield a series
561 	 * of GstElement that should be unreffed after use.
562 	 * MT safe. Caller owns returned value.
563 	 * Params:
564 	 * iface = the GType of an interface
565 	 * Returns: a GstIterator of GstElement for all elements in the bin implementing the given interface, or NULL. [transfer full]
566 	 */
567 	public Iterator iterateAllByInterface(GType iface)
568 	{
569 		// GstIterator * gst_bin_iterate_all_by_interface (GstBin *bin,  GType iface);
570 		auto p = gst_bin_iterate_all_by_interface(gstBin, iface);
571 		
572 		if(p is null)
573 		{
574 			return null;
575 		}
576 		
577 		return ObjectG.getDObject!(Iterator)(cast(GstIterator*) p);
578 	}
579 	
580 	/**
581 	 * Query bin for the current latency using and reconfigures this latency to all the
582 	 * elements with a LATENCY event.
583 	 * This method is typically called on the pipeline when a GST_MESSAGE_LATENCY
584 	 * is posted on the bus.
585 	 * This function simply emits the 'do-latency' signal so any custom latency
586 	 * calculations will be performed.
587 	 * Returns: TRUE if the latency could be queried and reconfigured.
588 	 */
589 	public int recalculateLatency()
590 	{
591 		// gboolean gst_bin_recalculate_latency (GstBin *bin);
592 		return gst_bin_recalculate_latency(gstBin);
593 	}
594 	
595 	/**
596 	 * Recursively looks for elements with an unlinked pad of the given
597 	 * direction within the specified bin and returns an unlinked pad
598 	 * if one is found, or NULL otherwise. If a pad is found, the caller
599 	 * owns a reference to it and should use gst_object_unref() on the
600 	 * pad when it is not needed any longer.
601 	 * Params:
602 	 * direction = whether to look for an unlinked source or sink pad
603 	 * Returns: unlinked pad of the given direction, or NULL. [transfer full]
604 	 */
605 	public Pad findUnlinkedPad(GstPadDirection direction)
606 	{
607 		// GstPad * gst_bin_find_unlinked_pad (GstBin *bin,  GstPadDirection direction);
608 		auto p = gst_bin_find_unlinked_pad(gstBin, direction);
609 		
610 		if(p is null)
611 		{
612 			return null;
613 		}
614 		
615 		return ObjectG.getDObject!(Pad)(cast(GstPad*) p);
616 	}
617 }