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.
This commit is contained in:
Sebastian Dröge 2011-07-11 11:28:40 +02:00
parent 9edd003406
commit 07e3936abf
3 changed files with 20 additions and 4 deletions

View file

@ -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;

View file

@ -147,7 +147,7 @@ struct _GstBaseVideoCodec
guint64 system_frame_number;
GList *frames;
GList *frames; /* Protected with OBJECT_LOCK */
GstVideoState state;
GstSegment segment;

View file

@ -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;
}
/**