audioaggregate: Don't hold object locks across calls to aggregate_one
authorOlivier Crête <olivier.crete@collabora.com>
Sat, 20 May 2017 17:00:23 +0000 (19:00 +0200)
committerOlivier Crête <olivier.crete@collabora.com>
Sun, 21 May 2017 16:44:53 +0000 (18:44 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=782878

gst-libs/gst/audio/gstaudioaggregator.c
gst/audiomixer/gstaudiointerleave.c
gst/audiomixer/gstaudiomixer.c

index d683331..398e2cf 100644 (file)
@@ -976,6 +976,8 @@ gst_audio_aggregator_mix_buffer (GstAudioAggregator * aagg,
   guint out_start;
   gboolean filled;
   guint blocksize;
+  guint in_offset;
+  gboolean pad_changed = FALSE;
 
   blocksize = gst_util_uint64_scale (aagg->priv->output_buffer_duration,
       GST_AUDIO_INFO_RATE (&aagg->info), GST_SECOND);
@@ -1001,12 +1003,26 @@ gst_audio_aggregator_mix_buffer (GstAudioAggregator * aagg,
     return FALSE;
   }
 
+  gst_buffer_ref (inbuf);
+  in_offset = pad->priv->position;
+  GST_OBJECT_UNLOCK (pad);
+  GST_OBJECT_UNLOCK (aagg);
+
   filled = GST_AUDIO_AGGREGATOR_GET_CLASS (aagg)->aggregate_one_buffer (aagg,
-      pad, inbuf, pad->priv->position, outbuf, out_start, overlap);
+      pad, inbuf, in_offset, outbuf, out_start, overlap);
+
+  GST_OBJECT_LOCK (aagg);
+  GST_OBJECT_LOCK (pad);
+
+  pad_changed = (inbuf != pad->priv->buffer);
+  gst_buffer_unref (inbuf);
 
   if (filled)
     GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_GAP);
 
+  if (pad_changed)
+    return FALSE;
+
   pad->priv->position += overlap;
   pad->priv->output_offset += overlap;
 
index cc10e21..fd58e78 100644 (file)
@@ -823,6 +823,9 @@ gst_audio_interleave_aggregate_one_buffer (GstAudioAggregator * aagg,
   gint out_width, in_bpf, out_bpf, out_channels, channel;
   guint8 *outdata;
 
+  GST_OBJECT_LOCK (aagg);
+  GST_OBJECT_LOCK (aaggpad);
+
   out_width = GST_AUDIO_INFO_WIDTH (&aagg->info) / 8;
   in_bpf = GST_AUDIO_INFO_BPF (&aaggpad->info);
   out_bpf = GST_AUDIO_INFO_BPF (&aagg->info);
@@ -850,6 +853,9 @@ gst_audio_interleave_aggregate_one_buffer (GstAudioAggregator * aagg,
   gst_buffer_unmap (inbuf, &inmap);
   gst_buffer_unmap (outbuf, &outmap);
 
+  GST_OBJECT_UNLOCK (aaggpad);
+  GST_OBJECT_UNLOCK (aagg);
+
   return TRUE;
 }
 
index 2233b82..0ac0f4a 100644 (file)
@@ -624,7 +624,6 @@ gst_audiomixer_release_pad (GstElement * element, GstPad * pad)
 }
 
 
-/* Called with object lock and pad object lock held */
 static gboolean
 gst_audiomixer_aggregate_one_buffer (GstAudioAggregator * aagg,
     GstAudioAggregatorPad * aaggpad, GstBuffer * inbuf, guint in_offset,
@@ -635,8 +634,13 @@ gst_audiomixer_aggregate_one_buffer (GstAudioAggregator * aagg,
   GstMapInfo outmap;
   gint bpf;
 
+  GST_OBJECT_LOCK (aagg);
+  GST_OBJECT_LOCK (aaggpad);
+
   if (pad->mute || pad->volume < G_MINDOUBLE) {
     GST_DEBUG_OBJECT (pad, "Skipping muted pad");
+    GST_OBJECT_UNLOCK (aaggpad);
+    GST_OBJECT_UNLOCK (aagg);
     return FALSE;
   }
 
@@ -744,6 +748,9 @@ gst_audiomixer_aggregate_one_buffer (GstAudioAggregator * aagg,
   gst_buffer_unmap (inbuf, &inmap);
   gst_buffer_unmap (outbuf, &outmap);
 
+  GST_OBJECT_UNLOCK (aaggpad);
+  GST_OBJECT_UNLOCK (aagg);
+
   return TRUE;
 }