mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 00:58:12 +00:00
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:
parent
caed64c720
commit
81f4c9e8bf
3 changed files with 20 additions and 4 deletions
|
@ -106,11 +106,13 @@ gst_base_video_codec_reset (GstBaseVideoCodec * base_video_codec)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (base_video_codec, "reset");
|
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)) {
|
for (g = base_video_codec->frames; g; g = g_list_next (g)) {
|
||||||
gst_base_video_codec_free_frame ((GstVideoFrame *) g->data);
|
gst_base_video_codec_free_frame ((GstVideoFrame *) g->data);
|
||||||
}
|
}
|
||||||
g_list_free (base_video_codec->frames);
|
g_list_free (base_video_codec->frames);
|
||||||
base_video_codec->frames = NULL;
|
base_video_codec->frames = NULL;
|
||||||
|
GST_OBJECT_UNLOCK (base_video_codec);
|
||||||
|
|
||||||
base_video_codec->bytes = 0;
|
base_video_codec->bytes = 0;
|
||||||
base_video_codec->time = 0;
|
base_video_codec->time = 0;
|
||||||
|
|
|
@ -147,7 +147,7 @@ struct _GstBaseVideoCodec
|
||||||
|
|
||||||
guint64 system_frame_number;
|
guint64 system_frame_number;
|
||||||
|
|
||||||
GList *frames;
|
GList *frames; /* Protected with OBJECT_LOCK */
|
||||||
GstVideoState state;
|
GstVideoState state;
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
|
|
||||||
|
|
|
@ -1359,10 +1359,14 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder,
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
GST_LOG_OBJECT (base_video_decoder, "finish frame");
|
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",
|
GST_LOG_OBJECT (base_video_decoder, "n %d in %d out %d",
|
||||||
g_list_length (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames),
|
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->input_adapter),
|
||||||
gst_adapter_available (base_video_decoder->output_adapter));
|
gst_adapter_available (base_video_decoder->output_adapter));
|
||||||
|
GST_OBJECT_UNLOCK (base_video_decoder);
|
||||||
|
#endif
|
||||||
|
|
||||||
GST_LOG_OBJECT (base_video_decoder,
|
GST_LOG_OBJECT (base_video_decoder,
|
||||||
"finish frame sync=%d pts=%" GST_TIME_FORMAT, frame->is_sync_point,
|
"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:
|
done:
|
||||||
|
GST_OBJECT_LOCK (base_video_decoder);
|
||||||
GST_BASE_VIDEO_CODEC (base_video_decoder)->frames =
|
GST_BASE_VIDEO_CODEC (base_video_decoder)->frames =
|
||||||
g_list_remove (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames, frame);
|
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);
|
gst_base_video_codec_free_frame (frame);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1718,8 +1724,10 @@ gst_base_video_decoder_have_frame_2 (GstBaseVideoDecoder * base_video_decoder)
|
||||||
GST_TIME_ARGS (frame->decode_timestamp));
|
GST_TIME_ARGS (frame->decode_timestamp));
|
||||||
GST_LOG_OBJECT (base_video_decoder, "dist %d", frame->distance_from_sync);
|
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 =
|
GST_BASE_VIDEO_CODEC (base_video_decoder)->frames =
|
||||||
g_list_append (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames, frame);
|
g_list_append (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames, frame);
|
||||||
|
GST_OBJECT_UNLOCK (base_video_decoder);
|
||||||
|
|
||||||
frame->deadline =
|
frame->deadline =
|
||||||
gst_segment_to_running_time (&GST_BASE_VIDEO_CODEC
|
gst_segment_to_running_time (&GST_BASE_VIDEO_CODEC
|
||||||
|
@ -1801,7 +1809,9 @@ gst_base_video_decoder_get_oldest_frame (GstBaseVideoDecoder *
|
||||||
{
|
{
|
||||||
GList *g;
|
GList *g;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (base_video_decoder);
|
||||||
g = g_list_first (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames);
|
g = g_list_first (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames);
|
||||||
|
GST_OBJECT_UNLOCK (base_video_decoder);
|
||||||
|
|
||||||
if (g == NULL)
|
if (g == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1820,17 +1830,21 @@ gst_base_video_decoder_get_frame (GstBaseVideoDecoder * base_video_decoder,
|
||||||
int frame_number)
|
int frame_number)
|
||||||
{
|
{
|
||||||
GList *g;
|
GList *g;
|
||||||
|
GstVideoFrame *frame = NULL;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (base_video_decoder);
|
||||||
for (g = g_list_first (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames);
|
for (g = g_list_first (GST_BASE_VIDEO_CODEC (base_video_decoder)->frames);
|
||||||
g; g = g_list_next (g)) {
|
g; g = g_list_next (g)) {
|
||||||
GstVideoFrame *frame = g->data;
|
GstVideoFrame *tmp = g->data;
|
||||||
|
|
||||||
if (frame->system_frame_number == frame_number) {
|
if (frame->system_frame_number == frame_number) {
|
||||||
return frame;
|
frame = tmp;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GST_OBJECT_UNLOCK (base_video_decoder);
|
||||||
|
|
||||||
return NULL;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue