From 60bb3f40de7fd4f84721fa749eeaa0766a2fdb13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 4 Jul 2016 11:12:25 +0200 Subject: audiodecoder: Protect samples_in/bytes_out and audio info with object lock It might cause invalid calculations during the CONVERT query otherwise. --- gst-libs/gst/audio/gstaudiodecoder.c | 41 ++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/gst-libs/gst/audio/gstaudiodecoder.c b/gst-libs/gst/audio/gstaudiodecoder.c index d672663e3..8c43cbb74 100644 --- a/gst-libs/gst/audio/gstaudiodecoder.c +++ b/gst-libs/gst/audio/gstaudiodecoder.c @@ -496,8 +496,10 @@ gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full) if (full) { dec->priv->active = FALSE; + GST_OBJECT_LOCK (dec); dec->priv->bytes_in = 0; dec->priv->samples_out = 0; + GST_OBJECT_UNLOCK (dec); dec->priv->agg = -1; dec->priv->error_count = 0; gst_audio_decoder_clear_queues (dec); @@ -524,11 +526,13 @@ gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full) if (dec->priv->ctx.allocator) gst_object_unref (dec->priv->ctx.allocator); + GST_OBJECT_LOCK (dec); gst_caps_replace (&dec->priv->ctx.input_caps, NULL); memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx)); gst_audio_info_init (&dec->priv->ctx.info); + GST_OBJECT_UNLOCK (dec); dec->priv->ctx.max_errors = GST_AUDIO_DECODER_MAX_ERRORS; dec->priv->ctx.had_output_data = FALSE; dec->priv->ctx.had_input_data = FALSE; @@ -811,7 +815,9 @@ gst_audio_decoder_set_output_format (GstAudioDecoder * dec, } /* copy the GstAudioInfo */ + GST_OBJECT_LOCK (dec); dec->priv->ctx.info = *info; + GST_OBJECT_UNLOCK (dec); dec->priv->ctx.output_format_changed = TRUE; done: @@ -1382,8 +1388,10 @@ gst_audio_decoder_finish_frame (GstAudioDecoder * dec, GstBuffer * buf, } } + GST_OBJECT_LOCK (dec); priv->samples += samples; priv->samples_out += samples; + GST_OBJECT_UNLOCK (dec); /* we got data, so note things are looking up */ if (G_UNLIKELY (dec->priv->error_count)) @@ -1444,7 +1452,9 @@ gst_audio_decoder_handle_frame (GstAudioDecoder * dec, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); g_queue_push_tail (&dec->priv->frames, buffer); dec->priv->ctx.delay = dec->priv->frames.length; + GST_OBJECT_LOCK (dec); dec->priv->bytes_in += size; + GST_OBJECT_UNLOCK (dec); } else { GST_LOG_OBJECT (dec, "providing subclass with NULL frame"); } @@ -1942,8 +1952,14 @@ not_negotiated: static inline gboolean gst_audio_decoder_do_byte (GstAudioDecoder * dec) { - return dec->priv->ctx.do_estimate_rate && dec->priv->ctx.info.bpf && + gboolean ret; + + GST_OBJECT_LOCK (dec); + ret = dec->priv->ctx.do_estimate_rate && dec->priv->ctx.info.bpf && dec->priv->ctx.info.rate <= dec->priv->samples_out; + GST_OBJECT_UNLOCK (dec); + + return ret; } /* Must be called holding the GST_AUDIO_DECODER_STREAM_LOCK */ @@ -1957,6 +1973,7 @@ gst_audio_decoder_negotiate_default_caps (GstAudioDecoder * dec) guint64 channel_mask = 0; gint caps_size; GstStructure *structure; + GstAudioInfo info; templcaps = gst_pad_get_pad_template_caps (dec->srcpad); caps = gst_pad_peer_query_caps (dec->srcpad, templcaps); @@ -2032,9 +2049,13 @@ gst_audio_decoder_negotiate_default_caps (GstAudioDecoder * dec) } } - if (!caps || !gst_audio_info_from_caps (&dec->priv->ctx.info, caps)) + if (!caps || !gst_audio_info_from_caps (&info, caps)) goto caps_error; + GST_OBJECT_LOCK (dec); + dec->priv->ctx.info = info; + GST_OBJECT_UNLOCK (dec); + GST_INFO_OBJECT (dec, "Chose default caps %" GST_PTR_FORMAT " for initial gap", caps); gst_caps_unref (caps); @@ -2588,9 +2609,12 @@ gst_audio_decoder_sink_query_default (GstAudioDecoder * dec, GstQuery * query) gint64 src_val, dest_val; gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); - if (!(res = __gst_audio_encoded_audio_convert (&dec->priv->ctx.info, - dec->priv->bytes_in, dec->priv->samples_out, - src_fmt, src_val, &dest_fmt, &dest_val))) + GST_OBJECT_LOCK (dec); + res = __gst_audio_encoded_audio_convert (&dec->priv->ctx.info, + dec->priv->bytes_in, dec->priv->samples_out, + src_fmt, src_val, &dest_fmt, &dest_val); + GST_OBJECT_UNLOCK (dec); + if (!res) goto error; gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); break; @@ -2769,8 +2793,11 @@ gst_audio_decoder_src_query_default (GstAudioDecoder * dec, GstQuery * query) gint64 src_val, dest_val; gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); - if (!(res = gst_audio_info_convert (&dec->priv->ctx.info, - src_fmt, src_val, dest_fmt, &dest_val))) + GST_OBJECT_LOCK (dec); + res = gst_audio_info_convert (&dec->priv->ctx.info, + src_fmt, src_val, dest_fmt, &dest_val); + GST_OBJECT_UNLOCK (dec); + if (!res) break; gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); break; -- cgit v1.2.1