playbin: Refactor autoplug-query handling

We now only check sinks and factories of the corresponding media
type. It doesn't make sense to pass audio/subtitle caps to a video
decoder.
This commit is contained in:
Sebastian Dröge 2013-05-28 13:08:00 +02:00
parent d366613401
commit e5064ee723
2 changed files with 161 additions and 142 deletions

View file

@ -4251,40 +4251,27 @@ gst_decode_pad_query (GstPad * pad, GstObject * parent, GstQuery * query)
gboolean ret = FALSE; gboolean ret = FALSE;
CHAIN_MUTEX_LOCK (dpad->chain); CHAIN_MUTEX_LOCK (dpad->chain);
if (!dpad->exposed && !dpad->chain->deadend) { if (!dpad->exposed && !dpad->chain->deadend && dpad->chain->elements) {
GstDecodeElement *delem = GstDecodeElement *delem = dpad->chain->elements->data;
(dpad->chain->elements ? dpad->chain->elements->data : NULL);
if (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION) {
g_print ("huh\n");
g_assert_not_reached ();
}
ret = FALSE; ret = FALSE;
GST_DEBUG_OBJECT (dpad->dbin, GST_DEBUG_OBJECT (dpad->dbin,
"calling autoplug-query for %s (element %s): %" GST_PTR_FORMAT, "calling autoplug-query for %s (element %s): %" GST_PTR_FORMAT,
GST_PAD_NAME (dpad), delem ? GST_ELEMENT_NAME (delem->element) : NULL, GST_PAD_NAME (dpad), GST_ELEMENT_NAME (delem->element), query);
query);
g_signal_emit (G_OBJECT (dpad->dbin), g_signal_emit (G_OBJECT (dpad->dbin),
gst_decode_bin_signals[SIGNAL_AUTOPLUG_QUERY], 0, dpad, delem->element, gst_decode_bin_signals[SIGNAL_AUTOPLUG_QUERY], 0, dpad, delem->element,
query, &ret); query, &ret);
if (ret)
GST_DEBUG_OBJECT (dpad->dbin,
"autoplug-query returned %d: %" GST_PTR_FORMAT, ret, query);
else
GST_DEBUG_OBJECT (dpad->dbin, "autoplug-query returned %d", ret); GST_DEBUG_OBJECT (dpad->dbin, "autoplug-query returned %d", ret);
if (ret) {
GstCaps *result, *filter;
GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (dpad));
gst_query_parse_caps (query, &filter);
gst_query_parse_caps_result (query, &result);
result =
gst_caps_merge (gst_caps_ref (result),
gst_pad_get_pad_template_caps (target));
if (filter) {
GstCaps *intersection =
gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
gst_caps_unref (result);
result = intersection;
}
gst_query_set_caps_result (query, result);
gst_caps_unref (result);
gst_object_unref (target);
}
} }
CHAIN_MUTEX_UNLOCK (dpad->chain); CHAIN_MUTEX_UNLOCK (dpad->chain);

View file

@ -4086,14 +4086,33 @@ autoplug_query_caps (GstElement * uridecodebin, GstPad * pad,
GstCaps *filter, *result = NULL; GstCaps *filter, *result = NULL;
GstElement *sink; GstElement *sink;
GstPad *sinkpad = NULL; GstPad *sinkpad = NULL;
GValueArray *factories; GstElementFactory *factory;
gint i, n; GstElementFactoryListType factory_type;
gboolean have_audio_sink = FALSE, have_video_sink = FALSE; gboolean have_sink = FALSE;
gst_query_parse_caps (query, &filter);
GST_SOURCE_GROUP_LOCK (group); GST_SOURCE_GROUP_LOCK (group);
gst_query_parse_caps (query, &filter);
if ((sink = group->playbin->text_sink)) factory = gst_element_get_factory (element);
if (!factory)
goto done;
if (gst_element_factory_list_is_type (factory,
GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE)) {
factory_type =
GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE;
/* If this is from the subtitle uridecodebin we don't need to
* check the audio and video sink */
if (group->suburidecodebin
&& gst_object_has_ancestor (GST_OBJECT_CAST (pad),
GST_OBJECT_CAST (group->suburidecodebin))) {
goto done;
}
if ((sink = group->video_sink)) {
sinkpad = gst_element_get_static_pad (sink, "sink"); sinkpad = gst_element_get_static_pad (sink, "sink");
if (sinkpad) { if (sinkpad) {
GstCaps *sinkcaps; GstCaps *sinkcaps;
@ -4114,13 +4133,12 @@ autoplug_query_caps (GstElement * uridecodebin, GstPad * pad,
gst_caps_unref (sinkcaps); gst_caps_unref (sinkcaps);
} }
gst_object_unref (sinkpad); gst_object_unref (sinkpad);
} else {
GstCaps *subcaps = gst_subtitle_overlay_create_factory_caps ();
if (!result)
result = subcaps;
else
result = gst_caps_merge (result, subcaps);
} }
have_sink = TRUE;
}
} else if (gst_element_factory_list_is_type (factory,
GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO)) {
factory_type = GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO;
/* If this is from the subtitle uridecodebin we don't need to /* If this is from the subtitle uridecodebin we don't need to
* check the audio and video sink */ * check the audio and video sink */
@ -4152,10 +4170,13 @@ autoplug_query_caps (GstElement * uridecodebin, GstPad * pad,
} }
gst_object_unref (sinkpad); gst_object_unref (sinkpad);
} }
have_audio_sink = TRUE; have_sink = TRUE;
} }
} else if (gst_element_factory_list_is_type (factory,
GST_ELEMENT_FACTORY_TYPE_MEDIA_SUBTITLE)) {
factory_type = GST_ELEMENT_FACTORY_TYPE_MEDIA_SUBTITLE;
if ((sink = group->video_sink)) { if ((sink = group->playbin->text_sink)) {
sinkpad = gst_element_get_static_pad (sink, "sink"); sinkpad = gst_element_get_static_pad (sink, "sink");
if (sinkpad) { if (sinkpad) {
GstCaps *sinkcaps; GstCaps *sinkcaps;
@ -4177,33 +4198,35 @@ autoplug_query_caps (GstElement * uridecodebin, GstPad * pad,
} }
gst_object_unref (sinkpad); gst_object_unref (sinkpad);
} }
have_video_sink = TRUE; have_sink = TRUE;
} else {
GstCaps *subcaps = gst_subtitle_overlay_create_factory_caps ();
if (!result)
result = subcaps;
else
result = gst_caps_merge (result, subcaps);
} }
} else {
goto done;
}
if (!have_sink) {
GValueArray *factories;
gint i, n;
factories = autoplug_factories_cb (uridecodebin, pad, NULL, group); factories = autoplug_factories_cb (uridecodebin, pad, NULL, group);
n = factories->n_values; n = factories->n_values;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
GValue *v = g_value_array_get_nth (factories, i); GValue *v = g_value_array_get_nth (factories, i);
GstElementFactory *factory = g_value_get_object (v); GstElementFactory *f = g_value_get_object (v);
const GList *templates; const GList *templates;
const GList *l; const GList *l;
GstCaps *templ_caps; GstCaps *templ_caps;
if (!gst_element_factory_list_is_type (factory, if (!gst_element_factory_list_is_type (f, factory_type))
GST_ELEMENT_FACTORY_TYPE_SINK))
continue; continue;
if (have_audio_sink templates = gst_element_factory_get_static_pad_templates (f);
&& gst_element_factory_list_is_type (factory,
GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO))
continue;
if (have_video_sink
&& gst_element_factory_list_is_type (factory,
GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE))
continue;
templates = gst_element_factory_get_static_pad_templates (factory);
for (l = templates; l; l = l->next) { for (l = templates; l; l = l->next) {
templ_caps = gst_static_pad_template_get_caps (l->data); templ_caps = gst_static_pad_template_get_caps (l->data);
@ -4217,9 +4240,9 @@ autoplug_query_caps (GstElement * uridecodebin, GstPad * pad,
gst_caps_unref (templ_caps); gst_caps_unref (templ_caps);
} }
} }
} }
g_value_array_free (factories); g_value_array_free (factories);
}
done: done:
GST_SOURCE_GROUP_UNLOCK (group); GST_SOURCE_GROUP_UNLOCK (group);
@ -4227,6 +4250,15 @@ done:
if (!result) if (!result)
return FALSE; return FALSE;
if (0) {
GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (pad));
if (target) {
result = gst_caps_merge (result, gst_pad_get_pad_template_caps (target));
gst_object_unref (target);
}
}
if (filter) { if (filter) {
GstCaps *intersection = GstCaps *intersection =
gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST); gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);