decodebin3: Don't leak collection when releasing inputs 72/309072/2 accepted/tizen/7.0/unified/20240409.152243
authorEdward Hervey <edward@centricular.com>
Mon, 7 Nov 2022 08:49:02 +0000 (09:49 +0100)
committerEunhye Choi <eunhae1.choi@samsung.com>
Thu, 4 Apr 2024 09:25:02 +0000 (18:25 +0900)
And refactor the function slightly for clarity

Change-Id: Ie8781b7d5d4f409434b628c343082a7c137c7ae2
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2784>

packaging/gstreamer.spec
subprojects/gst-plugins-base/gst/playback/gstdecodebin3.c

index 36b864c357a20f3080e23d0c37fe0295ed5cec8d..934467ade837a2b8daceaa9d4178881b822f5fce 100644 (file)
@@ -62,7 +62,7 @@
 
 Name:           %{_name}
 Version:        1.20.0
-Release:        57
+Release:        58
 Summary:        Streaming-Media Framework Runtime
 License:        LGPL-2.0+
 Group:          Multimedia/Framework
index fb4bc63fcd62c9b502b64bcba6949914d03e3003..880a48a1b75b45b9fd92707aa2414bd02481bf8e 100644 (file)
@@ -1000,6 +1000,9 @@ gst_decodebin3_input_pad_unlink (GstPad * pad, GstObject * parent)
 {
   GstDecodebin3 *dbin = (GstDecodebin3 *) parent;
   DecodebinInput *input;
+  GstStreamCollection *collection = NULL;
+  gulong probe_id = 0;
+  GstMessage *msg;
 
   GST_LOG_OBJECT (parent, "Got unlink on input pad %" GST_PTR_FORMAT
       ". Removing parsebin.", pad);
@@ -1008,62 +1011,68 @@ gst_decodebin3_input_pad_unlink (GstPad * pad, GstObject * parent)
     goto fail;
 
   INPUT_LOCK (dbin);
-  if (input->parsebin == NULL) {
+  if (input->parsebin == NULL ||
+      GST_OBJECT_PARENT (GST_OBJECT (input->parsebin)) != GST_OBJECT (dbin)) {
     INPUT_UNLOCK (dbin);
     return;
   }
 
-  if (GST_OBJECT_PARENT (GST_OBJECT (input->parsebin)) == GST_OBJECT (dbin)) {
-    GstStreamCollection *collection = NULL;
-    gulong probe_id = gst_pad_add_probe (input->parsebin_sink,
-        GST_PAD_PROBE_TYPE_QUERY_UPSTREAM,
-        (GstPadProbeCallback) query_duration_drop_probe, input, NULL);
+  /* Clear stream-collection corresponding to current INPUT and post new
+   * stream-collection message, if needed */
+  if (input->collection) {
+    gst_object_unref (input->collection);
+    input->collection = NULL;
+  }
 
-    /* Clear stream-collection corresponding to current INPUT and post new
-     * stream-collection message, if needed */
-    if (input->collection) {
-      gst_object_unref (input->collection);
-      input->collection = NULL;
-    }
+  SELECTION_LOCK (dbin);
+  collection = get_merged_collection (dbin);
+  if (!collection) {
+    SELECTION_UNLOCK (dbin);
+    goto beach;
+  }
+  if (collection == dbin->collection) {
+    SELECTION_UNLOCK (dbin);
+    gst_object_unref (collection);
+    goto beach;
+  }
 
-    SELECTION_LOCK (dbin);
-    collection = get_merged_collection (dbin);
-    if (collection && collection != dbin->collection) {
-      GstMessage *msg;
-      GST_DEBUG_OBJECT (dbin, "Update Stream Collection");
+  GST_DEBUG_OBJECT (dbin, "Update Stream Collection");
 
-      if (dbin->collection)
-        gst_object_unref (dbin->collection);
-      dbin->collection = collection;
-      dbin->select_streams_seqnum = GST_SEQNUM_INVALID;
+  if (dbin->collection)
+    gst_object_unref (dbin->collection);
+  dbin->collection = collection;
+  dbin->select_streams_seqnum = GST_SEQNUM_INVALID;
 
-      msg =
-          gst_message_new_stream_collection ((GstObject *) dbin,
-          dbin->collection);
+  msg =
+      gst_message_new_stream_collection ((GstObject *) dbin, dbin->collection);
 
-      SELECTION_UNLOCK (dbin);
-      gst_element_post_message (GST_ELEMENT_CAST (dbin), msg);
-      update_requested_selection (dbin);
-    } else
-      SELECTION_UNLOCK (dbin);
+  /* Drop duration queries that the application might be doing while this message is posted */
+  probe_id = gst_pad_add_probe (input->parsebin_sink,
+      GST_PAD_PROBE_TYPE_QUERY_UPSTREAM,
+      (GstPadProbeCallback) query_duration_drop_probe, input, NULL);
 
-    gst_bin_remove (GST_BIN (dbin), input->parsebin);
-    gst_element_set_state (input->parsebin, GST_STATE_NULL);
-    g_signal_handler_disconnect (input->parsebin, input->pad_removed_sigid);
-    g_signal_handler_disconnect (input->parsebin, input->pad_added_sigid);
-    g_signal_handler_disconnect (input->parsebin, input->drained_sigid);
-    gst_pad_remove_probe (input->parsebin_sink, probe_id);
-    gst_object_unref (input->parsebin);
-    gst_object_unref (input->parsebin_sink);
+  SELECTION_UNLOCK (dbin);
+  gst_element_post_message (GST_ELEMENT_CAST (dbin), msg);
+  update_requested_selection (dbin);
 
-    input->parsebin = NULL;
-    input->parsebin_sink = NULL;
+  gst_bin_remove (GST_BIN (dbin), input->parsebin);
+  gst_element_set_state (input->parsebin, GST_STATE_NULL);
+  g_signal_handler_disconnect (input->parsebin, input->pad_removed_sigid);
+  g_signal_handler_disconnect (input->parsebin, input->pad_added_sigid);
+  g_signal_handler_disconnect (input->parsebin, input->drained_sigid);
+  gst_pad_remove_probe (input->parsebin_sink, probe_id);
+  gst_object_unref (input->parsebin);
+  gst_object_unref (input->parsebin_sink);
 
-    if (!input->is_main) {
-      dbin->other_inputs = g_list_remove (dbin->other_inputs, input);
-      free_input_async (dbin, input);
-    }
+  input->parsebin = NULL;
+  input->parsebin_sink = NULL;
+
+  if (!input->is_main) {
+    dbin->other_inputs = g_list_remove (dbin->other_inputs, input);
+    free_input_async (dbin, input);
   }
+
+beach:
   INPUT_UNLOCK (dbin);
   return;