mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-29 19:50:40 +00:00
decodebin: set the decode pad target before setting elements to PAUSED
Otherwise caps and context queries will disappear into nothing and therefore fail. With autoplug-query now actually working, users (such as playbin) can proxy these queries to the selected video sink and be able to select an more appropriate configuration. https://bugzilla.gnome.org/show_bug.cgi?id=731204
This commit is contained in:
parent
df0d5aa4d5
commit
d50b713f44
1 changed files with 23 additions and 66 deletions
|
@ -1484,7 +1484,8 @@ decode_pad_set_target (GstDecodePad * dpad, GstPad * target)
|
||||||
* - get list of factories to autoplug.
|
* - get list of factories to autoplug.
|
||||||
* - continue autoplugging to one of the factories.
|
* - continue autoplugging to one of the factories.
|
||||||
*/
|
*/
|
||||||
static void
|
/* returns whether to expose the pad */
|
||||||
|
static gboolean
|
||||||
analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
GstCaps * caps, GstDecodeChain * chain)
|
GstCaps * caps, GstDecodeChain * chain)
|
||||||
{
|
{
|
||||||
|
@ -1504,12 +1505,12 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
&& src != ((GstDecodeElement *) chain->elements->data)->element
|
&& src != ((GstDecodeElement *) chain->elements->data)->element
|
||||||
&& src != ((GstDecodeElement *) chain->elements->data)->capsfilter) {
|
&& src != ((GstDecodeElement *) chain->elements->data)->capsfilter) {
|
||||||
GST_ERROR_OBJECT (dbin, "New pad from not the last element in this chain");
|
GST_ERROR_OBJECT (dbin, "New pad from not the last element in this chain");
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chain->endpad) {
|
if (chain->endpad) {
|
||||||
GST_ERROR_OBJECT (dbin, "New pad in a chain that is already complete");
|
GST_ERROR_OBJECT (dbin, "New pad in a chain that is already complete");
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chain->demuxer) {
|
if (chain->demuxer) {
|
||||||
|
@ -1532,7 +1533,7 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
CHAIN_MUTEX_UNLOCK (oldchain);
|
CHAIN_MUTEX_UNLOCK (oldchain);
|
||||||
if (!group) {
|
if (!group) {
|
||||||
GST_WARNING_OBJECT (dbin, "No current group");
|
GST_WARNING_OBJECT (dbin, "No current group");
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is not a dynamic pad demuxer, we're no-more-pads
|
/* If this is not a dynamic pad demuxer, we're no-more-pads
|
||||||
|
@ -1786,15 +1787,15 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
|
||||||
|
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
return;
|
return FALSE;
|
||||||
|
|
||||||
expose_pad:
|
expose_pad:
|
||||||
{
|
{
|
||||||
GST_LOG_OBJECT (dbin, "Pad is final. autoplug-continue:%d", apcontinue);
|
GST_LOG_OBJECT (dbin, "Pad is final and should expose the pad. "
|
||||||
expose_pad (dbin, src, dpad, pad, caps, chain);
|
"autoplug-continue:%d", apcontinue);
|
||||||
gst_object_unref (dpad);
|
gst_object_unref (dpad);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
discarded_type:
|
discarded_type:
|
||||||
|
@ -1814,7 +1815,7 @@ discarded_type:
|
||||||
EXPOSE_UNLOCK (dbin);
|
EXPOSE_UNLOCK (dbin);
|
||||||
do_async_done (dbin);
|
do_async_done (dbin);
|
||||||
|
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
unknown_type:
|
unknown_type:
|
||||||
|
@ -1848,7 +1849,7 @@ unknown_type:
|
||||||
}
|
}
|
||||||
do_async_done (dbin);
|
do_async_done (dbin);
|
||||||
}
|
}
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
non_fixed:
|
non_fixed:
|
||||||
{
|
{
|
||||||
|
@ -1887,7 +1888,7 @@ setup_caps_delay:
|
||||||
if (caps)
|
if (caps)
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1984,39 +1985,6 @@ error_message_to_string (GstMessage * msg)
|
||||||
return full_message;
|
return full_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We consider elements as "simple demuxer" when they are a demuxer
|
|
||||||
* with one and only one ALWAYS source pad.
|
|
||||||
*/
|
|
||||||
static gboolean
|
|
||||||
is_simple_demuxer_factory (GstElementFactory * factory)
|
|
||||||
{
|
|
||||||
if (strstr (gst_element_factory_get_metadata (factory,
|
|
||||||
GST_ELEMENT_METADATA_KLASS), "Demuxer")) {
|
|
||||||
const GList *tmp;
|
|
||||||
gint num_alway_srcpads = 0;
|
|
||||||
|
|
||||||
for (tmp = gst_element_factory_get_static_pad_templates (factory);
|
|
||||||
tmp; tmp = tmp->next) {
|
|
||||||
GstStaticPadTemplate *template = tmp->data;
|
|
||||||
|
|
||||||
if (template->direction == GST_PAD_SRC) {
|
|
||||||
if (template->presence == GST_PAD_ALWAYS) {
|
|
||||||
if (num_alway_srcpads >= 0)
|
|
||||||
num_alway_srcpads++;
|
|
||||||
} else {
|
|
||||||
num_alway_srcpads = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_alway_srcpads == 1)
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstPadProbeReturn
|
static GstPadProbeReturn
|
||||||
demuxer_source_pad_probe (GstPad * pad, GstPadProbeInfo * info,
|
demuxer_source_pad_probe (GstPad * pad, GstPadProbeInfo * info,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
|
@ -2122,7 +2090,8 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
gboolean subtitle;
|
gboolean subtitle;
|
||||||
GList *to_connect = NULL;
|
GList *to_connect = NULL;
|
||||||
gboolean is_parser_converter = FALSE, is_simple_demuxer = FALSE;
|
gboolean is_parser_converter = FALSE;
|
||||||
|
gboolean to_expose = FALSE;
|
||||||
|
|
||||||
/* Set dpad target to pad again, it might've been unset
|
/* Set dpad target to pad again, it might've been unset
|
||||||
* below but we came back here because something failed
|
* below but we came back here because something failed
|
||||||
|
@ -2190,7 +2159,6 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
||||||
*/
|
*/
|
||||||
is_parser_converter = strstr (gst_element_factory_get_metadata (factory,
|
is_parser_converter = strstr (gst_element_factory_get_metadata (factory,
|
||||||
GST_ELEMENT_METADATA_KLASS), "Parser") != NULL;
|
GST_ELEMENT_METADATA_KLASS), "Parser") != NULL;
|
||||||
is_simple_demuxer = is_simple_demuxer_factory (factory);
|
|
||||||
|
|
||||||
if (is_parser_converter) {
|
if (is_parser_converter) {
|
||||||
gboolean skip = FALSE;
|
gboolean skip = FALSE;
|
||||||
|
@ -2447,14 +2415,15 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
||||||
/* link this element further */
|
/* link this element further */
|
||||||
to_connect = connect_element (dbin, delem, chain);
|
to_connect = connect_element (dbin, delem, chain);
|
||||||
|
|
||||||
if ((is_simple_demuxer || is_parser_converter) && to_connect) {
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
for (l = to_connect; l; l = g_list_next (l)) {
|
for (l = to_connect; l; l = g_list_next (l)) {
|
||||||
GstPad *opad = GST_PAD_CAST (l->data);
|
GstPad *opad = GST_PAD_CAST (l->data);
|
||||||
GstCaps *ocaps;
|
GstCaps *ocaps;
|
||||||
|
|
||||||
ocaps = get_pad_caps (opad);
|
ocaps = get_pad_caps (opad);
|
||||||
analyze_new_pad (dbin, delem->element, opad, ocaps, chain);
|
to_expose = analyze_new_pad (dbin, delem->element, opad, ocaps, chain);
|
||||||
|
|
||||||
if (ocaps)
|
if (ocaps)
|
||||||
gst_caps_unref (ocaps);
|
gst_caps_unref (ocaps);
|
||||||
|
|
||||||
|
@ -2573,22 +2542,8 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
||||||
SUBTITLE_UNLOCK (dbin);
|
SUBTITLE_UNLOCK (dbin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to_connect) {
|
if (to_expose)
|
||||||
GList *l;
|
expose_pad (dbin, delem->element, dpad, pad, caps, chain);
|
||||||
for (l = to_connect; l; l = g_list_next (l)) {
|
|
||||||
GstPad *opad = GST_PAD_CAST (l->data);
|
|
||||||
GstCaps *ocaps;
|
|
||||||
|
|
||||||
ocaps = get_pad_caps (opad);
|
|
||||||
analyze_new_pad (dbin, delem->element, opad, ocaps, chain);
|
|
||||||
if (ocaps)
|
|
||||||
gst_caps_unref (ocaps);
|
|
||||||
|
|
||||||
gst_object_unref (opad);
|
|
||||||
}
|
|
||||||
g_list_free (to_connect);
|
|
||||||
to_connect = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -2836,7 +2791,8 @@ type_found (GstElement * typefind, guint probability,
|
||||||
* be held (if called from a proxied setcaps), so grab it anyway */
|
* be held (if called from a proxied setcaps), so grab it anyway */
|
||||||
GST_PAD_STREAM_LOCK (sink_pad);
|
GST_PAD_STREAM_LOCK (sink_pad);
|
||||||
decode_bin->decode_chain = gst_decode_chain_new (decode_bin, NULL, pad);
|
decode_bin->decode_chain = gst_decode_chain_new (decode_bin, NULL, pad);
|
||||||
analyze_new_pad (decode_bin, typefind, pad, caps, decode_bin->decode_chain);
|
if (analyze_new_pad (decode_bin, typefind, pad, caps, decode_bin->decode_chain))
|
||||||
|
expose_pad (decode_bin, typefind, decode_bin->decode_chain->current_pad, pad, caps, decode_bin->decode_chain);
|
||||||
GST_PAD_STREAM_UNLOCK (sink_pad);
|
GST_PAD_STREAM_UNLOCK (sink_pad);
|
||||||
|
|
||||||
gst_object_unref (sink_pad);
|
gst_object_unref (sink_pad);
|
||||||
|
@ -2889,7 +2845,8 @@ pad_added_cb (GstElement * element, GstPad * pad, GstDecodeChain * chain)
|
||||||
GST_DEBUG_OBJECT (pad, "pad added, chain:%p", chain);
|
GST_DEBUG_OBJECT (pad, "pad added, chain:%p", chain);
|
||||||
|
|
||||||
caps = get_pad_caps (pad);
|
caps = get_pad_caps (pad);
|
||||||
analyze_new_pad (dbin, element, pad, caps, chain);
|
if (analyze_new_pad (dbin, element, pad, caps, chain))
|
||||||
|
expose_pad (dbin, element, chain->current_pad, pad, caps, chain);
|
||||||
if (caps)
|
if (caps)
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue