2008-08-13 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * ext/pulse/pulsemixer.c: (gst_pulsemixer_change_state):
+ * ext/pulse/pulsemixerctrl.c: (gst_pulsemixer_ctrl_subscribe_cb),
+ (gst_pulsemixer_ctrl_open), (gst_pulsemixer_ctrl_new),
+ (gst_pulsemixer_ctrl_free), (gst_pulsemixer_ctrl_timeout_event):
+ * ext/pulse/pulsemixerctrl.h:
+ * ext/pulse/pulseprobe.c: (gst_pulseprobe_open),
+ (gst_pulseprobe_enumerate), (gst_pulseprobe_new),
+ (gst_pulseprobe_free), (gst_pulseprobe_needs_probe),
+ (gst_pulseprobe_probe_property), (gst_pulseprobe_get_values):
+ * ext/pulse/pulseprobe.h:
+ * ext/pulse/pulsesink.c: (gst_pulsesink_init):
+ * ext/pulse/pulsesrc.c: (gst_pulsesrc_init), (gst_pulsesrc_delay),
+ (gst_pulsesrc_change_state):
+ Improve debugging a bit by including the parent object in pulsemixerctrl
+ and pulseprobe objects and using GST_WARNING_OBJECT instead of
+ GST_WARNING.
+
+ Use the parent GObject subclass instead of a random struct as GObject
+ parameter for G_OBJECT_WARN_INVALID_PROPERTY_ID. This fixes a crash
+ when probing for another property than "device".
+
+2008-08-13 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+
Patch by: Laszlo Pandy <laszlok2 at gmail dot com>
* ext/pulse/pulsemixer.c: (gst_pulsemixer_set_property):
if (!this->mixer)
this->mixer =
- gst_pulsemixer_ctrl_new (this->server, this->device,
- GST_PULSEMIXER_UNKNOWN);
+ gst_pulsemixer_ctrl_new (G_OBJECT (this), this->server,
+ this->device, GST_PULSEMIXER_UNKNOWN);
break;
gst_pulsemixer_ctrl_source_info_cb, c);
if (!o) {
- GST_WARNING ("Failed to get sink info: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to get sink info: %s",
pa_strerror (pa_context_errno (c->context)));
return;
}
#define CHECK_DEAD_GOTO(c, label) do { \
if (!(c)->context || pa_context_get_state((c)->context) != PA_CONTEXT_READY) { \
- GST_WARNING("Not connected: %s", (c)->context ? pa_strerror(pa_context_errno((c)->context)) : "NULL"); \
+ GST_WARNING_OBJECT (c->object, "Not connected: %s", (c)->context ? pa_strerror(pa_context_errno((c)->context)) : "NULL"); \
goto label; \
} \
} while(0);
if (!(c->context =
pa_context_new (pa_threaded_mainloop_get_api (c->mainloop), name))) {
- GST_WARNING ("Failed to create context");
+ GST_WARNING_OBJECT (c->object, "Failed to create context");
goto unlock_and_fail;
}
gst_pulsemixer_ctrl_subscribe_cb, c);
if (pa_context_connect (c->context, c->server, 0, NULL) < 0) {
- GST_WARNING ("Failed to connect context: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to connect context: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
pa_threaded_mainloop_wait (c->mainloop);
if (pa_context_get_state (c->context) != PA_CONTEXT_READY) {
- GST_WARNING ("Failed to connect context: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to connect context: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
pa_context_subscribe (c->context,
PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE,
gst_pulsemixer_ctrl_success_cb, c))) {
- GST_WARNING ("Failed to subscribe to events: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to subscribe to events: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
}
if (!c->operation_success) {
- GST_WARNING ("Failed to subscribe to events: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to subscribe to events: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
if (!(o =
pa_context_get_sink_info_by_name (c->context, c->device,
gst_pulsemixer_ctrl_sink_info_cb, c))) {
- GST_WARNING ("Failed to get sink info: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to get sink info: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
if (!c->operation_success && (c->type == GST_PULSEMIXER_SINK
|| pa_context_errno (c->context) != PA_ERR_NOENTITY)) {
- GST_WARNING ("Failed to get sink info: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to get sink info: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
if (!(o =
pa_context_get_source_info_by_name (c->context, c->device,
gst_pulsemixer_ctrl_source_info_cb, c))) {
- GST_WARNING ("Failed to get source info: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to get source info: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
o = NULL;
if (!c->operation_success) {
- GST_WARNING ("Failed to get source info: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to get source info: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
}
GstPulseMixerCtrl *
-gst_pulsemixer_ctrl_new (const gchar * server, const gchar * device,
- GstPulseMixerType type)
+gst_pulsemixer_ctrl_new (GObject * object, const gchar * server,
+ const gchar * device, GstPulseMixerType type)
{
GstPulseMixerCtrl *c = NULL;
c = g_new (GstPulseMixerCtrl, 1);
+ c->object = g_object_ref (object);
c->tracklist = NULL;
c->server = g_strdup (server);
c->device = g_strdup (device);
g_free (c->device);
g_free (c->name);
g_free (c->description);
+ g_object_unref (c->object);
g_free (c);
}
&c->volume, NULL, NULL);
if (!o)
- GST_WARNING ("Failed to set device volume: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to set device volume: %s",
pa_strerror (pa_context_errno (c->context)));
else
pa_operation_unref (o);
NULL, NULL);
if (!o)
- GST_WARNING ("Failed to set device mute: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to set device mute: %s",
pa_strerror (pa_context_errno (c->context)));
else
pa_operation_unref (o);
struct _GstPulseMixerCtrl
{
+ GObject *object;
+
GList *tracklist;
gchar *server, *device;
gboolean update_volume, update_mute;
};
-GstPulseMixerCtrl *gst_pulsemixer_ctrl_new (const gchar * server,
+GstPulseMixerCtrl *gst_pulsemixer_ctrl_new (GObject *object, const gchar * server,
const gchar * device, GstPulseMixerType type);
void gst_pulsemixer_ctrl_free (GstPulseMixerCtrl * mixer);
if (!(c->context =
pa_context_new (pa_threaded_mainloop_get_api (c->mainloop), name))) {
- GST_WARNING ("Failed to create context");
+ GST_WARNING_OBJECT (c->object, "Failed to create context");
goto unlock_and_fail;
}
c);
if (pa_context_connect (c->context, c->server, 0, NULL) < 0) {
- GST_WARNING ("Failed to connect context: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to connect context: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
pa_threaded_mainloop_wait (c->mainloop);
if (pa_context_get_state (c->context) != PA_CONTEXT_READY) {
- GST_WARNING ("Failed to connect context: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to connect context: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
#define CHECK_DEAD_GOTO(c, label) do { \
if (!(c)->context || pa_context_get_state((c)->context) != PA_CONTEXT_READY) { \
- GST_WARNING("Not connected: %s", (c)->context ? pa_strerror(pa_context_errno((c)->context)) : "NULL"); \
+ GST_WARNING_OBJECT((c)->object, "Not connected: %s", (c)->context ? pa_strerror(pa_context_errno((c)->context)) : "NULL"); \
goto label; \
} \
} while(0);
if (!(o =
pa_context_get_sink_info_list (c->context,
gst_pulseprobe_sink_info_cb, c))) {
- GST_WARNING ("Failed to get sink info: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to get sink info: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
}
if (!c->operation_success) {
- GST_WARNING ("Failed to get sink info: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to get sink info: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
if (!(o =
pa_context_get_source_info_list (c->context,
gst_pulseprobe_source_info_cb, c))) {
- GST_WARNING ("Failed to get source info: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to get source info: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
}
if (!c->operation_success) {
- GST_WARNING ("Failed to get sink info: %s",
+ GST_WARNING_OBJECT (c->object, "Failed to get sink info: %s",
pa_strerror (pa_context_errno (c->context)));
goto unlock_and_fail;
}
}
GstPulseProbe *
-gst_pulseprobe_new (GObjectClass * klass, guint prop_id, const gchar * server,
- gboolean sinks, gboolean sources)
+gst_pulseprobe_new (GObject * object, GObjectClass * klass, guint prop_id,
+ const gchar * server, gboolean sinks, gboolean sources)
{
GstPulseProbe *c = NULL;
c = g_new (GstPulseProbe, 1);
+ c->object = g_object_ref (object);
c->server = g_strdup (server);
c->enumerate_sinks = sinks;
c->enumerate_sources = sources;
g_list_foreach (c->devices, (GFunc) g_free, NULL);
g_list_free (c->devices);
+ g_object_unref (c->object);
+
g_free (c);
}
if (prop_id == c->prop_id)
return !c->devices_valid;
- G_OBJECT_WARN_INVALID_PROPERTY_ID (c, prop_id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (c->object, prop_id, pspec);
return FALSE;
}
{
if (prop_id != c->prop_id) {
- G_OBJECT_WARN_INVALID_PROPERTY_ID (c, prop_id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (c->object, prop_id, pspec);
return;
}
GList *item;
if (prop_id != c->prop_id) {
- G_OBJECT_WARN_INVALID_PROPERTY_ID (c, prop_id, pspec);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (c->object, prop_id, pspec);
return NULL;
}
array = g_value_array_new (g_list_length (c->devices));
g_value_init (&value, G_TYPE_STRING);
for (item = c->devices; item != NULL; item = item->next) {
- GST_WARNING ("device found: %s", (const gchar *) item->data);
+ GST_WARNING_OBJECT (c->object, "device found: %s",
+ (const gchar *) item->data);
g_value_set_string (&value, (const gchar *) item->data);
g_value_array_append (array, &value);
}
struct _GstPulseProbe
{
+ GObject *object;
gchar *server;
GList *devices;
int devices_valid;
int operation_success;
};
-GstPulseProbe *gst_pulseprobe_new (GObjectClass * klass, guint prop_id,
- const gchar * server, gboolean sinks, gboolean sources);
+GstPulseProbe *gst_pulseprobe_new (GObject *object, GObjectClass * klass,
+ guint prop_id, const gchar * server, gboolean sinks, gboolean sources);
void gst_pulseprobe_free (GstPulseProbe * probe);
const GList *gst_pulseprobe_get_properties (GstPulseProbe * probe);
e = pa_threaded_mainloop_start (pulsesink->mainloop);
g_assert (e == 0);
- pulsesink->probe = gst_pulseprobe_new (G_OBJECT_GET_CLASS (pulsesink), PROP_DEVICE, pulsesink->device, TRUE, FALSE); /* TRUE for sinks, FALSE for sources */
+ pulsesink->probe = gst_pulseprobe_new (G_OBJECT (pulsesink), G_OBJECT_GET_CLASS (pulsesink), PROP_DEVICE, pulsesink->device, TRUE, FALSE); /* TRUE for sinks, FALSE for sources */
}
static void
if (!pulsesink->context
|| pa_context_get_state (pulsesink->context) != PA_CONTEXT_READY) {
GST_ELEMENT_ERROR (pulsesink, RESOURCE, FAILED, ("Bad context state: %s",
- pulsesink->context ? pa_strerror (pa_context_errno (pulsesink->
- context)) : NULL), (NULL));
+ pulsesink->
+ context ? pa_strerror (pa_context_errno (pulsesink->context)) :
+ NULL), (NULL));
goto unlock_and_fail;
}
if (!(pulsesink->stream = pa_stream_new (pulsesink->context,
- pulsesink->stream_name ? pulsesink->
- stream_name : "Playback Stream", &pulsesink->sample_spec,
+ pulsesink->
+ stream_name ? pulsesink->stream_name : "Playback Stream",
+ &pulsesink->sample_spec,
gst_pulse_gst_to_channel_map (&channel_map, spec)))) {
GST_ELEMENT_ERROR (pulsesink, RESOURCE, FAILED,
("Failed to create stream: %s",
pulsesrc->mixer = NULL;
- pulsesrc->probe = gst_pulseprobe_new (G_OBJECT_GET_CLASS (pulsesrc), PROP_DEVICE, pulsesrc->device, FALSE, TRUE); /* FALSE for sinks, TRUE for sources */
+ pulsesrc->probe = gst_pulseprobe_new (G_OBJECT (pulsesrc), G_OBJECT_GET_CLASS (pulsesrc), PROP_DEVICE, pulsesrc->device, FALSE, TRUE); /* FALSE for sinks, TRUE for sources */
}
static void
if (!pulsesrc->context
|| pa_context_get_state (pulsesrc->context) != PA_CONTEXT_READY) {
GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Bad context state: %s",
- pulsesrc->context ? pa_strerror (pa_context_errno (pulsesrc->
- context)) : NULL), (NULL));
+ pulsesrc->
+ context ? pa_strerror (pa_context_errno (pulsesrc->context)) :
+ NULL), (NULL));
goto unlock_and_fail;
}
goto unlock_and_fail;
}
- GST_WARNING ("Not data while querying latency");
+ GST_WARNING_OBJECT (pulsesrc, "Not data while querying latency");
t = 0;
} else if (negative)
t = 0;
if (!this->mixer)
this->mixer =
- gst_pulsemixer_ctrl_new (this->server, this->device,
- GST_PULSEMIXER_SOURCE);
+ gst_pulsemixer_ctrl_new (G_OBJECT (this), this->server,
+ this->device, GST_PULSEMIXER_SOURCE);
break;