mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:36:20 +00:00
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:
parent
d366613401
commit
e5064ee723
2 changed files with 161 additions and 142 deletions
|
@ -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);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dpad->dbin, "autoplug-query returned %d", ret);
|
if (ret)
|
||||||
if (ret) {
|
GST_DEBUG_OBJECT (dpad->dbin,
|
||||||
GstCaps *result, *filter;
|
"autoplug-query returned %d: %" GST_PTR_FORMAT, ret, query);
|
||||||
GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (dpad));
|
else
|
||||||
|
GST_DEBUG_OBJECT (dpad->dbin, "autoplug-query returned %d", ret);
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -4086,140 +4086,163 @@ 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);
|
||||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
if (!factory)
|
||||||
if (sinkpad) {
|
goto done;
|
||||||
GstCaps *sinkcaps;
|
|
||||||
|
|
||||||
/* Ignore errors here, if a custom sink fails to go
|
if (gst_element_factory_list_is_type (factory,
|
||||||
* to READY things are wrong and will error out later
|
GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
|
||||||
*/
|
GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE)) {
|
||||||
if (GST_STATE (sink) < GST_STATE_READY)
|
factory_type =
|
||||||
gst_element_set_state (sink, GST_STATE_READY);
|
GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
|
||||||
|
GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE;
|
||||||
|
|
||||||
sinkcaps = gst_pad_query_caps (sinkpad, filter);
|
/* If this is from the subtitle uridecodebin we don't need to
|
||||||
if (!gst_caps_is_any (sinkcaps)) {
|
* check the audio and video sink */
|
||||||
if (!result)
|
if (group->suburidecodebin
|
||||||
result = sinkcaps;
|
&& gst_object_has_ancestor (GST_OBJECT_CAST (pad),
|
||||||
else
|
GST_OBJECT_CAST (group->suburidecodebin))) {
|
||||||
result = gst_caps_merge (result, sinkcaps);
|
goto done;
|
||||||
} else {
|
|
||||||
gst_caps_unref (sinkcaps);
|
|
||||||
}
|
}
|
||||||
gst_object_unref (sinkpad);
|
|
||||||
} else {
|
|
||||||
GstCaps *subcaps = gst_subtitle_overlay_create_factory_caps ();
|
|
||||||
if (!result)
|
|
||||||
result = subcaps;
|
|
||||||
else
|
|
||||||
result = gst_caps_merge (result, subcaps);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If this is from the subtitle uridecodebin we don't need to
|
if ((sink = group->video_sink)) {
|
||||||
* check the audio and video sink */
|
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||||
if (group->suburidecodebin
|
if (sinkpad) {
|
||||||
&& gst_object_has_ancestor (GST_OBJECT_CAST (pad),
|
GstCaps *sinkcaps;
|
||||||
GST_OBJECT_CAST (group->suburidecodebin))) {
|
|
||||||
|
/* Ignore errors here, if a custom sink fails to go
|
||||||
|
* to READY things are wrong and will error out later
|
||||||
|
*/
|
||||||
|
if (GST_STATE (sink) < GST_STATE_READY)
|
||||||
|
gst_element_set_state (sink, GST_STATE_READY);
|
||||||
|
|
||||||
|
sinkcaps = gst_pad_query_caps (sinkpad, filter);
|
||||||
|
if (!gst_caps_is_any (sinkcaps)) {
|
||||||
|
if (!result)
|
||||||
|
result = sinkcaps;
|
||||||
|
else
|
||||||
|
result = gst_caps_merge (result, sinkcaps);
|
||||||
|
} else {
|
||||||
|
gst_caps_unref (sinkcaps);
|
||||||
|
}
|
||||||
|
gst_object_unref (sinkpad);
|
||||||
|
}
|
||||||
|
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
|
||||||
|
* 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->audio_sink)) {
|
||||||
|
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||||
|
if (sinkpad) {
|
||||||
|
GstCaps *sinkcaps;
|
||||||
|
|
||||||
|
/* Ignore errors here, if a custom sink fails to go
|
||||||
|
* to READY things are wrong and will error out later
|
||||||
|
*/
|
||||||
|
if (GST_STATE (sink) < GST_STATE_READY)
|
||||||
|
gst_element_set_state (sink, GST_STATE_READY);
|
||||||
|
|
||||||
|
sinkcaps = gst_pad_query_caps (sinkpad, filter);
|
||||||
|
if (!gst_caps_is_any (sinkcaps)) {
|
||||||
|
if (!result)
|
||||||
|
result = sinkcaps;
|
||||||
|
else
|
||||||
|
result = gst_caps_merge (result, sinkcaps);
|
||||||
|
} else {
|
||||||
|
gst_caps_unref (sinkcaps);
|
||||||
|
}
|
||||||
|
gst_object_unref (sinkpad);
|
||||||
|
}
|
||||||
|
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->playbin->text_sink)) {
|
||||||
|
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||||
|
if (sinkpad) {
|
||||||
|
GstCaps *sinkcaps;
|
||||||
|
|
||||||
|
/* Ignore errors here, if a custom sink fails to go
|
||||||
|
* to READY things are wrong and will error out later
|
||||||
|
*/
|
||||||
|
if (GST_STATE (sink) < GST_STATE_READY)
|
||||||
|
gst_element_set_state (sink, GST_STATE_READY);
|
||||||
|
|
||||||
|
sinkcaps = gst_pad_query_caps (sinkpad, filter);
|
||||||
|
if (!gst_caps_is_any (sinkcaps)) {
|
||||||
|
if (!result)
|
||||||
|
result = sinkcaps;
|
||||||
|
else
|
||||||
|
result = gst_caps_merge (result, sinkcaps);
|
||||||
|
} else {
|
||||||
|
gst_caps_unref (sinkcaps);
|
||||||
|
}
|
||||||
|
gst_object_unref (sinkpad);
|
||||||
|
}
|
||||||
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sink = group->audio_sink)) {
|
if (!have_sink) {
|
||||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
GValueArray *factories;
|
||||||
if (sinkpad) {
|
gint i, n;
|
||||||
GstCaps *sinkcaps;
|
|
||||||
|
|
||||||
/* Ignore errors here, if a custom sink fails to go
|
factories = autoplug_factories_cb (uridecodebin, pad, NULL, group);
|
||||||
* to READY things are wrong and will error out later
|
n = factories->n_values;
|
||||||
*/
|
for (i = 0; i < n; i++) {
|
||||||
if (GST_STATE (sink) < GST_STATE_READY)
|
GValue *v = g_value_array_get_nth (factories, i);
|
||||||
gst_element_set_state (sink, GST_STATE_READY);
|
GstElementFactory *f = g_value_get_object (v);
|
||||||
|
const GList *templates;
|
||||||
|
const GList *l;
|
||||||
|
GstCaps *templ_caps;
|
||||||
|
|
||||||
sinkcaps = gst_pad_query_caps (sinkpad, filter);
|
if (!gst_element_factory_list_is_type (f, factory_type))
|
||||||
if (!gst_caps_is_any (sinkcaps)) {
|
continue;
|
||||||
if (!result)
|
|
||||||
result = sinkcaps;
|
|
||||||
else
|
|
||||||
result = gst_caps_merge (result, sinkcaps);
|
|
||||||
} else {
|
|
||||||
gst_caps_unref (sinkcaps);
|
|
||||||
}
|
|
||||||
gst_object_unref (sinkpad);
|
|
||||||
}
|
|
||||||
have_audio_sink = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((sink = group->video_sink)) {
|
templates = gst_element_factory_get_static_pad_templates (f);
|
||||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
|
||||||
if (sinkpad) {
|
|
||||||
GstCaps *sinkcaps;
|
|
||||||
|
|
||||||
/* Ignore errors here, if a custom sink fails to go
|
for (l = templates; l; l = l->next) {
|
||||||
* to READY things are wrong and will error out later
|
templ_caps = gst_static_pad_template_get_caps (l->data);
|
||||||
*/
|
|
||||||
if (GST_STATE (sink) < GST_STATE_READY)
|
|
||||||
gst_element_set_state (sink, GST_STATE_READY);
|
|
||||||
|
|
||||||
sinkcaps = gst_pad_query_caps (sinkpad, filter);
|
if (!gst_caps_is_any (templ_caps)) {
|
||||||
if (!gst_caps_is_any (sinkcaps)) {
|
if (!result)
|
||||||
if (!result)
|
result = templ_caps;
|
||||||
result = sinkcaps;
|
else
|
||||||
else
|
result = gst_caps_merge (result, templ_caps);
|
||||||
result = gst_caps_merge (result, sinkcaps);
|
} else {
|
||||||
} else {
|
gst_caps_unref (templ_caps);
|
||||||
gst_caps_unref (sinkcaps);
|
}
|
||||||
}
|
|
||||||
gst_object_unref (sinkpad);
|
|
||||||
}
|
|
||||||
have_video_sink = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
factories = autoplug_factories_cb (uridecodebin, pad, NULL, group);
|
|
||||||
n = factories->n_values;
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
GValue *v = g_value_array_get_nth (factories, i);
|
|
||||||
GstElementFactory *factory = g_value_get_object (v);
|
|
||||||
const GList *templates;
|
|
||||||
const GList *l;
|
|
||||||
GstCaps *templ_caps;
|
|
||||||
|
|
||||||
if (!gst_element_factory_list_is_type (factory,
|
|
||||||
GST_ELEMENT_FACTORY_TYPE_SINK))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (have_audio_sink
|
|
||||||
&& 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) {
|
|
||||||
templ_caps = gst_static_pad_template_get_caps (l->data);
|
|
||||||
|
|
||||||
if (!gst_caps_is_any (templ_caps)) {
|
|
||||||
if (!result)
|
|
||||||
result = templ_caps;
|
|
||||||
else
|
|
||||||
result = gst_caps_merge (result, templ_caps);
|
|
||||||
} else {
|
|
||||||
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);
|
||||||
|
|
Loading…
Reference in a new issue