pulsesink: in accept_caps() check if ring buffer is NULL before de-referencing
authorTim-Philipp Müller <tim.muller@collabora.co.uk>
Thu, 18 Oct 2012 10:32:10 +0000 (11:32 +0100)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Fri, 19 Oct 2012 14:11:07 +0000 (15:11 +0100)
And sprinkle some thread-safety (take object lock for
accessing ring buffer, and pa main loop lock for the
context).

https://bugzilla.gnome.org/show_bug.cgi?id=683782

ext/pulse/pulsesink.c

index 6411a15..63d361a 100644 (file)
@@ -1960,9 +1960,7 @@ done:
 static gboolean
 gst_pulsesink_query_acceptcaps (GstPulseSink * psink, GstCaps * caps)
 {
-  GstPulseRingBuffer *pbuf = GST_PULSERING_BUFFER_CAST (GST_AUDIO_BASE_SINK
-      (psink)->ringbuffer);
-  GstPad *pad = GST_BASE_SINK_PAD (psink);
+  GstPulseRingBuffer *pbuf = NULL;
   GstCaps *pad_caps;
   GstStructure *st;
   gboolean ret = FALSE;
@@ -1975,14 +1973,14 @@ gst_pulsesink_query_acceptcaps (GstPulseSink * psink, GstCaps * caps)
   pa_format_info *format = NULL, *formats[1];
   guint channels;
 
-  pad_caps = gst_pad_query_caps (pad, caps);
+  pad_caps = gst_pad_query_caps (GST_BASE_SINK_PAD (psink), caps);
   ret = pad_caps != NULL;
   gst_caps_unref (pad_caps);
 
   GST_DEBUG_OBJECT (psink, "caps %" GST_PTR_FORMAT, caps);
 
-  /* Either template caps didn't match, or we're still in NULL state */
-  if (!ret || !pbuf->context)
+  /* Template caps didn't match */
+  if (!ret)
     goto done;
 
   /* If we've not got fixed caps, creating a stream might fail, so let's just
@@ -1990,10 +1988,23 @@ gst_pulsesink_query_acceptcaps (GstPulseSink * psink, GstCaps * caps)
   if (!gst_caps_is_fixed (caps))
     goto done;
 
-  ret = FALSE;
+  GST_OBJECT_LOCK (psink);
+  pbuf = GST_PULSERING_BUFFER_CAST (GST_AUDIO_BASE_SINK (psink)->ringbuffer);
+  if (pbuf != NULL)
+    gst_object_ref (pbuf);
+  GST_OBJECT_UNLOCK (psink);
+
+  /* We're still in NULL state */
+  if (pbuf == NULL)
+    goto done;
 
   pa_threaded_mainloop_lock (mainloop);
 
+  if (pbuf->context == NULL)
+    goto out;
+
+  ret = FALSE;
+
   spec.latency_time = GST_AUDIO_BASE_SINK (psink)->latency_time;
   if (!gst_audio_ring_buffer_parse_caps (&spec, caps))
     goto out;
@@ -2077,7 +2088,10 @@ out:
 
   pa_threaded_mainloop_unlock (mainloop);
 
+  gst_object_unref (pbuf);
+
 done:
+
   return ret;
 
 info_failed: