From 1f2d98028bf61c2e7b9e9fe2f2aee5d983aef745 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Thu, 10 Nov 2022 07:16:11 +0100 Subject: [PATCH] playbin3: Remove unused code This was never used, and if ever it's needed at some point for reference it's available in gstplaybin.c Part-of: --- .../gst/playback/gstplaybin3.c | 1201 ----------------- 1 file changed, 1201 deletions(-) diff --git a/subprojects/gst-plugins-base/gst/playback/gstplaybin3.c b/subprojects/gst-plugins-base/gst/playback/gstplaybin3.c index ba8a4ecd4f..5618d04057 100644 --- a/subprojects/gst-plugins-base/gst/playback/gstplaybin3.c +++ b/subprojects/gst-plugins-base/gst/playback/gstplaybin3.c @@ -300,22 +300,6 @@ static const gchar *stream_type_names[] = { (s) & GST_STREAM_TYPE_TEXT ? "text " : "" -#if 0 /* AUTOPLUG DISABLED */ -static void avelements_free (gpointer data); -static GSequence *avelements_create (GstPlayBin3 * playbin, - gboolean isaudioelement); -#endif - -/* The GstAudioVideoElement structure holding the audio/video decoder - * and the audio/video sink factories together with field indicating - * the number of common caps features */ -typedef struct -{ - GstElementFactory *dec; /* audio:video decoder */ - GstElementFactory *sink; /* audio:video sink */ - guint n_comm_cf; /* number of common caps features */ -} GstAVElement; - /* a structure to hold information about a uridecodebin pad */ struct _SourcePad { @@ -379,13 +363,6 @@ struct _GstSourceGroup gulong source_setup_id; gulong about_to_finish_id; -#if 0 /* AUTOPLUG DISABLED */ - gulong autoplug_factories_id; - gulong autoplug_select_id; - gulong autoplug_continue_id; - gulong autoplug_query_id; -#endif - gboolean stream_changed_pending; /* Active stream collection */ @@ -478,10 +455,6 @@ struct _GstPlayBin3 gint shutdown; gboolean async_pending; /* async-start has been emitted */ - GMutex elements_lock; - guint32 elements_cookie; - GList *elements; /* factories we can use for selecting elements */ - gboolean have_selector; /* set to FALSE when we fail to create an * input-selector, so that we only post a * warning once */ @@ -504,9 +477,6 @@ struct _GstPlayBin3 GstElement *video_stream_combiner; /* configured video stream combiner, or NULL */ GstElement *text_stream_combiner; /* configured text stream combiner, or NULL */ - GSequence *aelements; /* a list of GstAVElements for audio stream */ - GSequence *velements; /* a list of GstAVElements for video stream */ - guint64 ring_buffer_max_size; /* 0 means disabled */ gboolean is_live; /* Whether our current group is live */ @@ -592,11 +562,6 @@ enum LAST_SIGNAL }; -#if 0 /* AUTOPLUG DISABLED */ -static GstStaticCaps raw_audio_caps = GST_STATIC_CAPS ("audio/x-raw(ANY)"); -static GstStaticCaps raw_video_caps = GST_STATIC_CAPS ("video/x-raw(ANY)"); -#endif - static void gst_play_bin3_finalize (GObject * object); static void gst_play_bin3_set_property (GObject * object, guint prop_id, @@ -1227,83 +1192,6 @@ colorbalance_value_changed_cb (GstColorBalance * balance, gst_color_balance_value_changed (GST_COLOR_BALANCE (playbin), channel, value); } -#if 0 /* AUTOPLUG DISABLED */ -static gint -compare_factories_func (gconstpointer p1, gconstpointer p2) -{ - GstPluginFeature *f1, *f2; - gboolean is_sink1, is_sink2; - gboolean is_parser1, is_parser2; - - f1 = (GstPluginFeature *) p1; - f2 = (GstPluginFeature *) p2; - - is_sink1 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f1), - GST_ELEMENT_FACTORY_TYPE_SINK); - is_sink2 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f2), - GST_ELEMENT_FACTORY_TYPE_SINK); - is_parser1 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f1), - GST_ELEMENT_FACTORY_TYPE_PARSER); - is_parser2 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f2), - GST_ELEMENT_FACTORY_TYPE_PARSER); - - /* First we want all sinks as we prefer a sink if it directly - * supports the current caps */ - if (is_sink1 && !is_sink2) - return -1; - else if (!is_sink1 && is_sink2) - return 1; - - /* Then we want all parsers as we always want to plug parsers - * before decoders */ - if (is_parser1 && !is_parser2) - return -1; - else if (!is_parser1 && is_parser2) - return 1; - - /* And if it's a both a parser or sink we first sort by rank - * and then by factory name */ - return gst_plugin_feature_rank_compare_func (p1, p2); -} - -/* Must be called with elements lock! */ -static void -gst_play_bin3_update_elements_list (GstPlayBin3 * playbin) -{ - GList *res, *tmp; - guint cookie; - - cookie = gst_registry_get_feature_list_cookie (gst_registry_get ()); - - if (!playbin->elements || playbin->elements_cookie != cookie) { - if (playbin->elements) - gst_plugin_feature_list_free (playbin->elements); - res = - gst_element_factory_list_get_elements - (GST_ELEMENT_FACTORY_TYPE_DECODABLE, GST_RANK_MARGINAL); - tmp = - gst_element_factory_list_get_elements - (GST_ELEMENT_FACTORY_TYPE_AUDIOVIDEO_SINKS, GST_RANK_MARGINAL); - playbin->elements = g_list_concat (res, tmp); - playbin->elements = g_list_sort (playbin->elements, compare_factories_func); - } - - if (!playbin->aelements || playbin->elements_cookie != cookie) { - if (playbin->aelements) - g_sequence_free (playbin->aelements); - playbin->aelements = avelements_create (playbin, TRUE); - } - - if (!playbin->velements || playbin->elements_cookie != cookie) { - if (playbin->velements) - g_sequence_free (playbin->velements); - playbin->velements = avelements_create (playbin, FALSE); - } - - playbin->elements_cookie = cookie; -} -#endif - static void gst_play_bin3_init (GstPlayBin3 * playbin) { @@ -1323,9 +1211,6 @@ gst_play_bin3_init (GstPlayBin3 * playbin) init_group (playbin, &playbin->groups[0]); init_group (playbin, &playbin->groups[1]); - /* first filter out the interesting element factories */ - g_mutex_init (&playbin->elements_lock); - g_rec_mutex_init (&playbin->activation_lock); /* add sink */ @@ -1405,21 +1290,11 @@ gst_play_bin3_finalize (GObject * object) g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_TEXT].streams, TRUE); g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_TEXT].inputpads, TRUE); - if (playbin->elements) - gst_plugin_feature_list_free (playbin->elements); - - if (playbin->aelements) - g_sequence_free (playbin->aelements); - - if (playbin->velements) - g_sequence_free (playbin->velements); - g_rec_mutex_clear (&playbin->activation_lock); g_rec_mutex_clear (&playbin->lock); g_mutex_clear (&playbin->buffering_post_lock); g_mutex_clear (&playbin->dyn_lock); - g_mutex_clear (&playbin->elements_lock); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -3295,414 +3170,6 @@ about_to_finish_cb (GstElement * uridecodebin, GstSourceGroup * group) emit_about_to_finish (playbin); } -#if 0 /* AUTOPLUG DISABLED */ -/* Like gst_element_factory_can_sink_any_caps() but doesn't - * allow ANY caps on the sinkpad template */ -static gboolean -_factory_can_sink_caps (GstElementFactory * factory, GstCaps * caps) -{ - const GList *templs; - - templs = gst_element_factory_get_static_pad_templates (factory); - - while (templs) { - GstStaticPadTemplate *templ = (GstStaticPadTemplate *) templs->data; - - if (templ->direction == GST_PAD_SINK) { - GstCaps *templcaps = gst_static_caps_get (&templ->static_caps); - - if (!gst_caps_is_any (templcaps) - && gst_caps_is_subset (caps, templcaps)) { - gst_caps_unref (templcaps); - return TRUE; - } - gst_caps_unref (templcaps); - } - templs = g_list_next (templs); - } - - return FALSE; -} - -static void -avelements_free (gpointer avelement) -{ - GstAVElement *elm = (GstAVElement *) avelement; - - if (elm->dec) - gst_object_unref (elm->dec); - if (elm->sink) - gst_object_unref (elm->sink); - g_slice_free (GstAVElement, elm); -} - -static gint -avelement_compare_decoder (gconstpointer p1, gconstpointer p2, - gpointer user_data) -{ - GstAVElement *v1, *v2; - - v1 = (GstAVElement *) p1; - v2 = (GstAVElement *) p2; - - return strcmp (GST_OBJECT_NAME (v1->dec), GST_OBJECT_NAME (v2->dec)); -} - -static gint -avelement_lookup_decoder (gconstpointer p1, gconstpointer p2, - gpointer user_data) -{ - GstAVElement *v1; - GstElementFactory *f2; - - v1 = (GstAVElement *) p1; - f2 = (GstElementFactory *) p2; - - return strcmp (GST_OBJECT_NAME (v1->dec), GST_OBJECT_NAME (f2)); -} - -static gint -avelement_compare (gconstpointer p1, gconstpointer p2) -{ - GstAVElement *v1, *v2; - GstPluginFeature *fd1, *fd2, *fs1, *fs2; - gint64 diff, v1_rank, v2_rank; - - v1 = (GstAVElement *) p1; - v2 = (GstAVElement *) p2; - - fd1 = (GstPluginFeature *) v1->dec; - fd2 = (GstPluginFeature *) v2->dec; - - /* If both have a sink, we also compare their ranks */ - if (v1->sink && v2->sink) { - fs1 = (GstPluginFeature *) v1->sink; - fs2 = (GstPluginFeature *) v2->sink; - v1_rank = (gint64) gst_plugin_feature_get_rank (fd1) * - gst_plugin_feature_get_rank (fs1); - v2_rank = (gint64) gst_plugin_feature_get_rank (fd2) * - gst_plugin_feature_get_rank (fs2); - } else { - v1_rank = gst_plugin_feature_get_rank (fd1); - v2_rank = gst_plugin_feature_get_rank (fd2); - fs1 = fs2 = NULL; - } - - /* comparison based on the rank */ - diff = v2_rank - v1_rank; - if (diff < 0) - return -1; - else if (diff > 0) - return 1; - - /* comparison based on number of common caps features */ - diff = v2->n_comm_cf - v1->n_comm_cf; - if (diff != 0) - return diff; - - if (fs1 && fs2) { - /* comparison based on the name of sink elements */ - diff = strcmp (GST_OBJECT_NAME (fs1), GST_OBJECT_NAME (fs2)); - if (diff != 0) - return diff; - } - - /* comparison based on the name of decoder elements */ - return strcmp (GST_OBJECT_NAME (fd1), GST_OBJECT_NAME (fd2)); -} - -static GSequence * -avelements_create (GstPlayBin3 * playbin, gboolean isaudioelement) -{ - GstElementFactory *d_factory, *s_factory; - GList *dec_list, *sink_list, *dl, *sl; - GSequence *ave_seq = NULL; - GstAVElement *ave; - guint n_common_cf = 0; - - if (isaudioelement) { - sink_list = gst_element_factory_list_get_elements - (GST_ELEMENT_FACTORY_TYPE_SINK | - GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, GST_RANK_MARGINAL); - dec_list = - gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_DECODER - | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, GST_RANK_MARGINAL); - } else { - sink_list = gst_element_factory_list_get_elements - (GST_ELEMENT_FACTORY_TYPE_SINK | - GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO | - GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE, GST_RANK_MARGINAL); - - dec_list = - gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_DECODER - | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO | - GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE, GST_RANK_MARGINAL); - } - - /* create a list of audio/video elements. Each element in the list - * is holding an audio/video decoder and an audio/video sink in which - * the decoders srcpad template caps and sink element's sinkpad template - * caps are compatible */ - dl = dec_list; - sl = sink_list; - - ave_seq = g_sequence_new ((GDestroyNotify) avelements_free); - - for (; dl; dl = dl->next) { - d_factory = (GstElementFactory *) dl->data; - for (; sl; sl = sl->next) { - s_factory = (GstElementFactory *) sl->data; - - n_common_cf = - gst_playback_utils_get_n_common_capsfeatures (d_factory, s_factory, - gst_play_bin3_get_flags (playbin), isaudioelement); - if (n_common_cf < 1) - continue; - - ave = g_slice_new (GstAVElement); - ave->dec = gst_object_ref (d_factory); - ave->sink = gst_object_ref (s_factory); - ave->n_comm_cf = n_common_cf; - g_sequence_append (ave_seq, ave); - } - sl = sink_list; - } - g_sequence_sort (ave_seq, (GCompareDataFunc) avelement_compare_decoder, NULL); - - gst_plugin_feature_list_free (dec_list); - gst_plugin_feature_list_free (sink_list); - - return ave_seq; -} - -static gboolean -avelement_iter_is_equal (GSequenceIter * iter, GstElementFactory * factory) -{ - GstAVElement *ave; - - if (!iter) - return FALSE; - - ave = g_sequence_get (iter); - if (!ave) - return FALSE; - - return strcmp (GST_OBJECT_NAME (ave->dec), GST_OBJECT_NAME (factory)) == 0; -} - -static GList * -create_decoders_list (GList * factory_list, GSequence * avelements) -{ - GList *dec_list = NULL, *tmp; - GList *ave_list = NULL; - GList *ave_free_list = NULL; - GstAVElement *ave, *best_ave; - - g_return_val_if_fail (factory_list != NULL, NULL); - g_return_val_if_fail (avelements != NULL, NULL); - - for (tmp = factory_list; tmp; tmp = tmp->next) { - GstElementFactory *factory = (GstElementFactory *) tmp->data; - - /* if there are parsers or sink elements, add them first */ - if (gst_element_factory_list_is_type (factory, - GST_ELEMENT_FACTORY_TYPE_PARSER) || - gst_element_factory_list_is_type (factory, - GST_ELEMENT_FACTORY_TYPE_SINK)) { - dec_list = g_list_prepend (dec_list, gst_object_ref (factory)); - } else { - GSequenceIter *seq_iter; - - seq_iter = - g_sequence_lookup (avelements, factory, - (GCompareDataFunc) avelement_lookup_decoder, NULL); - if (!seq_iter) { - GstAVElement *ave = g_slice_new0 (GstAVElement); - - ave->dec = factory; - ave->sink = NULL; - /* There's at least raw */ - ave->n_comm_cf = 1; - - ave_list = g_list_prepend (ave_list, ave); - - /* We need to free these later */ - ave_free_list = g_list_prepend (ave_free_list, ave); - continue; - } - - /* Go to first iter with that decoder */ - do { - GSequenceIter *tmp_seq_iter; - - tmp_seq_iter = g_sequence_iter_prev (seq_iter); - if (!avelement_iter_is_equal (tmp_seq_iter, factory)) - break; - seq_iter = tmp_seq_iter; - } while (!g_sequence_iter_is_begin (seq_iter)); - - /* Get the best ranked GstAVElement for that factory */ - best_ave = NULL; - while (!g_sequence_iter_is_end (seq_iter) - && avelement_iter_is_equal (seq_iter, factory)) { - ave = g_sequence_get (seq_iter); - - if (!best_ave || avelement_compare (ave, best_ave) < 0) - best_ave = ave; - - seq_iter = g_sequence_iter_next (seq_iter); - } - ave_list = g_list_prepend (ave_list, best_ave); - } - } - - /* Sort all GstAVElements by their relative ranks and insert - * into the decoders list */ - ave_list = g_list_sort (ave_list, (GCompareFunc) avelement_compare); - for (tmp = ave_list; tmp; tmp = tmp->next) { - ave = (GstAVElement *) tmp->data; - dec_list = g_list_prepend (dec_list, gst_object_ref (ave->dec)); - } - g_list_free (ave_list); - gst_plugin_feature_list_free (factory_list); - - for (tmp = ave_free_list; tmp; tmp = tmp->next) - g_slice_free (GstAVElement, tmp->data); - g_list_free (ave_free_list); - - dec_list = g_list_reverse (dec_list); - - return dec_list; -} - -/* Called when we must provide a list of factories to plug to @pad with @caps. - * We first check if we have a sink that can handle the format and if we do, we - * return NULL, to expose the pad. If we have no sink (or the sink does not - * work), we return the list of elements that can connect. */ -static GValueArray * -autoplug_factories_cb (GstElement * decodebin, GstPad * pad, - GstCaps * caps, GstSourceGroup * group) -{ - GstPlayBin3 *playbin; - GList *factory_list, *tmp; - GValueArray *result; - gboolean unref_caps = FALSE; - gboolean isaudiodeclist = FALSE; - gboolean isvideodeclist = FALSE; - - if (!caps) { - caps = gst_caps_new_any (); - unref_caps = TRUE; - } - - playbin = group->playbin; - - GST_DEBUG_OBJECT (playbin, "factories group %p for %s:%s, %" GST_PTR_FORMAT, - group, GST_DEBUG_PAD_NAME (pad), caps); - - /* filter out the elements based on the caps. */ - g_mutex_lock (&playbin->elements_lock); - gst_play_bin3_update_elements_list (playbin); - factory_list = - gst_element_factory_list_filter (playbin->elements, caps, GST_PAD_SINK, - gst_caps_is_fixed (caps)); - g_mutex_unlock (&playbin->elements_lock); - - GST_DEBUG_OBJECT (playbin, "found factories %p", factory_list); - GST_PLUGIN_FEATURE_LIST_DEBUG (factory_list); - - /* check whether the caps are asking for a list of audio/video decoders */ - tmp = factory_list; - if (!gst_caps_is_any (caps)) { - for (; tmp; tmp = tmp->next) { - GstElementFactory *factory = (GstElementFactory *) tmp->data; - - isvideodeclist = gst_element_factory_list_is_type (factory, - GST_ELEMENT_FACTORY_TYPE_DECODER | - GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO | - GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE); - isaudiodeclist = gst_element_factory_list_is_type (factory, - GST_ELEMENT_FACTORY_TYPE_DECODER | - GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO); - - if (isaudiodeclist || isvideodeclist) - break; - } - } - - if (isaudiodeclist || isvideodeclist) { - GSequence **ave_list; - if (isaudiodeclist) - ave_list = &playbin->aelements; - else - ave_list = &playbin->velements; - - g_mutex_lock (&playbin->elements_lock); - /* sort factory_list based on the GstAVElement list priority */ - factory_list = create_decoders_list (factory_list, *ave_list); - g_mutex_unlock (&playbin->elements_lock); - } - - /* 2 additional elements for the already set audio/video sinks */ - result = g_value_array_new (g_list_length (factory_list) + 2); - - /* Check if we already have an audio/video sink and if this is the case - * put it as the first element of the array */ - if (group->audio_sink) { - GstElementFactory *factory = gst_element_get_factory (group->audio_sink); - - if (factory && _factory_can_sink_caps (factory, caps)) { - GValue val = { 0, }; - - g_value_init (&val, G_TYPE_OBJECT); - g_value_set_object (&val, factory); - result = g_value_array_append (result, &val); - g_value_unset (&val); - } - } - - if (group->video_sink) { - GstElementFactory *factory = gst_element_get_factory (group->video_sink); - - if (factory && _factory_can_sink_caps (factory, caps)) { - GValue val = { 0, }; - - g_value_init (&val, G_TYPE_OBJECT); - g_value_set_object (&val, factory); - result = g_value_array_append (result, &val); - g_value_unset (&val); - } - } - - for (tmp = factory_list; tmp; tmp = tmp->next) { - GstElementFactory *factory = GST_ELEMENT_FACTORY_CAST (tmp->data); - GValue val = { 0, }; - - if (group->audio_sink && gst_element_factory_list_is_type (factory, - GST_ELEMENT_FACTORY_TYPE_SINK | - GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO)) { - continue; - } - if (group->video_sink && gst_element_factory_list_is_type (factory, - GST_ELEMENT_FACTORY_TYPE_SINK | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO - | GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE)) { - continue; - } - - g_value_init (&val, G_TYPE_OBJECT); - g_value_set_object (&val, factory); - g_value_array_append (result, &val); - g_value_unset (&val); - } - gst_plugin_feature_list_free (factory_list); - - if (unref_caps) - gst_caps_unref (caps); - - return result; -} -#endif - static GstBusSyncReply activate_sink_bus_handler (GstBus * bus, GstMessage * msg, GstPlayBin3 * playbin) @@ -3782,633 +3249,6 @@ done: return ret; } -#if 0 /* AUTOPLUG DISABLED */ -/* autoplug-continue decides, if a pad has raw caps that can be exposed - * directly or if further decoding is necessary. We use this to expose - * supported subtitles directly */ - -/* FIXME 0.11: Remove the checks for ANY caps, a sink should specify - * explicitly the caps it supports and if it claims to support ANY - * caps it really should support everything */ -static gboolean -autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps, - GstSourceGroup * group) -{ - gboolean ret = TRUE; - GstPad *sinkpad = NULL; - gboolean activated_sink; - - GST_SOURCE_GROUP_LOCK (group); - - if (group->text_sink && - activate_sink (group->playbin, group->text_sink, &activated_sink)) { - sinkpad = gst_element_get_static_pad (group->text_sink, "sink"); - if (sinkpad) { - GstCaps *sinkcaps; - - sinkcaps = gst_pad_query_caps (sinkpad, NULL); - if (!gst_caps_is_any (sinkcaps)) - ret = !gst_pad_query_accept_caps (sinkpad, caps); - gst_caps_unref (sinkcaps); - gst_object_unref (sinkpad); - } - if (activated_sink) - gst_element_set_state (group->text_sink, GST_STATE_NULL); - } else { - GstCaps *subcaps = gst_subtitle_overlay_create_factory_caps (); - ret = !gst_caps_is_subset (caps, subcaps); - gst_caps_unref (subcaps); - } - /* If autoplugging can stop don't do additional checks */ - if (!ret) - goto done; - - if (group->audio_sink && - activate_sink (group->playbin, group->audio_sink, &activated_sink)) { - - sinkpad = gst_element_get_static_pad (group->audio_sink, "sink"); - if (sinkpad) { - GstCaps *sinkcaps; - - sinkcaps = gst_pad_query_caps (sinkpad, NULL); - if (!gst_caps_is_any (sinkcaps)) - ret = !gst_pad_query_accept_caps (sinkpad, caps); - gst_caps_unref (sinkcaps); - gst_object_unref (sinkpad); - } - if (activated_sink) - gst_element_set_state (group->audio_sink, GST_STATE_NULL); - } - if (!ret) - goto done; - - if (group->video_sink - && activate_sink (group->playbin, group->video_sink, &activated_sink)) { - sinkpad = gst_element_get_static_pad (group->video_sink, "sink"); - if (sinkpad) { - GstCaps *sinkcaps; - - sinkcaps = gst_pad_query_caps (sinkpad, NULL); - if (!gst_caps_is_any (sinkcaps)) - ret = !gst_pad_query_accept_caps (sinkpad, caps); - gst_caps_unref (sinkcaps); - gst_object_unref (sinkpad); - } - if (activated_sink) - gst_element_set_state (group->video_sink, GST_STATE_NULL); - } - -done: - GST_SOURCE_GROUP_UNLOCK (group); - - GST_DEBUG_OBJECT (group->playbin, - "continue autoplugging group %p for %s:%s, %" GST_PTR_FORMAT ": %d", - group, GST_DEBUG_PAD_NAME (pad), caps, ret); - - return ret; -} - -static gboolean -sink_accepts_caps (GstPlayBin3 * playbin, GstElement * sink, GstCaps * caps) -{ - GstPad *sinkpad; - - if ((sinkpad = gst_element_get_static_pad (sink, "sink"))) { - /* Got the sink pad, now let's see if the element actually does accept the - * caps that we have */ - if (!gst_pad_query_accept_caps (sinkpad, caps)) { - gst_object_unref (sinkpad); - return FALSE; - } - gst_object_unref (sinkpad); - } - - return TRUE; -} - -/* We are asked to select an element. See if the next element to check - * is a sink. If this is the case, we see if the sink works by setting it to - * READY. If the sink works, we return SELECT_EXPOSE to make decodebin - * expose the raw pad so that we can setup the mixers. */ -static GstAutoplugSelectResult -autoplug_select_cb (GstElement * decodebin, GstPad * pad, - GstCaps * caps, GstElementFactory * factory, GstSourceGroup * group) -{ - GstPlayBin3 *playbin; - GstElement *element; - const gchar *klass; - GstPlaySinkType type; - GstElement **sinkp; - GList *ave_list = NULL, *l; - GstAVElement *ave = NULL; - GSequence *ave_seq = NULL; - GSequenceIter *seq_iter; - - playbin = group->playbin; - - GST_DEBUG_OBJECT (playbin, "select group %p for %s:%s, %" GST_PTR_FORMAT, - group, GST_DEBUG_PAD_NAME (pad), caps); - - GST_DEBUG_OBJECT (playbin, "checking factory %s", GST_OBJECT_NAME (factory)); - - /* if it's not a sink, we make sure the element is compatible with - * the fixed sink */ - if (!gst_element_factory_list_is_type (factory, - GST_ELEMENT_FACTORY_TYPE_SINK)) { - gboolean isvideodec = gst_element_factory_list_is_type (factory, - GST_ELEMENT_FACTORY_TYPE_DECODER | - GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO | - GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE); - gboolean isaudiodec = gst_element_factory_list_is_type (factory, - GST_ELEMENT_FACTORY_TYPE_DECODER | - GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO); - - if (!isvideodec && !isaudiodec) - return GST_AUTOPLUG_SELECT_TRY; - - GST_SOURCE_GROUP_LOCK (group); - g_mutex_lock (&playbin->elements_lock); - - if (isaudiodec) { - ave_seq = playbin->aelements; - sinkp = &group->audio_sink; - } else { - ave_seq = playbin->velements; - sinkp = &group->video_sink; - } - - seq_iter = - g_sequence_lookup (ave_seq, factory, - (GCompareDataFunc) avelement_lookup_decoder, NULL); - if (seq_iter) { - /* Go to first iter with that decoder */ - do { - GSequenceIter *tmp_seq_iter; - - tmp_seq_iter = g_sequence_iter_prev (seq_iter); - if (!avelement_iter_is_equal (tmp_seq_iter, factory)) - break; - seq_iter = tmp_seq_iter; - } while (!g_sequence_iter_is_begin (seq_iter)); - - while (!g_sequence_iter_is_end (seq_iter) - && avelement_iter_is_equal (seq_iter, factory)) { - ave = g_sequence_get (seq_iter); - ave_list = g_list_prepend (ave_list, ave); - seq_iter = g_sequence_iter_next (seq_iter); - } - - /* Sort all GstAVElements by their relative ranks and insert - * into the decoders list */ - ave_list = g_list_sort (ave_list, (GCompareFunc) avelement_compare); - } else { - ave_list = g_list_prepend (ave_list, NULL); - } - - /* if it is a decoder and we don't have a fixed sink, then find out - * the matching audio/video sink from GstAVElements list */ - for (l = ave_list; l; l = l->next) { - gboolean created_sink = FALSE; - - ave = (GstAVElement *) l->data; - - if (((isaudiodec && !group->audio_sink) || - (isvideodec && !group->video_sink))) { - if (ave && ave->sink) { - GST_DEBUG_OBJECT (playbin, - "Trying to create sink '%s' for decoder '%s'", - gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (ave->sink)), - gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory))); - if ((*sinkp = gst_element_factory_create (ave->sink, NULL)) == NULL) { - GST_WARNING_OBJECT (playbin, - "Could not create an element from %s", - gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (ave->sink))); - continue; - } else { - if (!activate_sink (playbin, *sinkp, NULL)) { - gst_object_unref (*sinkp); - *sinkp = NULL; - GST_WARNING_OBJECT (playbin, - "Could not activate sink %s", - gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (ave->sink))); - continue; - } - gst_object_ref_sink (*sinkp); - created_sink = TRUE; - } - } - } - - /* If it is a decoder and we have a fixed sink for the media - * type it outputs, check that the decoder is compatible with this sink */ - if ((isaudiodec && group->audio_sink) || (isvideodec - && group->video_sink)) { - gboolean compatible = FALSE; - GstPad *sinkpad; - GstCaps *caps; - GstElement *sink; - - sink = *sinkp; - - if ((sinkpad = gst_element_get_static_pad (sink, "sink"))) { - GstPlayFlags flags = gst_play_bin3_get_flags (playbin); - GstCaps *raw_caps = - (isaudiodec) ? gst_static_caps_get (&raw_audio_caps) : - gst_static_caps_get (&raw_video_caps); - - caps = gst_pad_query_caps (sinkpad, NULL); - - /* If the sink supports raw audio/video, we first check - * if the decoder could output any raw audio/video format - * and assume it is compatible with the sink then. We don't - * do a complete compatibility check here if converters - * are plugged between the decoder and the sink because - * the converters will convert between raw formats and - * even if the decoder format is not supported by the decoder - * a converter will convert it. - * - * We assume here that the converters can convert between - * any raw format. - */ - if ((isaudiodec && !(flags & GST_PLAY_FLAG_NATIVE_AUDIO) - && gst_caps_can_intersect (caps, raw_caps)) || (!isaudiodec - && !(flags & GST_PLAY_FLAG_NATIVE_VIDEO) - && gst_caps_can_intersect (caps, raw_caps))) { - compatible = - gst_element_factory_can_src_any_caps (factory, raw_caps) - || gst_element_factory_can_src_any_caps (factory, caps); - } else { - compatible = gst_element_factory_can_src_any_caps (factory, caps); - } - - gst_object_unref (sinkpad); - gst_caps_unref (caps); - } - - if (compatible) - break; - - GST_DEBUG_OBJECT (playbin, "%s not compatible with the fixed sink", - GST_OBJECT_NAME (factory)); - - /* If it is not compatible, either continue with the next possible - * sink or if we have a fixed sink, skip the decoder */ - if (created_sink) { - gst_element_set_state (*sinkp, GST_STATE_NULL); - gst_object_unref (*sinkp); - *sinkp = NULL; - } else { - g_mutex_unlock (&playbin->elements_lock); - GST_SOURCE_GROUP_UNLOCK (group); - return GST_AUTOPLUG_SELECT_SKIP; - } - } - } - g_list_free (ave_list); - g_mutex_unlock (&playbin->elements_lock); - GST_SOURCE_GROUP_UNLOCK (group); - return GST_AUTOPLUG_SELECT_TRY; - } - - /* it's a sink, see if an instance of it actually works */ - GST_DEBUG_OBJECT (playbin, "we found a sink '%s'", GST_OBJECT_NAME (factory)); - - klass = - gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS); - - /* figure out the klass */ - if (strstr (klass, "Audio")) { - GST_DEBUG_OBJECT (playbin, "we found an audio sink"); - type = GST_PLAY_SINK_TYPE_AUDIO; - sinkp = &group->audio_sink; - } else if (strstr (klass, "Video")) { - GST_DEBUG_OBJECT (playbin, "we found a video sink"); - type = GST_PLAY_SINK_TYPE_VIDEO; - sinkp = &group->video_sink; - } else { - /* unknown klass, skip this element */ - GST_WARNING_OBJECT (playbin, "unknown sink klass %s found", klass); - return GST_AUTOPLUG_SELECT_SKIP; - } - - /* if we are asked to do visualisations and it's an audio sink, skip the - * element. We can only do visualisations with raw sinks */ - if (gst_play_sink_get_flags (playbin->playsink) & GST_PLAY_FLAG_VIS) { - if (type == GST_PLAY_SINK_TYPE_AUDIO) { - GST_DEBUG_OBJECT (playbin, "skip audio sink because of vis"); - return GST_AUTOPLUG_SELECT_SKIP; - } - } - - /* now see if we already have a sink element */ - GST_SOURCE_GROUP_LOCK (group); - if (*sinkp && GST_STATE (*sinkp) >= GST_STATE_READY) { - GstElement *sink = gst_object_ref (*sinkp); - - if (sink_accepts_caps (playbin, sink, caps)) { - GST_DEBUG_OBJECT (playbin, - "Existing sink '%s' accepts caps: %" GST_PTR_FORMAT, - GST_ELEMENT_NAME (sink), caps); - gst_object_unref (sink); - GST_SOURCE_GROUP_UNLOCK (group); - return GST_AUTOPLUG_SELECT_EXPOSE; - } else { - GST_DEBUG_OBJECT (playbin, - "Existing sink '%s' does not accept caps: %" GST_PTR_FORMAT, - GST_ELEMENT_NAME (sink), caps); - gst_object_unref (sink); - GST_SOURCE_GROUP_UNLOCK (group); - return GST_AUTOPLUG_SELECT_SKIP; - } - } - GST_DEBUG_OBJECT (playbin, "we have no pending sink, try to create '%s'", - gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory))); - - if ((*sinkp = gst_element_factory_create (factory, NULL)) == NULL) { - GST_WARNING_OBJECT (playbin, "Could not create an element from %s", - gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory))); - GST_SOURCE_GROUP_UNLOCK (group); - return GST_AUTOPLUG_SELECT_SKIP; - } - - element = *sinkp; - - if (!activate_sink (playbin, element, NULL)) { - GST_WARNING_OBJECT (playbin, "Could not activate sink %s", - gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory))); - *sinkp = NULL; - gst_object_unref (element); - GST_SOURCE_GROUP_UNLOCK (group); - return GST_AUTOPLUG_SELECT_SKIP; - } - - /* Check if the selected sink actually supports the - * caps and can be set to READY*/ - if (!sink_accepts_caps (playbin, element, caps)) { - *sinkp = NULL; - gst_element_set_state (element, GST_STATE_NULL); - gst_object_unref (element); - GST_SOURCE_GROUP_UNLOCK (group); - return GST_AUTOPLUG_SELECT_SKIP; - } - - /* remember the sink in the group now, the element is floating, we take - * ownership now - * - * store the sink in the group, we will configure it later when we - * reconfigure the sink */ - GST_DEBUG_OBJECT (playbin, "remember sink"); - gst_object_ref_sink (element); - GST_SOURCE_GROUP_UNLOCK (group); - - /* tell decodebin to expose the pad because we are going to use this - * sink */ - GST_DEBUG_OBJECT (playbin, "we found a working sink, expose pad"); - - return GST_AUTOPLUG_SELECT_EXPOSE; -} - -#define GST_PLAY_BIN3_FILTER_CAPS(filter,caps) G_STMT_START { \ - if ((filter)) { \ - GstCaps *intersection = \ - gst_caps_intersect_full ((filter), (caps), GST_CAPS_INTERSECT_FIRST); \ - gst_caps_unref ((caps)); \ - (caps) = intersection; \ - } \ -} G_STMT_END - -static gboolean -autoplug_query_caps (GstElement * uridecodebin, GstPad * pad, - GstElement * element, GstQuery * query, GstSourceGroup * group) -{ - GstCaps *filter, *result = NULL; - GstElement *sink; - GstPad *sinkpad = NULL; - GstElementFactory *factory; - GstElementFactoryListType factory_type; - gboolean have_sink = FALSE; - - GST_SOURCE_GROUP_LOCK (group); - gst_query_parse_caps (query, &filter); - - 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 ((sink = group->video_sink)) { - sinkpad = gst_element_get_static_pad (sink, "sink"); - if (sinkpad) { - GstCaps *sinkcaps; - - 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 ((sink = group->audio_sink)) { - sinkpad = gst_element_get_static_pad (sink, "sink"); - if (sinkpad) { - GstCaps *sinkcaps; - - 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; - - 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 (); - GST_PLAY_BIN3_FILTER_CAPS (filter, subcaps); - 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); - n = factories->n_values; - for (i = 0; i < n; i++) { - GValue *v = g_value_array_get_nth (factories, i); - GstElementFactory *f = g_value_get_object (v); - const GList *templates; - const GList *l; - GstCaps *templ_caps; - - if (!gst_element_factory_list_is_type (f, factory_type)) - continue; - - templates = gst_element_factory_get_static_pad_templates (f); - - for (l = templates; l; l = l->next) { - templ_caps = gst_static_pad_template_get_caps (l->data); - - if (!gst_caps_is_any (templ_caps)) { - GST_PLAY_BIN3_FILTER_CAPS (filter, 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); - } - -done: - GST_SOURCE_GROUP_UNLOCK (group); - - if (!result) - return FALSE; - - /* Add the actual decoder/parser/etc caps at the very end to - * make sure we don't cause empty caps to be returned, e.g. - * if a parser asks us but a decoder is required after it - * because no sink can handle the format directly. - */ - { - GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (pad)); - - if (target) { - GstCaps *target_caps = gst_pad_get_pad_template_caps (target); - GST_PLAY_BIN3_FILTER_CAPS (filter, target_caps); - if (!gst_caps_is_any (target_caps)) - result = gst_caps_merge (result, target_caps); - gst_object_unref (target); - } - } - - - gst_query_set_caps_result (query, result); - gst_caps_unref (result); - - return TRUE; -} - -static gboolean -autoplug_query_context (GstElement * uridecodebin, GstPad * pad, - GstElement * element, GstQuery * query, GstSourceGroup * group) -{ - GstElement *sink; - GstPad *sinkpad = NULL; - GstElementFactory *factory; - gboolean res = FALSE; - - GST_SOURCE_GROUP_LOCK (group); - - 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)) { - if ((sink = group->video_sink)) { - sinkpad = gst_element_get_static_pad (sink, "sink"); - if (sinkpad) { - res = gst_pad_query (sinkpad, query); - gst_object_unref (sinkpad); - } - } - } else if (gst_element_factory_list_is_type (factory, - GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO)) { - if ((sink = group->audio_sink)) { - sinkpad = gst_element_get_static_pad (sink, "sink"); - if (sinkpad) { - res = gst_pad_query (sinkpad, query); - gst_object_unref (sinkpad); - } - } - } else if (gst_element_factory_list_is_type (factory, - GST_ELEMENT_FACTORY_TYPE_MEDIA_SUBTITLE)) { - if ((sink = group->playbin->text_sink)) { - sinkpad = gst_element_get_static_pad (sink, "sink"); - if (sinkpad) { - res = gst_pad_query (sinkpad, query); - gst_object_unref (sinkpad); - } - } - } else { - goto done; - } - -done: - GST_SOURCE_GROUP_UNLOCK (group); - - return res; -} - -static gboolean -autoplug_query_cb (GstElement * uridecodebin, GstPad * pad, - GstElement * element, GstQuery * query, GstSourceGroup * group) -{ - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_CAPS: - return autoplug_query_caps (uridecodebin, pad, element, query, group); - case GST_QUERY_CONTEXT: - return autoplug_query_context (uridecodebin, pad, element, query, group); - default: - return FALSE; - } -} -#endif - /* must be called with the group lock */ static gboolean group_set_locked_state_unlocked (GstPlayBin3 * playbin, GstSourceGroup * group, @@ -4645,12 +3485,6 @@ error_cleanup: REMOVE_SIGNAL (group->uridecodebin, group->select_stream_id); REMOVE_SIGNAL (group->uridecodebin, group->source_setup_id); REMOVE_SIGNAL (group->uridecodebin, group->about_to_finish_id); -#if 0 - REMOVE_SIGNAL (group->urisourcebin, group->autoplug_factories_id); - REMOVE_SIGNAL (group->urisourcebin, group->autoplug_select_id); - REMOVE_SIGNAL (group->urisourcebin, group->autoplug_continue_id); - REMOVE_SIGNAL (group->urisourcebin, group->autoplug_query_id); -#endif gst_element_set_state (uridecodebin, GST_STATE_NULL); gst_bin_remove (GST_BIN_CAST (playbin), uridecodebin); @@ -4685,35 +3519,6 @@ deactivate_group (GstPlayBin3 * playbin, GstSourceGroup * group) if (playbin->active_stream_types != playbin->selected_stream_types) reconfigure_output (playbin); -#if 0 - /* delete any custom sinks we might have. - * conditionally set them to null if they aren't inside playsink yet */ - if (group->audio_sink) { - if (!gst_object_has_as_ancestor (GST_OBJECT_CAST (group->audio_sink), - GST_OBJECT_CAST (playbin->playsink))) { - gst_element_set_state (group->audio_sink, GST_STATE_NULL); - } - gst_object_unref (group->audio_sink); - } - group->audio_sink = NULL; - if (group->video_sink) { - if (!gst_object_has_as_ancestor (GST_OBJECT_CAST (group->video_sink), - GST_OBJECT_CAST (playbin->playsink))) { - gst_element_set_state (group->video_sink, GST_STATE_NULL); - } - gst_object_unref (group->video_sink); - } - group->video_sink = NULL; - if (group->text_sink) { - if (!gst_object_has_as_ancestor (GST_OBJECT_CAST (group->text_sink), - GST_OBJECT_CAST (playbin->playsink))) { - gst_element_set_state (group->text_sink, GST_STATE_NULL); - } - gst_object_unref (group->text_sink); - } - group->text_sink = NULL; -#endif - if (group->uridecodebin) { REMOVE_SIGNAL (group->uridecodebin, group->select_stream_id); REMOVE_SIGNAL (group->uridecodebin, group->source_setup_id); @@ -4726,12 +3531,6 @@ deactivate_group (GstPlayBin3 * playbin, GstSourceGroup * group) REMOVE_SIGNAL (group->uridecodebin, group->pad_added_id); REMOVE_SIGNAL (group->uridecodebin, group->pad_removed_id); -#if 0 - REMOVE_SIGNAL (group->urisourcebin, group->autoplug_factories_id); - REMOVE_SIGNAL (group->urisourcebin, group->autoplug_select_id); - REMOVE_SIGNAL (group->urisourcebin, group->autoplug_continue_id); - REMOVE_SIGNAL (group->urisourcebin, group->autoplug_query_id); -#endif } GST_SOURCE_GROUP_UNLOCK (group);