v4l2videodec: fix freeze race condition
authorJonas Rebmann <jre@pengutronix.de>
Wed, 27 Nov 2024 11:16:37 +0000 (12:16 +0100)
committerBackport Bot <gitlab-backport-bot@gstreamer-foundation.org>
Wed, 27 Nov 2024 19:10:04 +0000 (19:10 +0000)
This fixes a possible deadlock between gst_v4l2_video_dec_change_state
and gst_v4l2_video_dec_loop on the buffer pool.

When stopping capture, the flushing state of the v4l2 capture buffer
pool gets reverted in the processing loop after it was set via
gst_v4l2_object_unlock (self->v4l2capture) (in
gst_v4l2_video_dec_change_state). As a result, gst_v4l2_video_dec_loop
does not return and consequently, gst_pad_stop_task gets stuck waiting
for the GST_PAD_STREAM_LOCK. To circumvent this, skip acquiring the
buffer pool if stopping capture.

Suggested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7987>

subprojects/gst-plugins-good/sys/v4l2/gstv4l2videodec.c

index 7814bae03dec248abd6a52a714aac584f2e10bdd..f435f659cca5247179cb317da89e6e40cd2a9bdf 100644 (file)
@@ -745,6 +745,13 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
         GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
         goto beach;
       }
+
+      /*
+       * In case we are flushing or stopping the element, ensure the active
+       * state is reflected onto the newly create pool.
+       */
+      if (!g_atomic_int_get (&self->active))
+        gst_v4l2_object_unlock (self->v4l2capture);
     }
 
     /* just a safety, as introducing mistakes in negotiation seems rather