From e583c482220a1ae32d181f2280d122388900a7a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 19 Aug 2011 09:19:22 +0200 Subject: [PATCH] omxvideodec: Release basevideocodec stream lock while waiting for a buffer This prevents deadlocks if no empty input buffers are available and releasing input buffers requires the loop function to handle some output buffers first. --- omx/gstomxvideodec.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c index 63f289deab..0466388301 100644 --- a/omx/gstomxvideodec.c +++ b/omx/gstomxvideodec.c @@ -374,7 +374,7 @@ _find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf) guint64 best_diff = G_MAXUINT64; BufferIdentification *best_id = NULL; - GST_OBJECT_LOCK (self); + GST_BASE_VIDEO_CODEC_STREAM_LOCK (self); for (l = GST_BASE_VIDEO_CODEC (self)->frames; l; l = l->next) { GstVideoFrame *tmp = l->data; BufferIdentification *id = tmp->coder_hook; @@ -429,7 +429,7 @@ _find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf) } } - GST_OBJECT_UNLOCK (self); + GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (self); if (finish_frames) { g_warning ("Too old frames, bug in decoder -- please file a bug"); @@ -924,12 +924,12 @@ gst_omx_video_dec_reset (GstBaseVideoDecoder * decoder) /* FIXME: Workaround for * https://bugzilla.gnome.org/show_bug.cgi?id=654529 */ - GST_OBJECT_LOCK (self); + GST_BASE_VIDEO_CODEC_STREAM_LOCK (self); g_list_foreach (GST_BASE_VIDEO_CODEC (self)->frames, (GFunc) gst_base_video_codec_free_frame, NULL); g_list_free (GST_BASE_VIDEO_CODEC (self)->frames); GST_BASE_VIDEO_CODEC (self)->frames = NULL; - GST_OBJECT_UNLOCK (self); + GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (self); if (self->started) { gst_omx_port_set_flushing (self->in_port, TRUE); @@ -975,7 +975,12 @@ gst_omx_video_dec_handle_frame (GstBaseVideoDecoder * decoder, duration = frame->presentation_duration; while (offset < GST_BUFFER_SIZE (frame->sink_buffer)) { + /* Make sure to release the base class stream lock, otherwise + * _loop() can't call _finish_frame() and we might block forever + * because no input buffers are released */ + GST_BASE_VIDEO_CODEC_STREAM_UNLOCK (self); acq_ret = gst_omx_port_acquire_buffer (self->in_port, &buf); + GST_BASE_VIDEO_CODEC_STREAM_LOCK (self); if (acq_ret == GST_OMX_ACQUIRE_BUFFER_ERROR) { goto component_error;