mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
gst/playback/: Add some debug info to decodebin, update README
Original commit message from CVS: * gst/playback/README: * gst/playback/gstdecodebin.c: (gst_decode_bin_factory_filter), (gst_decode_bin_init), (find_compatibles), (close_pad_link), (try_to_link_1), (no_more_pads), (close_link), (type_found): Add some debug info to decodebin, update README
This commit is contained in:
parent
586f6f31da
commit
f92e880040
3 changed files with 180 additions and 36 deletions
|
@ -1,3 +1,11 @@
|
|||
2004-10-01 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/playback/README:
|
||||
* gst/playback/gstdecodebin.c: (gst_decode_bin_factory_filter),
|
||||
(gst_decode_bin_init), (find_compatibles), (close_pad_link),
|
||||
(try_to_link_1), (no_more_pads), (close_link), (type_found):
|
||||
Add some debug info to decodebin, update README
|
||||
|
||||
2004-10-01 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||
|
||||
* ext/dvdnav/dvdnavsrc.c: (dvdnav_handle_navigation_event):
|
||||
|
|
|
@ -7,9 +7,7 @@ decoderbin:
|
|||
|
||||
TODO
|
||||
- reuse of decoderbin, cleanup in READY state
|
||||
- debugging
|
||||
- threading after demuxing?
|
||||
- better factory selection, based on Demuxer/Decoder types and ranks.
|
||||
- error handling
|
||||
|
||||
baseplaybin:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
* Copyright (C) <2004> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
|
@ -51,26 +51,28 @@ typedef struct _GstDecodeBinClass GstDecodeBinClass;
|
|||
|
||||
struct _GstDecodeBin
|
||||
{
|
||||
GstBin bin;
|
||||
GstBin bin; /* we extend GstBin */
|
||||
|
||||
GstElement *typefind;
|
||||
GstElement *typefind; /* this holds the typefind object */
|
||||
|
||||
gboolean threaded;
|
||||
GList *dynamics;
|
||||
gboolean threaded; /* indicating threaded execution is desired */
|
||||
GList *dynamics; /* list of dynamic connections */
|
||||
|
||||
GList *factories;
|
||||
GList *factories; /* factories we can use for selecting elements */
|
||||
gint numpads;
|
||||
|
||||
GList *elements;
|
||||
GList *elements; /* elements we added in autoplugging */
|
||||
|
||||
guint have_type_id;
|
||||
guint have_type_id; /* signal id for the typefind element */
|
||||
};
|
||||
|
||||
struct _GstDecodeBinClass
|
||||
{
|
||||
GstBinClass parent_class;
|
||||
|
||||
/* signal we fire when a new pad has been decoded into raw audio/video */
|
||||
void (*new_decoded_pad) (GstElement * element, GstPad * pad, gboolean last);
|
||||
/* signal fired when we found a pad that we cannot decode */
|
||||
void (*unknown_type) (GstElement * element, GstCaps * caps);
|
||||
};
|
||||
|
||||
|
@ -89,12 +91,14 @@ enum
|
|||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
/* this structure is created for all dynamic pads that could get created
|
||||
* at runtime */
|
||||
typedef struct
|
||||
{
|
||||
gint np_sig_id;
|
||||
gint nmp_sig_id;
|
||||
GstElement *element;
|
||||
GstDecodeBin *decode_bin;
|
||||
gint np_sig_id; /* signal id of new_pad */
|
||||
gint nmp_sig_id; /* signal id of no_more_pads */
|
||||
GstElement *element; /* the element sending the signal */
|
||||
GstDecodeBin *decode_bin; /* pointer to ourself */
|
||||
}
|
||||
GstDynamic;
|
||||
|
||||
|
@ -196,12 +200,19 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_decode_bin_change_state);
|
||||
}
|
||||
|
||||
/* check if the bin is dynamic.
|
||||
*
|
||||
* If there are no outstanding dynamic connections, the bin is
|
||||
* considered to be non-dynamic.
|
||||
*/
|
||||
static gboolean
|
||||
gst_decode_bin_is_dynamic (GstDecodeBin * decode_bin)
|
||||
{
|
||||
return decode_bin->dynamics != NULL;
|
||||
}
|
||||
|
||||
/* the filter function for selecting the elements we can use in
|
||||
* autoplugging */
|
||||
static gboolean
|
||||
gst_decode_bin_factory_filter (GstPluginFeature * feature,
|
||||
GstDecodeBin * decode_bin)
|
||||
|
@ -209,14 +220,17 @@ gst_decode_bin_factory_filter (GstPluginFeature * feature,
|
|||
guint rank;
|
||||
const gchar *klass;
|
||||
|
||||
/* we only care about element factories */
|
||||
if (!GST_IS_ELEMENT_FACTORY (feature))
|
||||
return FALSE;
|
||||
|
||||
klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
|
||||
/* only demuxers and decoders can play */
|
||||
if (strstr (klass, "Demux") == NULL && strstr (klass, "Decoder") == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* only select elements with autoplugging rank */
|
||||
rank = gst_plugin_feature_get_rank (feature);
|
||||
if (rank < GST_RANK_MARGINAL)
|
||||
return FALSE;
|
||||
|
@ -224,6 +238,7 @@ gst_decode_bin_factory_filter (GstPluginFeature * feature,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* function used to sort element features */
|
||||
static gint
|
||||
compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
|
||||
{
|
||||
|
@ -241,24 +256,33 @@ gst_decode_bin_init (GstDecodeBin * decode_bin)
|
|||
{
|
||||
GList *factories;
|
||||
|
||||
/* first filter out the interesting element factories */
|
||||
factories = gst_registry_pool_feature_filter (
|
||||
(GstPluginFeatureFilter) gst_decode_bin_factory_filter,
|
||||
FALSE, decode_bin);
|
||||
|
||||
/* sort them according to their ranks */
|
||||
decode_bin->factories = g_list_sort (factories, (GCompareFunc) compare_ranks);
|
||||
/* do some debugging */
|
||||
g_list_foreach (decode_bin->factories, (GFunc) print_feature, NULL);
|
||||
|
||||
/* we create the typefind element only once */
|
||||
decode_bin->typefind = gst_element_factory_make ("typefind", "typefind");
|
||||
if (!decode_bin->typefind) {
|
||||
g_warning ("can't find typefind element");
|
||||
}
|
||||
gst_bin_add (GST_BIN (decode_bin), decode_bin->typefind);
|
||||
gst_element_add_ghost_pad (GST_ELEMENT (decode_bin),
|
||||
gst_element_get_pad (decode_bin->typefind, "sink"), "sink");
|
||||
g_warning ("can't find typefind element, decodebin will not work");
|
||||
} else {
|
||||
/* add the typefind element */
|
||||
gst_bin_add (GST_BIN (decode_bin), decode_bin->typefind);
|
||||
/* ghost the sink pad to ourself */
|
||||
gst_element_add_ghost_pad (GST_ELEMENT (decode_bin),
|
||||
gst_element_get_pad (decode_bin->typefind, "sink"), "sink");
|
||||
|
||||
decode_bin->have_type_id =
|
||||
g_signal_connect (G_OBJECT (decode_bin->typefind), "have_type",
|
||||
G_CALLBACK (type_found), decode_bin);
|
||||
/* connect a signal to find out when the typefind element found
|
||||
* a type */
|
||||
decode_bin->have_type_id =
|
||||
g_signal_connect (G_OBJECT (decode_bin->typefind), "have_type",
|
||||
G_CALLBACK (type_found), decode_bin);
|
||||
}
|
||||
|
||||
decode_bin->dynamics = NULL;
|
||||
}
|
||||
|
@ -291,28 +315,37 @@ gst_decode_bin_dispose (GObject * object)
|
|||
}
|
||||
}
|
||||
|
||||
/* this function runs through the element factories and returns a list
|
||||
* of all elements that are able to sink the given caps
|
||||
*/
|
||||
static GList *
|
||||
find_compatibles (GstDecodeBin * decode_bin, const GstCaps * caps)
|
||||
{
|
||||
GList *factories;
|
||||
GList *to_try = NULL;
|
||||
|
||||
/* loop over all the factories */
|
||||
for (factories = decode_bin->factories; factories;
|
||||
factories = g_list_next (factories)) {
|
||||
GstElementFactory *factory = GST_ELEMENT_FACTORY (factories->data);
|
||||
const GList *templates;
|
||||
GList *walk;
|
||||
|
||||
/* get the templates from the element factory */
|
||||
templates = gst_element_factory_get_pad_templates (factory);
|
||||
for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
|
||||
GstPadTemplate *templ = GST_PAD_TEMPLATE (walk->data);
|
||||
|
||||
/* we only care about the sink templates */
|
||||
if (templ->direction == GST_PAD_SINK) {
|
||||
GstCaps *intersect;
|
||||
|
||||
/* try to intersect the caps with the caps of the template */
|
||||
intersect =
|
||||
gst_caps_intersect (caps, gst_pad_template_get_caps (templ));
|
||||
/* check if the intersection is empty */
|
||||
if (!gst_caps_is_empty (intersect)) {
|
||||
/* non empty intersection, we can use this element */
|
||||
to_try = g_list_append (to_try, factory);
|
||||
}
|
||||
gst_caps_free (intersect);
|
||||
|
@ -322,6 +355,15 @@ find_compatibles (GstDecodeBin * decode_bin, const GstCaps * caps)
|
|||
return to_try;
|
||||
}
|
||||
|
||||
/* given a pad and a caps from an element, find the list of elements
|
||||
* that could connect to the pad
|
||||
*
|
||||
* If the pad has a raw format, this function will create a ghostpad
|
||||
* for the pad onto the decodebin.
|
||||
*
|
||||
* If no compatible elements could be found, this function will signal
|
||||
* the unknown_type signal.
|
||||
*/
|
||||
static void
|
||||
close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps,
|
||||
GstDecodeBin * decode_bin)
|
||||
|
@ -330,29 +372,34 @@ close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps,
|
|||
GstStructure *structure;
|
||||
const gchar *mimetype;
|
||||
|
||||
/* the caps is empty, this means the pad has no type, we can only
|
||||
* decide to fire the unknown_type signal. */
|
||||
if (gst_caps_is_empty (caps)) {
|
||||
g_signal_emit (G_OBJECT (decode_bin),
|
||||
gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, caps);
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME, iterate over more structures? */
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
mimetype = gst_structure_get_name (structure);
|
||||
|
||||
/* first see if this is raw */
|
||||
/* first see if this is raw. If the type is raw, we can
|
||||
* create a ghostpad for this pad. */
|
||||
if (g_str_has_prefix (mimetype, "video/x-raw") ||
|
||||
g_str_has_prefix (mimetype, "audio/x-raw")) {
|
||||
gchar *padname;
|
||||
GstPad *ghost;
|
||||
gboolean dynamic;
|
||||
|
||||
/* make a unique name for this new pad */
|
||||
padname = g_strdup_printf ("src%d", decode_bin->numpads);
|
||||
decode_bin->numpads++;
|
||||
|
||||
gst_element_add_ghost_pad (GST_ELEMENT (decode_bin), pad, padname);
|
||||
|
||||
ghost = gst_element_get_pad (GST_ELEMENT (decode_bin), padname);
|
||||
/* make it a ghostpad */
|
||||
ghost = gst_element_add_ghost_pad (GST_ELEMENT (decode_bin), pad, padname);
|
||||
|
||||
/* see if any more pending dynamic connections exist */
|
||||
dynamic = gst_decode_bin_is_dynamic (decode_bin);
|
||||
|
||||
/* our own signal with an extra flag that this is the only pad */
|
||||
|
@ -363,85 +410,128 @@ close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps,
|
|||
return;
|
||||
}
|
||||
|
||||
/* then continue plugging */
|
||||
/* then continue plugging, first find all compatible elements */
|
||||
to_try = find_compatibles (decode_bin, caps);
|
||||
if (to_try == NULL) {
|
||||
/* no compatible elements, fire the unknown_type signal, we cannot go
|
||||
* on */
|
||||
g_signal_emit (G_OBJECT (decode_bin),
|
||||
gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, caps);
|
||||
return;
|
||||
}
|
||||
|
||||
/* now try to link the elements in the to_try list to the pad */
|
||||
try_to_link_1 (decode_bin, pad, to_try);
|
||||
}
|
||||
|
||||
/* given a list of element factories, try to link one of the factories
|
||||
* to the given pad */
|
||||
static GstElement *
|
||||
try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad, GList * factories)
|
||||
{
|
||||
GList *walk;
|
||||
|
||||
/* loop over the factories */
|
||||
for (walk = factories; walk; walk = g_list_next (walk)) {
|
||||
GstElementFactory *factory = GST_ELEMENT_FACTORY (walk->data);
|
||||
GstElement *element;
|
||||
gboolean ret;
|
||||
|
||||
GST_DEBUG ("trying to link %s",
|
||||
GST_DEBUG_OBJECT (decode_bin, "trying to link %s",
|
||||
gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
|
||||
|
||||
/* make an element from the factory first */
|
||||
element = gst_element_factory_create (factory, NULL);
|
||||
if (element == NULL)
|
||||
if (element == NULL) {
|
||||
/* hmm, strange */
|
||||
GST_WARNING_OBJECT (decode_bin, "could not create an element from %s",
|
||||
gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
|
||||
continue;
|
||||
}
|
||||
|
||||
GST_DEBUG ("adding %s", gst_element_get_name (element));
|
||||
/* now add the element to the bin first */
|
||||
GST_DEBUG_OBJECT (decode_bin, "adding %s", gst_element_get_name (element));
|
||||
gst_bin_add (GST_BIN (decode_bin), element);
|
||||
/* keep out own list of elements */
|
||||
decode_bin->elements = g_list_prepend (decode_bin->elements, element);
|
||||
|
||||
/* try to link the given pad to a sinkpad */
|
||||
/* FIXME, find the sinkpad by looping over the pads instead of
|
||||
* looking it up by name */
|
||||
ret = gst_pad_link (pad, gst_element_get_pad (element, "sink"));
|
||||
if (ret) {
|
||||
const gchar *klass;
|
||||
GstElementFactory *factory;
|
||||
|
||||
/* The link worked, now figure out what it was that we connected */
|
||||
factory = gst_element_get_factory (element);
|
||||
klass = gst_element_factory_get_klass (factory);
|
||||
/* check if we can use threads */
|
||||
if (decode_bin->threaded) {
|
||||
if (strstr (klass, "Demux") != NULL) {
|
||||
/* FIXME, do something with threads here */
|
||||
}
|
||||
}
|
||||
|
||||
/* now that we added the element we can try to continue autoplugging
|
||||
* on it until we have a raw type */
|
||||
close_link (element, decode_bin);
|
||||
/* change the state of the element to that of the parent */
|
||||
gst_element_sync_state_with_parent (element);
|
||||
return element;
|
||||
} else {
|
||||
/* this element did not work, remove it again and continue trying
|
||||
* other elements */
|
||||
gst_bin_remove (GST_BIN (decode_bin), element);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This function will be called when a dynamic pad is created on an element.
|
||||
* We try to continue autoplugging on this new pad. */
|
||||
static void
|
||||
new_pad (GstElement * element, GstPad * pad, GstDynamic * dynamic)
|
||||
{
|
||||
close_pad_link (element, pad, gst_pad_get_caps (pad), dynamic->decode_bin);
|
||||
}
|
||||
|
||||
/* this signal is fired when an element signals the no_more_pads signal.
|
||||
* This means that the element will not generate more dynamic pads and
|
||||
* we can remove the element from the list of dynamic elements. When we
|
||||
* have no more dynamic elements in the pipeline, we can fire a no_more_pads
|
||||
* signal ourselves. */
|
||||
static void
|
||||
no_more_pads (GstElement * element, GstDynamic * dynamic)
|
||||
{
|
||||
GstDecodeBin *decode_bin = dynamic->decode_bin;
|
||||
|
||||
GST_DEBUG ("decodebin: no more pads");
|
||||
GST_DEBUG_OBJECT (decode_bin, "no more pads on element %s",
|
||||
gst_element_get_name (element));
|
||||
|
||||
/* disconnect signals */
|
||||
g_signal_handler_disconnect (G_OBJECT (dynamic->element), dynamic->np_sig_id);
|
||||
g_signal_handler_disconnect (G_OBJECT (dynamic->element),
|
||||
dynamic->nmp_sig_id);
|
||||
|
||||
/* remove the element from the list of dynamic elements */
|
||||
decode_bin->dynamics = g_list_remove (decode_bin->dynamics, dynamic);
|
||||
g_free (dynamic);
|
||||
|
||||
if (decode_bin->dynamics == NULL)
|
||||
/* if we have no more dynamic elements, we have no change of creating
|
||||
* more pads, so we fire the no_more_pads signal */
|
||||
if (decode_bin->dynamics == NULL) {
|
||||
GST_DEBUG_OBJECT (decode_bin,
|
||||
"no more dynamic elements, signaling no_more_pads");
|
||||
gst_element_no_more_pads (GST_ELEMENT (decode_bin));
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (decode_bin, "we have more dynamic elements");
|
||||
}
|
||||
}
|
||||
|
||||
/* this function inspects the given element and tries to connect something
|
||||
* on the srcpads. If there are dynamic pads, it sets up a signal handler to
|
||||
* continue autoplugging when they become available */
|
||||
static void
|
||||
close_link (GstElement * element, GstDecodeBin * decode_bin)
|
||||
{
|
||||
|
@ -449,43 +539,74 @@ close_link (GstElement * element, GstDecodeBin * decode_bin)
|
|||
gboolean dynamic = FALSE;
|
||||
GList *to_connect = NULL;
|
||||
|
||||
GST_DEBUG_OBJECT (decode_bin, "closing links with element %s",
|
||||
gst_element_get_name (element));
|
||||
|
||||
/* loop over all the padtemplates */
|
||||
for (pads = gst_element_get_pad_template_list (element); pads;
|
||||
pads = g_list_next (pads)) {
|
||||
GstPadTemplate *templ = GST_PAD_TEMPLATE (pads->data);
|
||||
const gchar *templ_name;
|
||||
|
||||
/* we are only interested in source pads */
|
||||
if (GST_PAD_TEMPLATE_DIRECTION (templ) != GST_PAD_SRC)
|
||||
continue;
|
||||
|
||||
templ_name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);
|
||||
GST_DEBUG_OBJECT (decode_bin, "got a source pad template %s", templ_name);
|
||||
|
||||
/* figure out what kind of pad this is */
|
||||
switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
|
||||
case GST_PAD_ALWAYS:
|
||||
{
|
||||
GstPad *pad = gst_element_get_pad (element,
|
||||
GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
|
||||
/* get the pad that we need to autoplug */
|
||||
GstPad *pad = gst_element_get_pad (element, templ_name);
|
||||
|
||||
if (pad) {
|
||||
GST_DEBUG_OBJECT (decode_bin, "got the pad for always template %s",
|
||||
templ_name);
|
||||
/* here is the pad, we need to autoplug it */
|
||||
to_connect = g_list_prepend (to_connect, pad);
|
||||
} else {
|
||||
/* strange, pad is marked as always but it's not
|
||||
* there. Fix the element */
|
||||
GST_WARNING_OBJECT (decode_bin,
|
||||
"could not get the pad for always template %s", templ_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GST_PAD_SOMETIMES:
|
||||
{
|
||||
GstPad *pad = gst_element_get_pad (element,
|
||||
GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
|
||||
/* try to get the pad to see if it is already created or
|
||||
* not */
|
||||
GstPad *pad = gst_element_get_pad (element, templ_name);
|
||||
|
||||
if (pad) {
|
||||
GST_DEBUG_OBJECT (decode_bin, "got the pad for sometimes template %s",
|
||||
templ_name);
|
||||
/* the pad is created, we need to autoplug it */
|
||||
to_connect = g_list_prepend (to_connect, pad);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (decode_bin,
|
||||
"did not get the sometimes pad of template %s", templ_name);
|
||||
/* we have an element that will create dynamic pads */
|
||||
dynamic = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GST_PAD_REQUEST:
|
||||
/* ignore request pads */
|
||||
GST_DEBUG_OBJECT (decode_bin, "ignoring request padtemplate %s",
|
||||
templ_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dynamic) {
|
||||
GstDynamic *dyn;
|
||||
|
||||
GST_DEBUG_OBJECT (decode_bin, "got a dynamic element here");
|
||||
/* ok, this element has dynamic pads, set up the signal handlers to be
|
||||
* notified of them */
|
||||
dyn = g_new0 (GstDynamic, 1);
|
||||
dyn->np_sig_id = g_signal_connect (G_OBJECT (element), "new-pad",
|
||||
G_CALLBACK (new_pad), dyn);
|
||||
|
@ -494,29 +615,46 @@ close_link (GstElement * element, GstDecodeBin * decode_bin)
|
|||
dyn->element = element;
|
||||
dyn->decode_bin = decode_bin;
|
||||
|
||||
/* and add this element to the dynamic elements */
|
||||
decode_bin->dynamics = g_list_prepend (decode_bin->dynamics, dyn);
|
||||
}
|
||||
|
||||
/* now loop over all the pads we need to connect */
|
||||
for (pads = to_connect; pads; pads = g_list_next (pads)) {
|
||||
GstPad *pad = GST_PAD (pads->data);
|
||||
|
||||
GST_DEBUG_OBJECT (decode_bin, "closing pad link for %s",
|
||||
gst_pad_get_name (pad));
|
||||
|
||||
/* continue autoplugging on the pads */
|
||||
close_pad_link (element, pad, gst_pad_get_caps (pad), decode_bin);
|
||||
}
|
||||
g_list_free (to_connect);
|
||||
}
|
||||
|
||||
/* this is the signal handler for the typefind element have_type signal.
|
||||
* It tries to continue autoplugging on the typefind src pad */
|
||||
static void
|
||||
type_found (GstElement * typefind, guint probability, GstCaps * caps,
|
||||
GstDecodeBin * decode_bin)
|
||||
{
|
||||
gboolean dynamic;
|
||||
|
||||
GST_DEBUG_OBJECT (decode_bin, "typefind found caps %" GST_PTR_FORMAT, caps);
|
||||
|
||||
/* autoplug the new pad with the caps that the signal gave us */
|
||||
close_pad_link (typefind, gst_element_get_pad (typefind, "src"), caps,
|
||||
decode_bin);
|
||||
|
||||
dynamic = gst_decode_bin_is_dynamic (decode_bin);
|
||||
if (dynamic == FALSE) {
|
||||
GST_DEBUG_OBJECT (decode_bin, "we have no dynamic elements anymore");
|
||||
/* if we have no dynamic elements, we know that no new pads
|
||||
* will be created and we can signal out no_more_pads signal */
|
||||
gst_element_no_more_pads (GST_ELEMENT (decode_bin));
|
||||
} else {
|
||||
/* more dynamic elements exist that could create new pads */
|
||||
GST_DEBUG_OBJECT (decode_bin, "we more dynamic elements");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue