pulsesink: Get rid of acceptcaps side-effects

The sink info callback should not have side-effects on the GstPulseSink
object since we are sometimes using with a dummy stream in acceptcaps.

https://bugzilla.gnome.org/show_bug.cgi?id=686459
This commit is contained in:
Arun Raghavan 2013-05-10 12:09:19 +05:30
parent 1d6d0ef609
commit e5fad95306
2 changed files with 33 additions and 38 deletions

View File

@ -1900,6 +1900,19 @@ gst_pulsesink_class_init (GstPulseSinkClass * klass)
gst_static_pad_template_get (&pad_template)); gst_static_pad_template_get (&pad_template));
} }
static void
free_device_info (GstPulseDeviceInfo * device_info)
{
GList *l;
g_free (device_info->description);
for (l = g_list_first (device_info->formats); l; l = g_list_next (l))
pa_format_info_free ((pa_format_info *) l->data);
g_list_free (device_info->formats);
}
/* Returns the current time of the sink ringbuffer. The timing_info is updated /* Returns the current time of the sink ringbuffer. The timing_info is updated
* on every data write/flush and every 100ms (PA_STREAM_AUTO_TIMING_UPDATE). * on every data write/flush and every 100ms (PA_STREAM_AUTO_TIMING_UPDATE).
*/ */
@ -1954,34 +1967,19 @@ static void
gst_pulsesink_sink_info_cb (pa_context * c, const pa_sink_info * i, int eol, gst_pulsesink_sink_info_cb (pa_context * c, const pa_sink_info * i, int eol,
void *userdata) void *userdata)
{ {
GstPulseRingBuffer *pbuf; GstPulseDeviceInfo *device_info = (GstPulseDeviceInfo *) userdata;
GstPulseSink *psink;
GList *l;
guint8 j; guint8 j;
pbuf = GST_PULSERING_BUFFER_CAST (userdata);
psink = GST_PULSESINK_CAST (GST_OBJECT_PARENT (pbuf));
if (!i) if (!i)
goto done; goto done;
g_free (psink->device_description); device_info->description = g_strdup (i->description);
psink->device_description = g_strdup (i->description);
g_mutex_lock (&psink->sink_formats_lock);
for (l = g_list_first (psink->sink_formats); l; l = g_list_next (l))
pa_format_info_free ((pa_format_info *) l->data);
g_list_free (psink->sink_formats);
psink->sink_formats = NULL;
device_info->formats = NULL;
for (j = 0; j < i->n_formats; j++) for (j = 0; j < i->n_formats; j++)
psink->sink_formats = g_list_prepend (psink->sink_formats, device_info->formats = g_list_prepend (device_info->formats,
pa_format_info_copy (i->formats[j])); pa_format_info_copy (i->formats[j]));
g_mutex_unlock (&psink->sink_formats_lock);
done: done:
pa_threaded_mainloop_signal (mainloop, 0); pa_threaded_mainloop_signal (mainloop, 0);
} }
@ -1990,6 +1988,7 @@ static gboolean
gst_pulsesink_query_acceptcaps (GstPulseSink * psink, GstCaps * caps) gst_pulsesink_query_acceptcaps (GstPulseSink * psink, GstCaps * caps)
{ {
GstPulseRingBuffer *pbuf = NULL; GstPulseRingBuffer *pbuf = NULL;
GstPulseDeviceInfo device_info = { NULL, NULL };
GstCaps *pad_caps; GstCaps *pad_caps;
GstStructure *st; GstStructure *st;
gboolean ret = FALSE; gboolean ret = FALSE;
@ -2063,7 +2062,7 @@ gst_pulsesink_query_acceptcaps (GstPulseSink * psink, GstCaps * caps)
GList *i; GList *i;
if (!(o = pa_context_get_sink_info_by_name (pbuf->context, psink->device, if (!(o = pa_context_get_sink_info_by_name (pbuf->context, psink->device,
gst_pulsesink_sink_info_cb, pbuf))) gst_pulsesink_sink_info_cb, &device_info)))
goto info_failed; goto info_failed;
while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) { while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) {
@ -2072,14 +2071,12 @@ gst_pulsesink_query_acceptcaps (GstPulseSink * psink, GstCaps * caps)
goto out; goto out;
} }
g_mutex_lock (&psink->sink_formats_lock); for (i = g_list_first (device_info.formats); i; i = g_list_next (i)) {
for (i = g_list_first (psink->sink_formats); i; i = g_list_next (i)) {
if (pa_format_info_is_compatible ((pa_format_info *) i->data, format)) { if (pa_format_info_is_compatible ((pa_format_info *) i->data, format)) {
ret = TRUE; ret = TRUE;
break; break;
} }
} }
g_mutex_unlock (&psink->sink_formats_lock);
} else { } else {
/* We're in READY, let's connect a stream to see if the format is /* We're in READY, let's connect a stream to see if the format is
* accpeted by whatever sink we're routed to */ * accpeted by whatever sink we're routed to */
@ -2110,6 +2107,7 @@ out:
pa_operation_unref (o); pa_operation_unref (o);
if (stream) { if (stream) {
free_device_info (&device_info);
pa_stream_set_state_callback (stream, NULL, NULL); pa_stream_set_state_callback (stream, NULL, NULL);
pa_stream_disconnect (stream); pa_stream_disconnect (stream);
pa_stream_unref (stream); pa_stream_unref (stream);
@ -2138,11 +2136,10 @@ gst_pulsesink_init (GstPulseSink * pulsesink)
{ {
pulsesink->server = NULL; pulsesink->server = NULL;
pulsesink->device = NULL; pulsesink->device = NULL;
pulsesink->device_description = NULL; pulsesink->device_info.description = NULL;
pulsesink->client_name = gst_pulse_client_name (); pulsesink->client_name = gst_pulse_client_name ();
g_mutex_init (&pulsesink->sink_formats_lock); pulsesink->device_info.formats = NULL;
pulsesink->sink_formats = NULL;
pulsesink->volume = DEFAULT_VOLUME; pulsesink->volume = DEFAULT_VOLUME;
pulsesink->volume_set = FALSE; pulsesink->volume_set = FALSE;
@ -2176,18 +2173,12 @@ static void
gst_pulsesink_finalize (GObject * object) gst_pulsesink_finalize (GObject * object)
{ {
GstPulseSink *pulsesink = GST_PULSESINK_CAST (object); GstPulseSink *pulsesink = GST_PULSESINK_CAST (object);
GList *i;
g_free (pulsesink->server); g_free (pulsesink->server);
g_free (pulsesink->device); g_free (pulsesink->device);
g_free (pulsesink->device_description);
g_free (pulsesink->client_name); g_free (pulsesink->client_name);
for (i = g_list_first (pulsesink->sink_formats); i; i = g_list_next (i)) free_device_info (&pulsesink->device_info);
pa_format_info_free ((pa_format_info *) i->data);
g_list_free (pulsesink->sink_formats);
g_mutex_clear (&pulsesink->sink_formats_lock);
if (pulsesink->properties) if (pulsesink->properties)
gst_structure_free (pulsesink->properties); gst_structure_free (pulsesink->properties);
@ -2521,8 +2512,9 @@ gst_pulsesink_device_description (GstPulseSink * psink)
if (pbuf == NULL) if (pbuf == NULL)
goto no_buffer; goto no_buffer;
free_device_info (&psink->device_info);
if (!(o = pa_context_get_sink_info_by_name (pbuf->context, if (!(o = pa_context_get_sink_info_by_name (pbuf->context,
psink->device, gst_pulsesink_sink_info_cb, pbuf))) psink->device, gst_pulsesink_sink_info_cb, &psink->device_info)))
goto info_failed; goto info_failed;
while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) { while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) {
@ -2535,7 +2527,7 @@ unlock:
if (o) if (o)
pa_operation_unref (o); pa_operation_unref (o);
t = g_strdup (psink->device_description); t = g_strdup (psink->device_info.description);
pa_threaded_mainloop_unlock (mainloop); pa_threaded_mainloop_unlock (mainloop);
return t; return t;

View File

@ -55,12 +55,17 @@ G_BEGIN_DECLS
typedef struct _GstPulseSink GstPulseSink; typedef struct _GstPulseSink GstPulseSink;
typedef struct _GstPulseSinkClass GstPulseSinkClass; typedef struct _GstPulseSinkClass GstPulseSinkClass;
typedef struct _GstPulseDeviceInfo {
gchar *description;
GList *formats;
} GstPulseDeviceInfo;
struct _GstPulseSink struct _GstPulseSink
{ {
GstAudioBaseSink sink; GstAudioBaseSink sink;
gchar *server, *device, *stream_name, *client_name; gchar *server, *device, *stream_name, *client_name;
gchar *device_description; GstPulseDeviceInfo device_info;
GstPulseProbe *probe; GstPulseProbe *probe;
@ -78,8 +83,6 @@ struct _GstPulseSink
GstStructure *properties; GstStructure *properties;
pa_proplist *proplist; pa_proplist *proplist;
GMutex sink_formats_lock;
GList *sink_formats;
volatile gint format_lost; volatile gint format_lost;
GstClockTime format_lost_time; GstClockTime format_lost_time;
}; };