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/1120>
This commit is contained in:
Thibault Saunier 2021-04-21 22:40:35 -04:00 committed by GStreamer Marge Bot
parent 2e13d97dd6
commit 3f5d580f4e

View file

@ -1630,6 +1630,8 @@ static gboolean
analyse_source (GstURISourceBin * urisrc, gboolean * is_raw, analyse_source (GstURISourceBin * urisrc, gboolean * is_raw,
gboolean * have_out, gboolean * is_dynamic, gboolean use_queue) gboolean * have_out, gboolean * is_dynamic, gboolean use_queue)
{ {
GstElementClass *elemclass;
GList *walk;
GstIterator *pads_iter; GstIterator *pads_iter;
gboolean done = FALSE; gboolean done = FALSE;
gboolean res = TRUE; gboolean res = TRUE;
@ -1701,14 +1703,9 @@ analyse_source (GstURISourceBin * urisrc, gboolean * is_raw,
gst_iterator_free (pads_iter); gst_iterator_free (pads_iter);
gst_caps_unref (rawcaps); gst_caps_unref (rawcaps);
if (!*have_out) { /* check for padtemplates that list SOMETIMES pads to check
GstElementClass *elemclass; * check if it is dynamic. */
GList *walk;
/* element has no output pads, check for padtemplates that list SOMETIMES
* pads. */
elemclass = GST_ELEMENT_GET_CLASS (urisrc->source); elemclass = GST_ELEMENT_GET_CLASS (urisrc->source);
walk = gst_element_class_get_pad_template_list (elemclass); walk = gst_element_class_get_pad_template_list (elemclass);
while (walk != NULL) { while (walk != NULL) {
GstPadTemplate *templ; GstPadTemplate *templ;
@ -1721,7 +1718,6 @@ analyse_source (GstURISourceBin * urisrc, gboolean * is_raw,
} }
walk = g_list_next (walk); walk = g_list_next (walk);
} }
}
return res; return res;
no_slot: no_slot:
@ -2164,25 +2160,32 @@ setup_source (GstURISourceBin * urisrc)
urisrc->need_queue && urisrc->use_buffering)) urisrc->need_queue && urisrc->use_buffering))
goto invalid_source; goto invalid_source;
if (!is_dynamic) {
if (is_raw) { if (is_raw) {
GST_DEBUG_OBJECT (urisrc, "Source provides all raw data"); GST_DEBUG_OBJECT (urisrc, "Source provides all raw data");
/* source provides raw data, we added the pads and we can now signal a /* source provides raw data, we added the pads and we can now signal a
* no_more pads because we are done. */ * no_more pads because we are done. */
gst_element_no_more_pads (GST_ELEMENT_CAST (urisrc)); gst_element_no_more_pads (GST_ELEMENT_CAST (urisrc));
return TRUE; return TRUE;
} } else if (!have_out) {
if (!have_out && !is_dynamic) {
GST_DEBUG_OBJECT (urisrc, "Source has no output pads"); GST_DEBUG_OBJECT (urisrc, "Source has no output pads");
return TRUE; return TRUE;
} }
if (is_dynamic) { } else {
GST_DEBUG_OBJECT (urisrc, "Source has dynamic output pads"); GST_DEBUG_OBJECT (urisrc, "Source has dynamic output pads");
/* connect a handler for the new-pad signal */ /* connect a handler for the new-pad signal */
urisrc->src_np_sig_id = urisrc->src_np_sig_id =
g_signal_connect (urisrc->source, "pad-added", g_signal_connect (urisrc->source, "pad-added",
G_CALLBACK (source_new_pad), urisrc); G_CALLBACK (source_new_pad), urisrc);
} else { }
if (urisrc->is_stream) {
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"); GST_DEBUG_OBJECT (urisrc, "Setting up streaming");
/* do the stream things here */ /* do the stream things here */
if (!setup_typefind (urisrc, NULL)) if (!setup_typefind (urisrc, NULL))
@ -2190,6 +2193,8 @@ setup_source (GstURISourceBin * urisrc)
} else { } else {
GstIterator *pads_iter; GstIterator *pads_iter;
gboolean done = FALSE; gboolean done = FALSE;
/* Expose all non-raw srcpads */
pads_iter = gst_element_iterate_src_pads (urisrc->source); pads_iter = gst_element_iterate_src_pads (urisrc->source);
while (!done) { while (!done) {
GValue item = { 0, }; GValue item = { 0, };
@ -2197,8 +2202,7 @@ setup_source (GstURISourceBin * urisrc)
switch (gst_iterator_next (pads_iter, &item)) { switch (gst_iterator_next (pads_iter, &item)) {
case GST_ITERATOR_ERROR: case GST_ITERATOR_ERROR:
GST_WARNING_OBJECT (urisrc, GST_WARNING_OBJECT (urisrc, "Error iterating pads on source element");
"Error iterating pads on source element");
/* FALLTHROUGH */ /* FALLTHROUGH */
case GST_ITERATOR_DONE: case GST_ITERATOR_DONE:
done = TRUE; done = TRUE;
@ -2219,7 +2223,7 @@ setup_source (GstURISourceBin * urisrc)
} }
gst_iterator_free (pads_iter); gst_iterator_free (pads_iter);
} }
}
return TRUE; return TRUE;
/* ERRORS */ /* ERRORS */