From 81f4c9e8bf9eb28c121c53c965c8aee6003acf0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 11 Jul 2011 11:28:40 +0200 Subject: [PATCH] basevideocodec: Protect access to the list of pending frames with the object lock This is required if ::finish_frame() and all buffer output happens on a different thread than the sinkpad streaming thread. --- gst-libs/gst/video/gstbasevideocodec.c | 2 ++ gst-libs/gst/video/gstbasevideocodec.h | 2 +- gst-libs/gst/video/gstbasevideodecoder.c | 20 +++++++++++++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/video/gstbasevideocodec.c b/gst-libs/gst/video/gstbasevideocodec.c index ea35b0174a..31fa5e5df6 100644 --- a/gst-libs/gst/video/gstbasevideocodec.c +++ b/gst-libs/gst/video/gstbasevideocodec.c @@ -106,11 +106,13 @@ gst_base_video_codec_reset (GstBaseVideoCodec * base_video_codec) GST_DEBUG_OBJECT (base_video_codec, "reset"); + GST_OBJECT_LOCK (base_video_codec); for (g = base_video_codec->frames; g; g = g_list_next (g)) { gst_base_video_codec_free_frame ((GstVideoFrame *) g->data); } g_list_free (base_video_codec->frames); base_video_codec->frames = NULL; + GST_OBJECT_UNLOCK (base_video_codec); base_video_codec->bytes = 0; base_video_codec->time = 0; diff --git a/gst-libs/gst/video/gstbasevideocodec.h b/gst-libs/gst/video/gstbasevideocodec.h index 9fc2cb27d9..c1e37120d9 100644 --- a/gst-libs/gst/video/gstbasevideocodec.h +++ b/gst-libs/gst/video/gstbasevideocodec.h @@ -147,7 +147,7 @@ struct _GstBaseVideoCodec guint64 system_frame_number; - GList *frames; + GList *frames; /* Protected with OBJECT_LOCK */ GstVideoState state; GstSegment segment; diff --git a/gst-libs/gst/video/gstbasevideodecoder.c b/gst-libs/gst/video/gstbasevideodecoder.c index 8b6c34472f..95cf991509 100644 --- a/gst-libs/gst/video/gstbasevideodecoder.c +++ b/gst-libs/gst/video/gstbasevideodecoder.c @@ -1359,10 +1359,14 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder, GList *l; GST_LOG_OBJECT (base_video_decoder, "finish frame"); +#ifndef GST_DISABLE_GST_DEBUG + GST_OBJECT_LOCK (base_video_decoder); GST_LOG_OBJECT (base_video_decoder, "n %d in %d out %d", g_list_length (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames), gst_adapter_available (base_video_decoder->input_adapter), gst_adapter_available (base_video_decoder->output_adapter)); + GST_OBJECT_UNLOCK (base_video_decoder); +#endif GST_LOG_OBJECT (base_video_decoder, "finish frame sync=%d pts=%" GST_TIME_FORMAT, frame->is_sync_point, @@ -1553,8 +1557,10 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder, } done: + GST_OBJECT_LOCK (base_video_decoder); GST_BASE_VIDEO_CODEC (base_video_decoder)->frames = g_list_remove (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames, frame); + GST_OBJECT_UNLOCK (base_video_decoder); gst_base_video_codec_free_frame (frame); return ret; @@ -1718,8 +1724,10 @@ gst_base_video_decoder_have_frame_2 (GstBaseVideoDecoder * base_video_decoder) GST_TIME_ARGS (frame->decode_timestamp)); GST_LOG_OBJECT (base_video_decoder, "dist %d", frame->distance_from_sync); + GST_OBJECT_LOCK (base_video_decoder); GST_BASE_VIDEO_CODEC (base_video_decoder)->frames = g_list_append (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames, frame); + GST_OBJECT_UNLOCK (base_video_decoder); frame->deadline = gst_segment_to_running_time (&GST_BASE_VIDEO_CODEC @@ -1801,7 +1809,9 @@ gst_base_video_decoder_get_oldest_frame (GstBaseVideoDecoder * { GList *g; + GST_OBJECT_LOCK (base_video_decoder); g = g_list_first (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames); + GST_OBJECT_UNLOCK (base_video_decoder); if (g == NULL) return NULL; @@ -1820,17 +1830,21 @@ gst_base_video_decoder_get_frame (GstBaseVideoDecoder * base_video_decoder, int frame_number) { GList *g; + GstVideoFrame *frame = NULL; + GST_OBJECT_LOCK (base_video_decoder); for (g = g_list_first (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames); g; g = g_list_next (g)) { - GstVideoFrame *frame = g->data; + GstVideoFrame *tmp = g->data; if (frame->system_frame_number == frame_number) { - return frame; + frame = tmp; + break; } } + GST_OBJECT_UNLOCK (base_video_decoder); - return NULL; + return frame; } /**