uridecodebin: Don't force floating reference for future reusable decodebin
authorSeungha Yang <seungha@centricular.com>
Tue, 20 Apr 2021 17:05:36 +0000 (02:05 +0900)
committerSeungha Yang <seungha@centricular.com>
Tue, 20 Apr 2021 17:40:06 +0000 (02:40 +0900)
uridecodebin assumes that refcount of decodebins stored in pending_decodebins
are floating but it might not be true in case that refcount of the decodebin
was touched in other places. To avoid the floating refcount issue,
hold strong reference.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1113>

gst/playback/gsturidecodebin.c

index 3837b25b9baa1670d9477cbbeabcf706909334c1..dc6984d9847624ec6239d60ec0191ffacf6f7d64 100644 (file)
@@ -101,7 +101,9 @@ struct _GstURIDecodeBin
   GstElement *queue;
   GstElement *typefind;
   guint have_type_id;           /* have-type signal id from typefind */
+  /* without holding ref */
   GSList *decodebins;
+  /* Holding strong reference to decodebin */
   GSList *pending_decodebins;
   GHashTable *streams;
   guint numpads;
@@ -1690,8 +1692,6 @@ remove_decoders (GstURIDecodeBin * bin, gboolean force)
       caps = DEFAULT_CAPS;
       g_object_set (decoder, "caps", caps, NULL);
       gst_caps_unref (caps);
-      /* make it freshly floating again */
-      g_object_force_floating (G_OBJECT (decoder));
 
       bin->pending_decodebins =
           g_slist_prepend (bin->pending_decodebins, decoder);
@@ -1810,6 +1810,7 @@ static GstElement *
 make_decoder (GstURIDecodeBin * decoder)
 {
   GstElement *decodebin;
+  gboolean unref_dbin = FALSE;
 
   /* re-use pending decodebin */
   if (decoder->pending_decodebins) {
@@ -1818,6 +1819,7 @@ make_decoder (GstURIDecodeBin * decoder)
     decodebin = (GstElement *) first->data;
     decoder->pending_decodebins =
         g_slist_delete_link (decoder->pending_decodebins, first);
+    unref_dbin = TRUE;
   } else {
     GST_LOG_OBJECT (decoder, "making new decodebin");
 
@@ -1900,6 +1902,11 @@ make_decoder (GstURIDecodeBin * decoder)
   gst_bin_add (GST_BIN_CAST (decoder), decodebin);
 
   decoder->decodebins = g_slist_prepend (decoder->decodebins, decodebin);
+  /* Unref if this decodebin came from our pending_decodebins,
+   * since we were holding strong reference to decodebin and gst_bin_add()
+   * will increase refcount */
+  if (unref_dbin)
+    gst_object_unref (decodebin);
 
   return decodebin;