splitmuxsink: Avoid deadlock when releasing a pad from a running muxer
authorVivia Nikolaidou <vivia@ahiru.eu>
Thu, 10 Dec 2020 12:27:49 +0000 (14:27 +0200)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 16 Dec 2020 06:17:08 +0000 (06:17 +0000)
Might not drain correctly

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

gst/multifile/gstsplitmuxsink.c
gst/multifile/gstsplitmuxsink.h

index b6d7f18..093f5a5 100644 (file)
@@ -2768,7 +2768,12 @@ handle_mq_input (GstPad * pad, GstPadProbeInfo * info, MqStreamCtx * ctx)
 
     switch (splitmux->input_state) {
       case SPLITMUX_INPUT_STATE_COLLECTING_GOP_START:
-        if (ctx->is_reference) {
+        if (ctx->is_releasing) {
+          /* The pad belonging to this context is being released */
+          GST_WARNING_OBJECT (pad, "Pad is being released while the muxer is "
+              "running. Data might not drain correctly");
+          loop_again = FALSE;
+        } else if (ctx->is_reference) {
           /* This is the reference context. If it's a keyframe,
            * it marks the start of a new GOP and we should wait in
            * check_completed_gop before continuing, but either way
@@ -3232,6 +3237,9 @@ gst_splitmux_sink_release_pad (GstElement * element, GstPad * pad)
 
   GST_SPLITMUX_LOCK (splitmux);
 
+  ctx->is_releasing = TRUE;
+  GST_SPLITMUX_BROADCAST_INPUT (splitmux);
+
   /* Can release the context now */
   mq_stream_ctx_free (ctx);
   if (ctx == splitmux->reference_ctx)
@@ -3254,6 +3262,10 @@ gst_splitmux_sink_release_pad (GstElement * element, GstPad * pad)
   if (splitmux->contexts == NULL)
     gst_splitmux_reset_elements (splitmux);
 
+  /* Wake up other input streams to check if the completion conditions have
+   * changed */
+  GST_SPLITMUX_BROADCAST_INPUT (splitmux);
+
 fail:
   GST_SPLITMUX_UNLOCK (splitmux);
 }
index 14e4803..dc12182 100644 (file)
@@ -85,6 +85,7 @@ typedef struct _MqStreamCtx
   gboolean out_eos_async_done;
   gboolean need_unblock;
   gboolean caps_change;
+  gboolean is_releasing;
 
   GstSegment in_segment;
   GstSegment out_segment;