playback: Improve stream list search
authorEdward Hervey <edward@centricular.com>
Wed, 23 Oct 2024 13:39:17 +0000 (15:39 +0200)
committerBackport Bot <gitlab-backport-bot@gstreamer-foundation.org>
Mon, 28 Oct 2024 13:15:41 +0000 (13:15 +0000)
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/7764>

subprojects/gst-plugins-base/gst/playback/gstdecodebin3.c
subprojects/gst-plugins-base/gst/playback/gstplaybackutils.c
subprojects/gst-plugins-base/gst/playback/gstplaybackutils.h
subprojects/gst-plugins-base/gst/playback/gsturisourcebin.c

index b2311ea4d30b5436ad0dd5fb9abe314095619c03..c7daaca67ed78f7eb70a6a3c6909c2d60d00cf7b 100644 (file)
@@ -27,6 +27,7 @@
 #include <gst/pbutils/pbutils.h>
 
 #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);
       }
     }
index 996245a89164f6e8220f31ce333f17fe1ac7da91..3b2fa50d43a31d7c1c0744a706b57ef3d4172a72 100644 (file)
@@ -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;
+}
index d7f67008e68ffee4764798f6dc60b68b8ca180fd..7ecf3f1d87c7deea5856f9d2c3262444bc28fdb5 100644 (file)
@@ -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__ */
index 0d24b00b74354fd92d46c7367a5110471d9129cd..bf8ba01ec0341c15e849763b21f8a660ee935a9e 100644 (file)
@@ -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);
         }
       }