urisourcebin: Set source element to READY before querying it

Generating the source element is done when urisourcebin is doing the READY to
PAUSED state change, so it is reasonable to set the new source element to that
state.

This also allows detecting early failures with backing libraries or
hardware (checks done in NULL->READY).

Finally it makes more sense to have an element in READY when attempting to query
information from it (such as SCHEDULING queries or probing live-ness).

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5058>
This commit is contained in:
Edward Hervey 2023-01-31 16:12:17 +01:00 committed by GStreamer Marge Bot
parent 3e541953f8
commit 1ee26b0a7a

View file

@ -1465,8 +1465,6 @@ gen_source_element (GstURISourceBin * urisrc)
GObjectClass *source_class;
GstElement *source;
GParamSpec *pspec;
GstQuery *query;
GstSchedulingFlags flags;
GError *err = NULL;
if (!urisrc->uri)
@ -1486,31 +1484,9 @@ gen_source_element (GstURISourceBin * urisrc)
GST_LOG_OBJECT (urisrc, "found source type %s", G_OBJECT_TYPE_NAME (source));
urisrc->is_stream = IS_STREAM_URI (urisrc->uri);
query = gst_query_new_scheduling ();
if (gst_element_query (source, query)) {
gst_query_parse_scheduling (query, &flags, NULL, NULL, NULL);
if ((flags & GST_SCHEDULING_FLAG_BANDWIDTH_LIMITED))
urisrc->is_stream = TRUE;
}
gst_query_unref (query);
source_class = G_OBJECT_GET_CLASS (source);
if (urisrc->is_stream) {
/* Live sources are not streamable */
pspec = g_object_class_find_property (source_class, "is-live");
if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN) {
gboolean is_live;
g_object_get (G_OBJECT (source), "is-live", &is_live, NULL);
if (is_live)
urisrc->is_stream = FALSE;
}
}
GST_LOG_OBJECT (urisrc, "source is stream: %d", urisrc->is_stream);
/* Propagate connection speed */
pspec = g_object_class_find_property (source_class, "connection-speed");
if (pspec != NULL) {
guint64 speed = urisrc->connection_speed / 1000;
@ -1750,6 +1726,38 @@ analyse_source_and_expose_raw_pads (GstURISourceBin * urisrc,
GstIterator *pads_iter;
gboolean res = TRUE;
/* Collect generic information about the source */
urisrc->is_stream = IS_STREAM_URI (urisrc->uri);
if (!urisrc->is_stream) {
GstQuery *query;
GstSchedulingFlags flags;
/* do a final check to see if the source element is streamable */
query = gst_query_new_scheduling ();
if (gst_element_query (urisrc->source, query)) {
gst_query_parse_scheduling (query, &flags, NULL, NULL, NULL);
if ((flags & GST_SCHEDULING_FLAG_BANDWIDTH_LIMITED))
urisrc->is_stream = TRUE;
}
gst_query_unref (query);
}
if (urisrc->is_stream) {
GObjectClass *source_class = G_OBJECT_GET_CLASS (urisrc->source);
GParamSpec *pspec = g_object_class_find_property (source_class, "is-live");
/* Live sources are not streamable */
if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN) {
gboolean is_live;
g_object_get (G_OBJECT (urisrc->source), "is-live", &is_live, NULL);
if (is_live)
urisrc->is_stream = FALSE;
}
}
GST_LOG_OBJECT (urisrc, "source is stream: %d", urisrc->is_stream);
/* Handle the existing source pads */
pads_iter = gst_element_iterate_src_pads (urisrc->source);
restart:
@ -2285,12 +2293,16 @@ setup_source (GstURISourceBin * urisrc)
* handled by the application right after. */
gst_bin_add (GST_BIN_CAST (urisrc), urisrc->source);
/* notify of the new source used */
/* notify of the new source used and allow external users to do final
* modifications before activating the element */
g_object_notify (G_OBJECT (urisrc), "source");
g_signal_emit (urisrc, gst_uri_source_bin_signals[SIGNAL_SOURCE_SETUP],
0, urisrc->source);
if (gst_element_set_state (urisrc->source,
GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS)
goto state_fail;
/* see if the source element emits raw audio/video all by itself,
* if so, we can create streams for the pads and be done with it.
* Also check that is has source pads, if not, we assume it will
@ -2323,6 +2335,12 @@ invalid_source:
(_("Source element is invalid.")), (NULL));
return FALSE;
}
state_fail:
{
GST_ELEMENT_ERROR (urisrc, CORE, FAILED,
(_("Source element can't be prepared")), (NULL));
return FALSE;
}
no_pads:
{
GST_ELEMENT_ERROR (urisrc, CORE, FAILED,