mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-13 10:55:34 +00:00
videodecoder: Protect all accesses to priv->output_frame with the stream lock
Fixes segfault as queries/events can happen after a reset
This commit is contained in:
parent
6dd8302029
commit
ebae8ffa71
1 changed files with 29 additions and 7 deletions
|
@ -1254,12 +1254,14 @@ gst_video_decoder_src_event_default (GstVideoDecoder * decoder,
|
|||
priv->proportion = proportion;
|
||||
if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (timestamp))) {
|
||||
if (G_UNLIKELY (diff > 0)) {
|
||||
if (priv->output_state->info.fps_n > 0)
|
||||
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
||||
if (priv->output_state != NULL && priv->output_state->info.fps_n > 0)
|
||||
duration =
|
||||
gst_util_uint64_scale (GST_SECOND,
|
||||
priv->output_state->info.fps_d, priv->output_state->info.fps_n);
|
||||
else
|
||||
duration = 0;
|
||||
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
||||
priv->earliest_time = timestamp + 2 * diff + duration;
|
||||
} else {
|
||||
priv->earliest_time = timestamp + diff;
|
||||
|
@ -1384,8 +1386,13 @@ gst_video_decoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
|||
GST_DEBUG_OBJECT (dec, "convert query");
|
||||
|
||||
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
|
||||
GST_VIDEO_DECODER_STREAM_LOCK (dec);
|
||||
if (dec->priv->output_state != NULL)
|
||||
res = gst_video_rawvideo_convert (dec->priv->output_state,
|
||||
src_fmt, src_val, &dest_fmt, &dest_val);
|
||||
else
|
||||
res = FALSE;
|
||||
GST_VIDEO_DECODER_STREAM_UNLOCK (dec);
|
||||
if (!res)
|
||||
goto error;
|
||||
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
|
||||
|
@ -1399,7 +1406,7 @@ gst_video_decoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
|||
res = gst_pad_peer_query (dec->sinkpad, query);
|
||||
if (res) {
|
||||
gst_query_parse_latency (query, &live, &min_latency, &max_latency);
|
||||
GST_DEBUG_OBJECT (dec, "Peer latency: live %d, min %"
|
||||
GST_DEBUG_OBJECT (dec, "Peer qlatency: live %d, min %"
|
||||
GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
|
||||
GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
|
||||
|
||||
|
@ -2944,13 +2951,24 @@ gst_video_decoder_allocate_output_frame (GstVideoDecoder *
|
|||
decoder, GstVideoCodecFrame * frame)
|
||||
{
|
||||
GstFlowReturn flow_ret;
|
||||
GstVideoCodecState *state = decoder->priv->output_state;
|
||||
int num_bytes = GST_VIDEO_INFO_SIZE (&state->info);
|
||||
GstVideoCodecState *state;
|
||||
int num_bytes;
|
||||
|
||||
g_return_val_if_fail (num_bytes != 0, GST_FLOW_ERROR);
|
||||
g_return_val_if_fail (frame->output_buffer == NULL, GST_FLOW_ERROR);
|
||||
|
||||
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
|
||||
|
||||
state = decoder->priv->output_state;
|
||||
if (state == NULL) {
|
||||
g_warning ("Output state should be set before allocating frame");
|
||||
goto error;
|
||||
}
|
||||
num_bytes = GST_VIDEO_INFO_SIZE (&state->info);
|
||||
if (num_bytes == 0) {
|
||||
g_warning ("Frame size should not be 0");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (decoder->priv->output_state_changed
|
||||
|| (decoder->priv->output_state
|
||||
&& gst_pad_check_reconfigure (decoder->srcpad))))
|
||||
|
@ -2964,6 +2982,10 @@ gst_video_decoder_allocate_output_frame (GstVideoDecoder *
|
|||
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
||||
|
||||
return flow_ret;
|
||||
|
||||
error:
|
||||
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue