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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3009>
This commit is contained in:
Thibault Saunier 2022-09-07 10:36:09 -04:00 committed by GStreamer Marge Bot
parent 71eda6e2e6
commit 1c4950718f
3 changed files with 46 additions and 32 deletions

View file

@ -11097,6 +11097,18 @@
"type": "gboolean", "type": "gboolean",
"writable": true "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": { "ring-buffer-max-size": {
"blurb": "Max. amount of data in the ring buffer (bytes, 0 = ring buffer disabled)", "blurb": "Max. amount of data in the ring buffer (bytes, 0 = ring buffer disabled)",
"conditionally-available": false, "conditionally-available": false,

View file

@ -127,8 +127,6 @@ struct _GstDiscovererPrivate
GstElement *uridecodebin; GstElement *uridecodebin;
GstBus *bus; GstBus *bus;
GType decodebin_type;
/* Custom main context variables */ /* Custom main context variables */
GMainContext *ctx; GMainContext *ctx;
GSource *bus_source; GSource *bus_source;
@ -142,7 +140,6 @@ struct _GstDiscovererPrivate
gulong pad_remove_id; gulong pad_remove_id;
gulong no_more_pads_id; gulong no_more_pads_id;
gulong source_chg_id; gulong source_chg_id;
gulong element_added_id;
gulong bus_cb_id; gulong bus_cb_id;
gboolean use_cache; gboolean use_cache;
@ -328,22 +325,9 @@ gst_discoverer_class_init (GstDiscovererClass * klass)
NULL, NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_ELEMENT); 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 static void
gst_discoverer_init (GstDiscoverer * dc) gst_discoverer_init (GstDiscoverer * dc)
{ {
GstElement *tmp;
GstFormat format = GST_FORMAT_TIME; GstFormat format = GST_FORMAT_TIME;
dc->priv = gst_discoverer_get_instance_private (dc); dc->priv = gst_discoverer_get_instance_private (dc);
@ -372,6 +356,9 @@ gst_discoverer_init (GstDiscoverer * dc)
GST_ERROR ("Can't create uridecodebin"); GST_ERROR ("Can't create uridecodebin");
return; return;
} }
g_object_set (dc->priv->uridecodebin, "post-stream-topology", TRUE, NULL);
GST_LOG_OBJECT (dc, "Adding uridecodebin to pipeline"); GST_LOG_OBJECT (dc, "Adding uridecodebin to pipeline");
gst_bin_add (dc->priv->pipeline, dc->priv->uridecodebin); 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"); 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 */ /* create queries */
dc->priv->seeking_query = gst_query_new_seeking (format); 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->pad_remove_id);
DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->no_more_pads_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->source_chg_id);
DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->element_added_id);
DISCONNECT_SIGNAL (dc->priv->bus, dc->priv->bus_cb_id); DISCONNECT_SIGNAL (dc->priv->bus, dc->priv->bus_cb_id);
/* pipeline was set to NULL in _reset */ /* pipeline was set to NULL in _reset */

View file

@ -119,6 +119,7 @@ struct _GstURIDecodeBin
gboolean expose_allstreams; /* Whether to expose unknown type streams or not */ gboolean expose_allstreams; /* Whether to expose unknown type streams or not */
guint64 ring_buffer_max_size; /* 0 means disabled */ guint64 ring_buffer_max_size; /* 0 means disabled */
gboolean post_stream_topology;
}; };
struct _GstURIDecodeBinClass struct _GstURIDecodeBinClass
@ -186,6 +187,7 @@ enum
#define DEFAULT_FORCE_SW_DECODERS FALSE #define DEFAULT_FORCE_SW_DECODERS FALSE
#define DEFAULT_EXPOSE_ALL_STREAMS TRUE #define DEFAULT_EXPOSE_ALL_STREAMS TRUE
#define DEFAULT_RING_BUFFER_MAX_SIZE 0 #define DEFAULT_RING_BUFFER_MAX_SIZE 0
#define DEFAULT_POST_STREAM_TOPOLOGY FALSE
enum enum
{ {
@ -201,7 +203,8 @@ enum
PROP_USE_BUFFERING, PROP_USE_BUFFERING,
PROP_FORCE_SW_DECODERS, PROP_FORCE_SW_DECODERS,
PROP_EXPOSE_ALL_STREAMS, 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 }; 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, 0, G_MAXUINT, DEFAULT_RING_BUFFER_MAX_SIZE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 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: * GstURIDecodeBin::unknown-type:
* @bin: The uridecodebin. * @bin: The uridecodebin.
@ -850,6 +866,9 @@ gst_uri_decode_bin_set_property (GObject * object, guint prop_id,
case PROP_RING_BUFFER_MAX_SIZE: case PROP_RING_BUFFER_MAX_SIZE:
dec->ring_buffer_max_size = g_value_get_uint64 (value); dec->ring_buffer_max_size = g_value_get_uint64 (value);
break; break;
case PROP_POST_STREAM_TOPOLOGY:
dec->post_stream_topology = g_value_get_boolean (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -913,6 +932,9 @@ gst_uri_decode_bin_get_property (GObject * object, guint prop_id,
case PROP_RING_BUFFER_MAX_SIZE: case PROP_RING_BUFFER_MAX_SIZE:
g_value_set_uint64 (value, dec->ring_buffer_max_size); g_value_set_uint64 (value, dec->ring_buffer_max_size);
break; break;
case PROP_POST_STREAM_TOPOLOGY:
g_value_set_boolean (value, dec->post_stream_topology);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -1879,9 +1901,11 @@ make_decoder (GstURIDecodeBin * decoder)
if (decoder->caps) if (decoder->caps)
g_object_set (decodebin, "caps", decoder->caps, NULL); 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, 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) { if (!decoder->is_stream || decoder->is_adaptive) {
/* propagate the use-buffering property but only when we are not already /* 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) if (!rawcaps)
rawcaps = DEFAULT_CAPS; rawcaps = DEFAULT_CAPS;
/* if this is a pad with all raw caps, we can expose it */ /* if this is a pad with all raw caps, we can expose it.
if (has_raw_caps (pad, rawcaps)) { * 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. */ /* it's all raw, create output pads. */
GST_URI_DECODE_BIN_UNLOCK (bin); GST_URI_DECODE_BIN_UNLOCK (bin);
gst_caps_unref (rawcaps); gst_caps_unref (rawcaps);