From 91d987d6b7ac6a5d52a15e2c930526692db95f98 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 23 Oct 2024 15:39:17 +0200 Subject: [PATCH] playback: Improve stream list search There is the possibility than an element/code/helper creates an identical `GstStream` (same type and stream-id) instance instead of re-using a previous one. For those cases, when detecting whether a `GstStream` is already present in a collection, we need to do more checks than just comparing the pointer. Part-of: --- .../gst/playback/gstdecodebin3.c | 3 +- .../gst/playback/gstplaybackutils.c | 34 +++++++++++++++++++ .../gst/playback/gstplaybackutils.h | 8 +++-- .../gst/playback/gsturisourcebin.c | 5 +-- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/subprojects/gst-plugins-base/gst/playback/gstdecodebin3.c b/subprojects/gst-plugins-base/gst/playback/gstdecodebin3.c index b2311ea4d3..c7daaca67e 100644 --- a/subprojects/gst-plugins-base/gst/playback/gstdecodebin3.c +++ b/subprojects/gst-plugins-base/gst/playback/gstdecodebin3.c @@ -27,6 +27,7 @@ #include #include "gstplaybackelements.h" +#include "gstplaybackutils.h" #include "gstrawcaps.h" /** @@ -2636,7 +2637,7 @@ get_merged_collection (GstDecodebin3 * dbin) GstStream *stream = gst_stream_collection_get_stream (input->collection, i); /* Only add if not already present in the list */ - if (!g_list_find (unsorted_streams, stream)) + if (!gst_playback_utils_stream_in_list (unsorted_streams, stream)) unsorted_streams = g_list_append (unsorted_streams, stream); } } diff --git a/subprojects/gst-plugins-base/gst/playback/gstplaybackutils.c b/subprojects/gst-plugins-base/gst/playback/gstplaybackutils.c index 996245a891..3b2fa50d43 100644 --- a/subprojects/gst-plugins-base/gst/playback/gstplaybackutils.c +++ b/subprojects/gst-plugins-base/gst/playback/gstplaybackutils.c @@ -162,3 +162,37 @@ gst_playback_utils_compare_factories_func (gconstpointer p1, gconstpointer p2) * and then by factory name */ return gst_plugin_feature_rank_compare_func (p1, p2); } + +/* gst_playback_utils_stream_in_list: + * @streams: A list of #GstStream + * @stream: A #GstStream + * + * Searchs whether the given @stream is present in @streams. This also handles + * the case where the actual @stream was rewritten but contains the same + * stream-id and type. + * + * Returns: TRUE if @stream is in @streams. + * + **/ +gboolean +gst_playback_utils_stream_in_list (GList * streams, GstStream * stream) +{ + GList *iter; + const gchar *stream_id = gst_stream_get_stream_id (stream); + GstStreamType stream_type = gst_stream_get_stream_type (stream); + + for (iter = streams; iter; iter = iter->next) { + GstStream *cand = iter->data; + + if (iter->data == stream) + return TRUE; + /* Compare the stream type */ + if (gst_stream_get_stream_type (cand) != stream_type) + continue; + /* Compare the stream-id */ + if (!g_strcmp0 (stream_id, gst_stream_get_stream_id (cand))) + return TRUE; + } + + return FALSE; +} diff --git a/subprojects/gst-plugins-base/gst/playback/gstplaybackutils.h b/subprojects/gst-plugins-base/gst/playback/gstplaybackutils.h index d7f67008e6..7ecf3f1d87 100644 --- a/subprojects/gst-plugins-base/gst/playback/gstplaybackutils.h +++ b/subprojects/gst-plugins-base/gst/playback/gstplaybackutils.h @@ -34,8 +34,12 @@ gst_playback_utils_get_n_common_capsfeatures (GstElementFactory * fact1, GstPlayFlags flags, gboolean isaudioelement); G_GNUC_INTERNAL -gint -gst_playback_utils_compare_factories_func (gconstpointer p1, gconstpointer p2); +gint gst_playback_utils_compare_factories_func(gconstpointer p1, + gconstpointer p2); + +G_GNUC_INTERNAL +gboolean gst_playback_utils_stream_in_list(GList *streams, GstStream *stream); + G_END_DECLS #endif /* __GST_PLAYBACK_UTILS_H__ */ diff --git a/subprojects/gst-plugins-base/gst/playback/gsturisourcebin.c b/subprojects/gst-plugins-base/gst/playback/gsturisourcebin.c index 0d24b00b74..bf8ba01ec0 100644 --- a/subprojects/gst-plugins-base/gst/playback/gsturisourcebin.c +++ b/subprojects/gst-plugins-base/gst/playback/gsturisourcebin.c @@ -2896,7 +2896,8 @@ handle_parsebin_collection (ChildSrcPadInfo * info, for (iter = info->outputs; iter; iter = iter->next) { OutputSlotInfo *output = iter->data; - if (output->stream && !g_list_find (streams, output->stream)) { + if (output->stream + && !gst_playback_utils_stream_in_list (streams, output->stream)) { GST_DEBUG_OBJECT (output->originating_pad, "No longer used in new collection"); unused_slots = g_list_append (unused_slots, output); @@ -2973,7 +2974,7 @@ uri_source_bin_aggregate_collection (GstURISourceBin * urisrc) for (i = 0; i < len; i++) { GstStream *stream = gst_stream_collection_get_stream (info->collection, i); - if (!g_list_find (streams, stream)) { + if (!gst_playback_utils_stream_in_list (streams, stream)) { streams = g_list_append (streams, stream); } }