inputselector: Avoid deadlock when shutting down
authorVivia Nikolaidou <vivia@ahiru.eu>
Thu, 2 Mar 2023 13:51:08 +0000 (15:51 +0200)
committerTim-Philipp Müller <tim@centricular.com>
Thu, 2 Mar 2023 15:42:15 +0000 (15:42 +0000)
Transition from PLAYING to PAUSED unschedules any pending clock wait,
but there was no guard that prevented another input buffer then waiting
again while in PAUSED before dataflow stops. Use a new `playing` flag to
avoid this, and exit the chain function if instead of playing we're now
flushing. Basically the same as the clocksync element.

Closes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1772

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4099>

subprojects/gstreamer/plugins/elements/gstinputselector.c
subprojects/gstreamer/plugins/elements/gstinputselector.h

index ac8470e..6f6796c 100644 (file)
@@ -853,6 +853,13 @@ gst_input_selector_wait_running_time (GstInputSelector * sel,
         continue;
       }
 
+      if (!sel->playing) {
+        GST_DEBUG_OBJECT (selpad, "Waiting for playing");
+        GST_INPUT_SELECTOR_WAIT (sel);
+        GST_DEBUG_OBJECT (selpad, "Done waiting");
+        continue;
+      }
+
       /* FIXME: If no upstream latency was queried yet, do one now */
       clock_id =
           gst_clock_new_single_shot_id (clock,
@@ -1432,6 +1439,7 @@ gst_input_selector_init (GstInputSelector * sel)
   g_mutex_init (&sel->lock);
   g_cond_init (&sel->cond);
   sel->eos = FALSE;
+  sel->playing = FALSE;
 
   sel->upstream_latency = 0;
   sel->last_output_ts = GST_CLOCK_TIME_NONE;
@@ -2029,6 +2037,12 @@ gst_input_selector_change_state (GstElement * element,
       GST_INPUT_SELECTOR_BROADCAST (self);
       GST_INPUT_SELECTOR_UNLOCK (self);
       break;
+    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:{
+      GST_INPUT_SELECTOR_LOCK (self);
+      self->playing = TRUE;
+      GST_INPUT_SELECTOR_BROADCAST (self);
+      GST_INPUT_SELECTOR_UNLOCK (self);
+    }
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:{
       GList *walk;
 
@@ -2052,6 +2066,10 @@ gst_input_selector_change_state (GstElement * element,
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       gst_input_selector_reset (self);
       break;
+    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+      GST_INPUT_SELECTOR_LOCK (self);
+      self->playing = FALSE;
+      GST_INPUT_SELECTOR_UNLOCK (self);
     default:
       break;
   }
index 039f628..35e008b 100644 (file)
@@ -81,6 +81,7 @@ struct _GstInputSelector {
   gboolean eos;
   gboolean eos_sent;
   gboolean flushing;
+  gboolean playing;
 
   GstClockTime upstream_latency;
   GstClockTime last_output_ts;