Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
thiblahute authored and GStreamer Marge Bot committed May 13, 2021
1 parent 2e13d97 commit 3f5d580
Showing 1 changed file with 70 additions and 66 deletions.
136 changes: 70 additions & 66 deletions gst/playback/gsturisourcebin.c
Expand Up @@ -1630,6 +1630,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;
Expand Down Expand Up @@ -1701,26 +1703,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;
Expand Down Expand Up @@ -2164,62 +2160,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 */
Expand Down

0 comments on commit 3f5d580

Please sign in to comment.