From 1c4950718f0b2ff6abbf14bee472316d7cfb1ea7 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 7 Sep 2022 10:36:09 -0400 Subject: [PATCH] discoverer: Fix discovering source that expose raw audio/video Exposes a "uridecodebin:post-stream-topology" property as the discoverer needs to have topology information about all streams so we need `uridecodebin` to always plug decodebins for that case. Part-of: --- .../docs/plugins/gst_plugins_cache.json | 12 +++++++ .../gst-libs/gst/pbutils/gstdiscoverer.c | 30 ++-------------- .../gst/playback/gsturidecodebin.c | 36 ++++++++++++++++--- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json b/subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json index 5014d23d01..8828acea98 100644 --- a/subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json +++ b/subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json @@ -11097,6 +11097,18 @@ "type": "gboolean", "writable": true }, + "post-stream-topology": { + "blurb": "Post stream-topology messages", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": true + }, "ring-buffer-max-size": { "blurb": "Max. amount of data in the ring buffer (bytes, 0 = ring buffer disabled)", "conditionally-available": false, diff --git a/subprojects/gst-plugins-base/gst-libs/gst/pbutils/gstdiscoverer.c b/subprojects/gst-plugins-base/gst-libs/gst/pbutils/gstdiscoverer.c index 5075fe3f6d..bd5feeef72 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/pbutils/gstdiscoverer.c @@ -127,8 +127,6 @@ struct _GstDiscovererPrivate GstElement *uridecodebin; GstBus *bus; - GType decodebin_type; - /* Custom main context variables */ GMainContext *ctx; GSource *bus_source; @@ -142,7 +140,6 @@ struct _GstDiscovererPrivate gulong pad_remove_id; gulong no_more_pads_id; gulong source_chg_id; - gulong element_added_id; gulong bus_cb_id; gboolean use_cache; @@ -328,22 +325,9 @@ gst_discoverer_class_init (GstDiscovererClass * klass) NULL, NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_ELEMENT); } -static void -uridecodebin_element_added_cb (GstElement * uridecodebin, - GstElement * child, GstDiscoverer * dc) -{ - GST_DEBUG ("New element added to uridecodebin : %s", - GST_ELEMENT_NAME (child)); - - if (G_OBJECT_TYPE (child) == dc->priv->decodebin_type) { - g_object_set (child, "post-stream-topology", TRUE, NULL); - } -} - static void gst_discoverer_init (GstDiscoverer * dc) { - GstElement *tmp; GstFormat format = GST_FORMAT_TIME; dc->priv = gst_discoverer_get_instance_private (dc); @@ -372,6 +356,9 @@ gst_discoverer_init (GstDiscoverer * dc) GST_ERROR ("Can't create uridecodebin"); return; } + + g_object_set (dc->priv->uridecodebin, "post-stream-topology", TRUE, NULL); + GST_LOG_OBJECT (dc, "Adding uridecodebin to pipeline"); gst_bin_add (dc->priv->pipeline, dc->priv->uridecodebin); @@ -397,16 +384,6 @@ gst_discoverer_init (GstDiscoverer * dc) GST_DEBUG_OBJECT (dc, "Done initializing Discoverer"); - /* This is ugly. We get the GType of decodebin so we can quickly detect - * when a decodebin is added to uridecodebin so we can set the - * post-stream-topology setting to TRUE */ - dc->priv->element_added_id = - g_signal_connect_object (dc->priv->uridecodebin, "element-added", - G_CALLBACK (uridecodebin_element_added_cb), dc, 0); - tmp = gst_element_factory_make ("decodebin", NULL); - dc->priv->decodebin_type = G_OBJECT_TYPE (tmp); - gst_object_unref (tmp); - /* create queries */ dc->priv->seeking_query = gst_query_new_seeking (format); } @@ -447,7 +424,6 @@ gst_discoverer_dispose (GObject * obj) DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->pad_remove_id); DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->no_more_pads_id); DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->source_chg_id); - DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->element_added_id); DISCONNECT_SIGNAL (dc->priv->bus, dc->priv->bus_cb_id); /* pipeline was set to NULL in _reset */ diff --git a/subprojects/gst-plugins-base/gst/playback/gsturidecodebin.c b/subprojects/gst-plugins-base/gst/playback/gsturidecodebin.c index 87f02682c1..a128d92217 100644 --- a/subprojects/gst-plugins-base/gst/playback/gsturidecodebin.c +++ b/subprojects/gst-plugins-base/gst/playback/gsturidecodebin.c @@ -119,6 +119,7 @@ struct _GstURIDecodeBin gboolean expose_allstreams; /* Whether to expose unknown type streams or not */ guint64 ring_buffer_max_size; /* 0 means disabled */ + gboolean post_stream_topology; }; struct _GstURIDecodeBinClass @@ -186,6 +187,7 @@ enum #define DEFAULT_FORCE_SW_DECODERS FALSE #define DEFAULT_EXPOSE_ALL_STREAMS TRUE #define DEFAULT_RING_BUFFER_MAX_SIZE 0 +#define DEFAULT_POST_STREAM_TOPOLOGY FALSE enum { @@ -201,7 +203,8 @@ enum PROP_USE_BUFFERING, PROP_FORCE_SW_DECODERS, PROP_EXPOSE_ALL_STREAMS, - PROP_RING_BUFFER_MAX_SIZE + PROP_RING_BUFFER_MAX_SIZE, + PROP_POST_STREAM_TOPOLOGY }; static guint gst_uri_decode_bin_signals[LAST_SIGNAL] = { 0 }; @@ -529,6 +532,19 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) 0, G_MAXUINT, DEFAULT_RING_BUFFER_MAX_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstURIDecodeBin:post-stream-topology + * + * Post stream-topology messages on the bus every time the topology changes. + * + * Since: 1.22 + */ + g_object_class_install_property (gobject_class, PROP_POST_STREAM_TOPOLOGY, + g_param_spec_boolean ("post-stream-topology", "Post Stream Topology", + "Post stream-topology messages", + DEFAULT_POST_STREAM_TOPOLOGY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstURIDecodeBin::unknown-type: * @bin: The uridecodebin. @@ -850,6 +866,9 @@ gst_uri_decode_bin_set_property (GObject * object, guint prop_id, case PROP_RING_BUFFER_MAX_SIZE: dec->ring_buffer_max_size = g_value_get_uint64 (value); break; + case PROP_POST_STREAM_TOPOLOGY: + dec->post_stream_topology = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -913,6 +932,9 @@ gst_uri_decode_bin_get_property (GObject * object, guint prop_id, case PROP_RING_BUFFER_MAX_SIZE: g_value_set_uint64 (value, dec->ring_buffer_max_size); break; + case PROP_POST_STREAM_TOPOLOGY: + g_value_set_boolean (value, dec->post_stream_topology); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1879,9 +1901,11 @@ make_decoder (GstURIDecodeBin * decoder) if (decoder->caps) g_object_set (decodebin, "caps", decoder->caps, NULL); - /* Propagate expose-all-streams and connection-speed properties */ + /* Propagate expose-all-streams, connection-speed properties + * and post_stream_topology */ g_object_set (decodebin, "expose-all-streams", decoder->expose_allstreams, - "connection-speed", decoder->connection_speed / 1000, NULL); + "connection-speed", decoder->connection_speed / 1000, + "post-stream-topology", decoder->post_stream_topology, NULL); if (!decoder->is_stream || decoder->is_adaptive) { /* propagate the use-buffering property but only when we are not already @@ -2176,8 +2200,10 @@ source_new_pad (GstElement * element, GstPad * pad, GstURIDecodeBin * bin) if (!rawcaps) rawcaps = DEFAULT_CAPS; - /* if this is a pad with all raw caps, we can expose it */ - if (has_raw_caps (pad, rawcaps)) { + /* if this is a pad with all raw caps, we can expose it. + * But if stream-topology needs to be posted, we need to + * plug a decodebin so it can build the topology for us to forward. */ + if (!bin->post_stream_topology && has_raw_caps (pad, rawcaps)) { /* it's all raw, create output pads. */ GST_URI_DECODE_BIN_UNLOCK (bin); gst_caps_unref (rawcaps);