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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7716>
This commit is contained in:
Edward Hervey 2024-10-23 15:39:17 +02:00 committed by GStreamer Marge Bot
parent 0fda426656
commit 39c770af90
4 changed files with 45 additions and 5 deletions

View file

@ -27,6 +27,7 @@
#include <gst/pbutils/pbutils.h> #include <gst/pbutils/pbutils.h>
#include "gstplaybackelements.h" #include "gstplaybackelements.h"
#include "gstplaybackutils.h"
#include "gstrawcaps.h" #include "gstrawcaps.h"
/** /**
@ -2521,7 +2522,7 @@ get_merged_collection (GstDecodebin3 * dbin)
GstStream *stream = GstStream *stream =
gst_stream_collection_get_stream (input->collection, i); gst_stream_collection_get_stream (input->collection, i);
/* Only add if not already present in the list */ /* 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); unsorted_streams = g_list_append (unsorted_streams, stream);
} }
} }

View file

@ -162,3 +162,37 @@ gst_playback_utils_compare_factories_func (gconstpointer p1, gconstpointer p2)
* and then by factory name */ * and then by factory name */
return gst_plugin_feature_rank_compare_func (p1, p2); 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;
}

View file

@ -34,8 +34,12 @@ gst_playback_utils_get_n_common_capsfeatures (GstElementFactory * fact1,
GstPlayFlags flags, GstPlayFlags flags,
gboolean isaudioelement); gboolean isaudioelement);
G_GNUC_INTERNAL G_GNUC_INTERNAL
gint gint gst_playback_utils_compare_factories_func(gconstpointer p1,
gst_playback_utils_compare_factories_func (gconstpointer p1, gconstpointer p2); gconstpointer p2);
G_GNUC_INTERNAL
gboolean gst_playback_utils_stream_in_list(GList *streams, GstStream *stream);
G_END_DECLS G_END_DECLS
#endif /* __GST_PLAYBACK_UTILS_H__ */ #endif /* __GST_PLAYBACK_UTILS_H__ */

View file

@ -2896,7 +2896,8 @@ handle_parsebin_collection (ChildSrcPadInfo * info,
for (iter = info->outputs; iter; iter = iter->next) { for (iter = info->outputs; iter; iter = iter->next) {
OutputSlotInfo *output = iter->data; 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, GST_DEBUG_OBJECT (output->originating_pad,
"No longer used in new collection"); "No longer used in new collection");
unused_slots = g_list_append (unused_slots, output); 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++) { for (i = 0; i < len; i++) {
GstStream *stream = GstStream *stream =
gst_stream_collection_get_stream (info->collection, i); 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); streams = g_list_append (streams, stream);
} }
} }