omxvideodec: always signal drain cond when stopping streaming loop
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>
Wed, 16 May 2018 15:06:29 +0000 (17:06 +0200)
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>
Fri, 8 Jun 2018 07:47:32 +0000 (09:47 +0200)
If for some reason something goes wrong and we stop the streaming loop
we may end up with other threads still waiting on the drain cond.
No more buffers will be produced by the component so they were waiting
forever.

Fix this by always signalling this cond when stopping the streaming
loop.

https://bugzilla.gnome.org/show_bug.cgi?id=796207

omx/gstomxvideodec.c
omx/gstomxvideodec.h

index 5eb4295..53cc2e2 100644 (file)
@@ -1532,7 +1532,7 @@ copy_frame (const GstVideoInfo * info, GstBuffer * outbuf)
 }
 
 static void
-gst_omx_video_enc_pause_loop (GstOMXVideoDec * self, GstFlowReturn flow_ret)
+gst_omx_video_dec_pause_loop (GstOMXVideoDec * self, GstFlowReturn flow_ret)
 {
   g_mutex_lock (&self->drain_lock);
   if (self->draining) {
@@ -1833,16 +1833,14 @@ component_error:
             gst_omx_component_get_last_error_string (self->dec),
             gst_omx_component_get_last_error (self->dec)));
     gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
-    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
-    self->downstream_flow_ret = GST_FLOW_ERROR;
-    self->started = FALSE;
+    gst_omx_video_dec_pause_loop (self, GST_FLOW_ERROR);
     return;
   }
 
 flushing:
   {
     GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
-    gst_omx_video_enc_pause_loop (self, GST_FLOW_FLUSHING);
+    gst_omx_video_dec_pause_loop (self, GST_FLOW_FLUSHING);
     return;
   }
 
@@ -1887,8 +1885,6 @@ flow_error:
 
       gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self),
           gst_event_new_eos ());
-      gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
-      self->started = FALSE;
     } else if (flow_ret < GST_FLOW_EOS) {
       GST_ELEMENT_ERROR (self, STREAM, FAILED,
           ("Internal data stream error."), ("stream stopped, reason %s",
@@ -1896,12 +1892,10 @@ flow_error:
 
       gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self),
           gst_event_new_eos ());
-      gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
-      self->started = FALSE;
     } else if (flow_ret == GST_FLOW_FLUSHING) {
       GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
-      gst_omx_video_enc_pause_loop (self, flow_ret);
     }
+    gst_omx_video_dec_pause_loop (self, flow_ret);
     GST_VIDEO_DECODER_STREAM_UNLOCK (self);
     return;
   }
@@ -1911,9 +1905,7 @@ reconfigure_error:
     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
         ("Unable to reconfigure output port"));
     gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
-    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
-    self->downstream_flow_ret = GST_FLOW_ERROR;
-    self->started = FALSE;
+    gst_omx_video_dec_pause_loop (self, GST_FLOW_ERROR);
     return;
   }
 
@@ -1922,9 +1914,7 @@ invalid_buffer:
     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
         ("Invalid sized input buffer"));
     gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
-    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
-    self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED;
-    self->started = FALSE;
+    gst_omx_video_dec_pause_loop (self, GST_FLOW_NOT_NEGOTIATED);
     GST_VIDEO_DECODER_STREAM_UNLOCK (self);
     return;
   }
@@ -1933,10 +1923,8 @@ caps_failed:
   {
     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), ("Failed to set caps"));
     gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
-    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
+    gst_omx_video_dec_pause_loop (self, GST_FLOW_NOT_NEGOTIATED);
     GST_VIDEO_DECODER_STREAM_UNLOCK (self);
-    self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED;
-    self->started = FALSE;
     return;
   }
 release_error:
@@ -1945,9 +1933,7 @@ release_error:
         ("Failed to relase output buffer to component: %s (0x%08x)",
             gst_omx_error_to_string (err), err));
     gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
-    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
-    self->downstream_flow_ret = GST_FLOW_ERROR;
-    self->started = FALSE;
+    gst_omx_video_dec_pause_loop (self, GST_FLOW_ERROR);
     GST_VIDEO_DECODER_STREAM_UNLOCK (self);
     return;
   }
index cb70e02..eec3525 100644 (file)
@@ -74,7 +74,7 @@ struct _GstOMXVideoDec
   GMutex drain_lock;
   GCond drain_cond;
   /* TRUE if EOS buffers shouldn't be forwarded */
-  gboolean draining;
+  gboolean draining; /* protected by drain_lock */
 
   GstFlowReturn downstream_flow_ret;
   /* Initially FALSE. Switched to TRUE when all requirements