mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
audioaggregator: Make access to the pad list thread-safe while mixing
When mixing every single buffer the object lock is shortly released and acquired again. In the meantime the pad list can become invalid because a pad was removed or added, and equally the current pad might as well have been finalized in the meantime. To get around that, take a snapshot of all sinkpads before mixing and work with that list of pads. Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3052 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5510>
This commit is contained in:
parent
a7c1da6ce5
commit
f7d4ea6eec
1 changed files with 16 additions and 3 deletions
|
@ -2224,6 +2224,8 @@ gst_audio_aggregator_aggregate (GstAggregator * agg, gboolean timeout)
|
||||||
GstElement *element;
|
GstElement *element;
|
||||||
GstAudioAggregator *aagg;
|
GstAudioAggregator *aagg;
|
||||||
GList *iter;
|
GList *iter;
|
||||||
|
GstPad **sinkpads;
|
||||||
|
guint n_sinkpads, i;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstBuffer *outbuf = NULL;
|
GstBuffer *outbuf = NULL;
|
||||||
gint64 next_offset;
|
gint64 next_offset;
|
||||||
|
@ -2471,9 +2473,17 @@ gst_audio_aggregator_aggregate (GstAggregator * agg, gboolean timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_OBJECT_LOCK (agg);
|
GST_OBJECT_LOCK (agg);
|
||||||
for (iter = element->sinkpads; iter; iter = iter->next) {
|
|
||||||
GstAudioAggregatorPad *pad = (GstAudioAggregatorPad *) iter->data;
|
// mix_buffer() will shortly release the object lock so we need to
|
||||||
GstAggregatorPad *aggpad = (GstAggregatorPad *) iter->data;
|
// ensure that the pad list stays valid.
|
||||||
|
n_sinkpads = element->numsinkpads;
|
||||||
|
sinkpads = g_newa (GstPad *, n_sinkpads + 1);
|
||||||
|
for (i = 0, iter = element->sinkpads; iter; i++, iter = iter->next)
|
||||||
|
sinkpads[i] = gst_object_ref (iter->data);
|
||||||
|
|
||||||
|
for (i = 0; i < n_sinkpads; i++) {
|
||||||
|
GstAudioAggregatorPad *pad = (GstAudioAggregatorPad *) sinkpads[i];
|
||||||
|
GstAggregatorPad *aggpad = (GstAggregatorPad *) sinkpads[i];
|
||||||
|
|
||||||
if (gst_aggregator_pad_is_inactive (aggpad))
|
if (gst_aggregator_pad_is_inactive (aggpad))
|
||||||
continue;
|
continue;
|
||||||
|
@ -2505,6 +2515,9 @@ gst_audio_aggregator_aggregate (GstAggregator * agg, gboolean timeout)
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (agg);
|
GST_OBJECT_UNLOCK (agg);
|
||||||
|
|
||||||
|
for (i = 0; i < n_sinkpads; i++)
|
||||||
|
gst_object_unref (sinkpads[i]);
|
||||||
|
|
||||||
if (dropped) {
|
if (dropped) {
|
||||||
/* We dropped a buffer, retry */
|
/* We dropped a buffer, retry */
|
||||||
GST_LOG_OBJECT (aagg, "A pad dropped a buffer, wait for the next one");
|
GST_LOG_OBJECT (aagg, "A pad dropped a buffer, wait for the next one");
|
||||||
|
|
Loading…
Reference in a new issue