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