summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Saunier <tsaunier@igalia.com>2021-04-21 22:40:35 -0400
committerTim-Philipp Müller <tim@centricular.com>2021-10-31 13:28:43 +0000
commit90d5b2f8eab2beb0465c80e2034fcdceb351356a (patch)
tree12a5cffa35e303310f9c2cad1bd4548fe4976f5f
parent292f9bdd4da1f44c4a25835065b5e73bb6a091c6 (diff)
downloadgstreamer-plugins-base-90d5b2f8eab2beb0465c80e2034fcdceb351356a.tar.gz
playback: Handle sources with dynamic pads and pads already present
In case we already have a pad but more might be added later we were ignoring the new pads added later, we should track the element new pads and expose them as they are added. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1285>
-rw-r--r--gst/playback/gsturisourcebin.c136
1 files changed, 70 insertions, 66 deletions
diff --git a/gst/playback/gsturisourcebin.c b/gst/playback/gsturisourcebin.c
index b8100d233..b972779e8 100644
--- a/gst/playback/gsturisourcebin.c
+++ b/gst/playback/gsturisourcebin.c
@@ -1624,6 +1624,8 @@ static gboolean
analyse_source (GstURISourceBin * urisrc, gboolean * is_raw,
gboolean * have_out, gboolean * is_dynamic, gboolean use_queue)
{
+ GstElementClass *elemclass;
+ GList *walk;
GstIterator *pads_iter;
gboolean done = FALSE;
gboolean res = TRUE;
@@ -1695,26 +1697,20 @@ analyse_source (GstURISourceBin * urisrc, gboolean * is_raw,
gst_iterator_free (pads_iter);
gst_caps_unref (rawcaps);
- if (!*have_out) {
- GstElementClass *elemclass;
- GList *walk;
-
- /* element has no output pads, check for padtemplates that list SOMETIMES
- * pads. */
- elemclass = GST_ELEMENT_GET_CLASS (urisrc->source);
-
- walk = gst_element_class_get_pad_template_list (elemclass);
- while (walk != NULL) {
- GstPadTemplate *templ;
-
- templ = (GstPadTemplate *) walk->data;
- if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) {
- if (GST_PAD_TEMPLATE_PRESENCE (templ) == GST_PAD_SOMETIMES)
- *is_dynamic = TRUE;
- break;
- }
- walk = g_list_next (walk);
+ /* check for padtemplates that list SOMETIMES pads to check
+ * check if it is dynamic. */
+ elemclass = GST_ELEMENT_GET_CLASS (urisrc->source);
+ walk = gst_element_class_get_pad_template_list (elemclass);
+ while (walk != NULL) {
+ GstPadTemplate *templ;
+
+ templ = (GstPadTemplate *) walk->data;
+ if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) {
+ if (GST_PAD_TEMPLATE_PRESENCE (templ) == GST_PAD_SOMETIMES)
+ *is_dynamic = TRUE;
+ break;
}
+ walk = g_list_next (walk);
}
return res;
@@ -2158,62 +2154,70 @@ setup_source (GstURISourceBin * urisrc)
urisrc->need_queue && urisrc->use_buffering))
goto invalid_source;
- if (is_raw) {
- GST_DEBUG_OBJECT (urisrc, "Source provides all raw data");
- /* source provides raw data, we added the pads and we can now signal a
- * no_more pads because we are done. */
- gst_element_no_more_pads (GST_ELEMENT_CAST (urisrc));
- return TRUE;
- }
- if (!have_out && !is_dynamic) {
- GST_DEBUG_OBJECT (urisrc, "Source has no output pads");
- return TRUE;
- }
- if (is_dynamic) {
+ if (!is_dynamic) {
+ if (is_raw) {
+ GST_DEBUG_OBJECT (urisrc, "Source provides all raw data");
+ /* source provides raw data, we added the pads and we can now signal a
+ * no_more pads because we are done. */
+ gst_element_no_more_pads (GST_ELEMENT_CAST (urisrc));
+ return TRUE;
+ } else if (!have_out) {
+ GST_DEBUG_OBJECT (urisrc, "Source has no output pads");
+
+ return TRUE;
+ }
+ } else {
GST_DEBUG_OBJECT (urisrc, "Source has dynamic output pads");
/* connect a handler for the new-pad signal */
urisrc->src_np_sig_id =
g_signal_connect (urisrc->source, "pad-added",
G_CALLBACK (source_new_pad), urisrc);
+ }
+
+ if (is_raw) {
+ GST_DEBUG_OBJECT (urisrc,
+ "Got raw srcpads on a dynamic source, using them as is.");
+
+ return TRUE;
+ } else if (urisrc->is_stream) {
+ GST_DEBUG_OBJECT (urisrc, "Setting up streaming");
+ /* do the stream things here */
+ if (!setup_typefind (urisrc, NULL))
+ goto streaming_failed;
} else {
- if (urisrc->is_stream) {
- GST_DEBUG_OBJECT (urisrc, "Setting up streaming");
- /* do the stream things here */
- if (!setup_typefind (urisrc, NULL))
- goto streaming_failed;
- } else {
- GstIterator *pads_iter;
- gboolean done = FALSE;
- pads_iter = gst_element_iterate_src_pads (urisrc->source);
- while (!done) {
- GValue item = { 0, };
- GstPad *pad;
-
- switch (gst_iterator_next (pads_iter, &item)) {
- case GST_ITERATOR_ERROR:
- GST_WARNING_OBJECT (urisrc,
- "Error iterating pads on source element");
- /* FALLTHROUGH */
- case GST_ITERATOR_DONE:
- done = TRUE;
- break;
- case GST_ITERATOR_RESYNC:
- /* reset results and resync */
- gst_iterator_resync (pads_iter);
- break;
- case GST_ITERATOR_OK:
- pad = g_value_get_object (&item);
- if (!setup_typefind (urisrc, pad)) {
- gst_iterator_free (pads_iter);
- goto streaming_failed;
- }
- g_value_reset (&item);
- break;
- }
+ GstIterator *pads_iter;
+ gboolean done = FALSE;
+
+ /* Expose all non-raw srcpads */
+ pads_iter = gst_element_iterate_src_pads (urisrc->source);
+ while (!done) {
+ GValue item = { 0, };
+ GstPad *pad;
+
+ switch (gst_iterator_next (pads_iter, &item)) {
+ case GST_ITERATOR_ERROR:
+ GST_WARNING_OBJECT (urisrc, "Error iterating pads on source element");
+ /* FALLTHROUGH */
+ case GST_ITERATOR_DONE:
+ done = TRUE;
+ break;
+ case GST_ITERATOR_RESYNC:
+ /* reset results and resync */
+ gst_iterator_resync (pads_iter);
+ break;
+ case GST_ITERATOR_OK:
+ pad = g_value_get_object (&item);
+ if (!setup_typefind (urisrc, pad)) {
+ gst_iterator_free (pads_iter);
+ goto streaming_failed;
+ }
+ g_value_reset (&item);
+ break;
}
- gst_iterator_free (pads_iter);
}
+ gst_iterator_free (pads_iter);
}
+
return TRUE;
/* ERRORS */