ext/ogg/gstoggdemux.c: Extra debug output when activating/deactivating chains.

Original commit message from CVS:
* ext/ogg/gstoggdemux.c: (gst_ogg_demux_deactivate_current_chain),
(gst_ogg_demux_activate_chain):
Extra debug output when activating/deactivating chains.

* gst/playback/gstdecodebin.c: (gst_decode_bin_factory_filter),
(is_demuxer_element), (try_to_link_1), (remove_element_chain),
(unlinked):
Remove a queue from our list when it becomes unlinked.
Don't add queues to elements in class 'Demux' if they
can only produce one pad
This commit is contained in:
Jan Schmidt 2005-12-18 15:04:21 +00:00
parent 7811799ce8
commit 0efd7381c4
3 changed files with 123 additions and 44 deletions

View file

@ -1,3 +1,16 @@
2005-12-18 Jan Schmidt <thaytan@mad.scientist.com>
* ext/ogg/gstoggdemux.c: (gst_ogg_demux_deactivate_current_chain),
(gst_ogg_demux_activate_chain):
Extra debug output when activating/deactivating chains.
* gst/playback/gstdecodebin.c: (gst_decode_bin_factory_filter),
(is_demuxer_element), (try_to_link_1), (remove_element_chain),
(unlinked):
Remove a queue from our list when it becomes unlinked.
Don't add queues to elements in class 'Demux' if they
can only produce one pad
2005-12-18 Julien MOUTTE <julien@moutte.net>
* gst-libs/gst/video/gstvideosink.c: (gst_video_sink_base_init),

View file

@ -1378,11 +1378,15 @@ gst_ogg_demux_deactivate_current_chain (GstOggDemux * ogg)
if (chain == NULL)
return TRUE;
GST_DEBUG ("deactivating chain %p", chain);
/* send EOS on all the pads */
for (i = 0; i < chain->streams->len; i++) {
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
gst_pad_push_event (GST_PAD (pad), gst_event_new_eos ());
GST_DEBUG_OBJECT (ogg, "removing pad %" GST_PTR_FORMAT, pad);
gst_element_remove_pad (GST_ELEMENT (ogg), GST_PAD (pad));
}
/* if we cannot seek back to the chain, we can destroy the chain
@ -1409,13 +1413,15 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
gst_ogg_demux_deactivate_current_chain (ogg);
GST_DEBUG ("activating chain");
GST_DEBUG ("activating chain %p", chain);
/* first add the pads */
for (i = 0; i < chain->streams->len; i++) {
GstOggPad *pad;
pad = g_array_index (chain->streams, GstOggPad *, i);
GST_DEBUG_OBJECT (ogg, "adding pad %" GST_PTR_FORMAT, pad);
gst_element_add_pad (GST_ELEMENT (ogg), GST_PAD (pad));
}

View file

@ -69,6 +69,8 @@ struct _GstDecodeBin
guint have_type_id; /* signal id for the typefind element */
gboolean shutting_down; /* stop pluggin if we're shutting down */
GType queue_type; /* store the GType of queues, to aid in recognising them */
};
struct _GstDecodeBinClass
@ -233,7 +235,7 @@ gst_decode_bin_factory_filter (GstPluginFeature * feature,
return FALSE;
klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
/* only demuxers and decoders can play */
/* only demuxers, decoders and parsers can play */
if (strstr (klass, "Demux") == NULL &&
strstr (klass, "Decoder") == NULL && strstr (klass, "Parse") == NULL) {
return FALSE;
@ -603,6 +605,56 @@ many_types:
}
}
/* Decide whether an element is a demuxer based on the
* klass and number/type of src pad templates it has */
static gboolean
is_demuxer_element (GstElement * srcelement)
{
GstElementFactory *srcfactory;
GstElementClass *elemclass;
GList *templates, *walk;
const gchar *klass;
gint potential_src_pads = 0;
srcfactory = gst_element_get_factory (srcelement);
klass = gst_element_factory_get_klass (srcfactory);
/* Can't be a demuxer unless it has Demux in the klass name */
if (!strstr (klass, "Demux"))
return FALSE;
/* Walk the src pad templates and count how many the element
* might produce */
elemclass = GST_ELEMENT_GET_CLASS (srcelement);
walk = templates = gst_element_class_get_pad_template_list (elemclass);
while (walk != NULL) {
GstPadTemplate *templ;
templ = (GstPadTemplate *) walk->data;
if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) {
switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
case GST_PAD_ALWAYS:
case GST_PAD_SOMETIMES:
if (strstr (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "%"))
potential_src_pads += 2; /* Might make multiple pads */
else
potential_src_pads += 1;
break;
case GST_PAD_REQUEST:
potential_src_pads += 2;
break;
}
}
walk = g_list_next (walk);
}
if (potential_src_pads < 2)
return FALSE;
return TRUE;
}
/*
* given a list of element factories, try to link one of the factories
* to the given pad.
@ -615,25 +667,41 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstElement * srcelement, GstPad * pad,
GList * factories)
{
GList *walk;
GstElementFactory *srcfactory = NULL;
GstElement *result = NULL;
gboolean isdemux = FALSE;
const gchar *klass;
GstPad *queuesinkpad = NULL, *queuesrcpad = NULL;
GstElement *queue = NULL;
GstPad *usedsrcpad = pad;
/* Check if the parent of the src pad is a demuxer */
srcfactory = gst_element_get_factory (srcelement);
klass = gst_element_factory_get_klass (srcfactory);
isdemux = !!(strstr (klass, "Demux"));
isdemux = is_demuxer_element (srcelement);
if (isdemux && factories != NULL) {
/* Insert a queue between demuxer and decoder */
GST_DEBUG_OBJECT (decode_bin,
"Element %s is a demuxer, inserting a queue",
GST_OBJECT_NAME (srcelement));
queue = gst_element_factory_make ("queue", NULL);
decode_bin->queue_type = G_OBJECT_TYPE (queue);
g_object_set (G_OBJECT (queue), "max-size-buffers", 0, NULL);
g_object_set (G_OBJECT (queue), "max-size-time", 0LL, NULL);
g_object_set (G_OBJECT (queue), "max-size-bytes", 8192, NULL);
gst_bin_add (GST_BIN (decode_bin), queue);
gst_element_set_state (queue, GST_STATE_READY);
queuesinkpad = gst_element_get_pad (queue, "sink");
usedsrcpad = queuesrcpad = gst_element_get_pad (queue, "src");
g_return_val_if_fail (gst_pad_link (pad, queuesinkpad) == GST_PAD_LINK_OK,
NULL);
}
/* loop over the factories */
for (walk = factories; walk; walk = g_list_next (walk)) {
GstElementFactory *factory = GST_ELEMENT_FACTORY (walk->data);
GstElement *element;
GstElement *queue = NULL;
GstPadLinkReturn ret;
GstPad *sinkpad;
GstPad *usedsrcpad = pad;
GstPad *queuesinkpad = NULL, *queuesrcpad = NULL;
GST_DEBUG_OBJECT (decode_bin, "trying to link %s",
gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
@ -662,24 +730,6 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstElement * srcelement, GstPad * pad,
/* set to ready first so it is ready */
gst_element_set_state (element, GST_STATE_READY);
if (isdemux) {
/* Insert a queue between demuxer and decoder */
GST_DEBUG_OBJECT (decode_bin,
"Element %s is a demuxer, inserting a queue",
GST_OBJECT_NAME (srcelement));
queue = gst_element_factory_make ("queue", NULL);
g_object_set (G_OBJECT (queue), "max-size-buffers", 0, NULL);
g_object_set (G_OBJECT (queue), "max-size-time", 0LL, NULL);
g_object_set (G_OBJECT (queue), "max-size-bytes", 8192, NULL);
gst_bin_add (GST_BIN (decode_bin), queue);
gst_element_set_state (queue, GST_STATE_READY);
queuesinkpad = gst_element_get_pad (queue, "sink");
usedsrcpad = queuesrcpad = gst_element_get_pad (queue, "src");
gst_pad_link (pad, queuesinkpad);
}
if ((ret = gst_pad_link (usedsrcpad, sinkpad)) != GST_PAD_LINK_OK) {
GST_DEBUG_OBJECT (decode_bin, "link failed on pad %s:%s, reason %d",
GST_DEBUG_PAD_NAME (pad), ret);
@ -687,15 +737,7 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstElement * srcelement, GstPad * pad,
gst_object_unref (sinkpad);
/* this element did not work, remove it again and continue trying
* other elements, the element will be disposed. */
if (isdemux)
gst_element_set_state (queue, GST_STATE_NULL);
gst_element_set_state (element, GST_STATE_NULL);
if (isdemux) {
gst_pad_unlink (pad, queuesrcpad);
gst_object_unref (queuesrcpad);
gst_object_unref (queuesinkpad);
gst_bin_remove (GST_BIN (decode_bin), queue);
}
gst_bin_remove (GST_BIN (decode_bin), element);
} else {
@ -704,7 +746,7 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstElement * srcelement, GstPad * pad,
GST_DEBUG_OBJECT (decode_bin, "linked on pad %s:%s",
GST_DEBUG_PAD_NAME (usedsrcpad));
if (isdemux) {
if (queue != NULL) {
decode_bin->queues = g_list_append (decode_bin->queues, queue);
g_signal_connect (G_OBJECT (queue),
"overrun", G_CALLBACK (queue_filled_cb), decode_bin);
@ -713,12 +755,9 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstElement * srcelement, GstPad * pad,
/* The link worked, now figure out what it was that we connected */
/* make sure we catch unlink signals */
sig = g_signal_connect (G_OBJECT (usedsrcpad), "unlinked",
sig = g_signal_connect (G_OBJECT (pad), "unlinked",
G_CALLBACK (unlinked), decode_bin);
/* keep a ref to the signal id so that we can disconnect the signal callback */
g_object_set_data (G_OBJECT (pad), "unlinked_id", GINT_TO_POINTER (sig));
/* 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);
@ -729,8 +768,12 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstElement * srcelement, GstPad * pad,
/* get rid of the sinkpad now */
gst_object_unref (sinkpad);
if (isdemux) {
/* Set the queue to paused and set the pointer to NULL so we don't
* remove it below */
if (queue != NULL) {
gst_element_set_state (queue, GST_STATE_PAUSED);
queue = NULL;
gst_object_unref (queuesrcpad);
gst_object_unref (queuesinkpad);
}
@ -740,6 +783,14 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstElement * srcelement, GstPad * pad,
}
}
done:
if (queue != NULL) {
/* We didn't successfully connect to the queue */
gst_pad_unlink (pad, queuesrcpad);
gst_element_set_state (queue, GST_STATE_NULL);
gst_object_unref (queuesrcpad);
gst_object_unref (queuesinkpad);
gst_bin_remove (GST_BIN (decode_bin), queue);
}
return result;
}
@ -801,6 +852,12 @@ remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
GST_OBJECT_PARENT (elem) != GST_OBJECT (decode_bin))
elem = GST_ELEMENT (GST_OBJECT_PARENT (elem));
if (G_OBJECT_TYPE (elem) == decode_bin->queue_type) {
GST_DEBUG_OBJECT (decode_bin,
"Encountered demuxer output queue while removing element chain");
decode_bin->queues = g_list_remove (decode_bin->queues, elem);
}
GST_DEBUG_OBJECT (decode_bin, "%s:%s", GST_DEBUG_PAD_NAME (pad));
int_links = gst_pad_get_internal_links (pad);
@ -1010,15 +1067,18 @@ unlinked (GstPad * pad, GstPad * peerpad, GstDecodeBin * decode_bin)
if (!is_our_kid (peer, decode_bin))
goto exit;
GST_DEBUG_OBJECT (decode_bin, "pad %s:%s removal while alive - chained?",
GST_DEBUG_PAD_NAME (pad));
/* remove all elements linked to the peerpad */
remove_element_chain (decode_bin, peerpad);
/* if an element removes two pads, then we don't want this twice */
/* FIXME: decode_bin->dynamics doesn't contain a list of GstElements, it
* has GstDynamic structures */
if (g_list_find (decode_bin->dynamics, element) != NULL)
goto exit;
GST_DEBUG_OBJECT (decode_bin, "pad removal while alive - chained?");
dyn = dynamic_create (element, decode_bin);
/* and add this element to the dynamic elements */
decode_bin->dynamics = g_list_prepend (decode_bin->dynamics, dyn);