summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.com>2013-08-18 23:32:22 -0400
committerOlivier CrĂȘte <olivier.crete@collabora.com>2013-08-22 13:32:04 -0400
commit691b04e5c949ba85aa8e6dc8f5259017c4f652af (patch)
tree2bc22aebb77822dc68a6bb885c56ab2d1676eddd /ext
parentd56f4718c2349adade11adb0400e2ab8679fce7f (diff)
downloadgstreamer-691b04e5c949ba85aa8e6dc8f5259017c4f652af.tar.gz
pulsesrc: Add property to find out the device currently in use
https://bugzilla.gnome.org/show_bug.cgi?id=590768
Diffstat (limited to 'ext')
-rw-r--r--ext/pulse/pulsesrc.c101
-rw-r--r--ext/pulse/pulsesrc.h2
2 files changed, 103 insertions, 0 deletions
diff --git a/ext/pulse/pulsesrc.c b/ext/pulse/pulsesrc.c
index ac19f179e0..2786794641 100644
--- a/ext/pulse/pulsesrc.c
+++ b/ext/pulse/pulsesrc.c
@@ -53,6 +53,7 @@ GST_DEBUG_CATEGORY_EXTERN (pulse_debug);
#define DEFAULT_SERVER NULL
#define DEFAULT_DEVICE NULL
+#define DEFAULT_CURRENT_DEVICE NULL
#define DEFAULT_DEVICE_NAME NULL
#define DEFAULT_VOLUME 1.0
@@ -65,6 +66,7 @@ enum
PROP_SERVER,
PROP_DEVICE,
PROP_DEVICE_NAME,
+ PROP_CURRENT_DEVICE,
PROP_CLIENT_NAME,
PROP_STREAM_PROPERTIES,
PROP_SOURCE_OUTPUT_INDEX,
@@ -156,6 +158,11 @@ gst_pulsesrc_class_init (GstPulseSrcClass * klass)
"The PulseAudio source device to connect to", DEFAULT_DEVICE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_CURRENT_DEVICE,
+ g_param_spec_string ("current-device", "Current Device",
+ "The current PulseAudio source device", DEFAULT_CURRENT_DEVICE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
g_object_class_install_property (gobject_class,
PROP_DEVICE_NAME,
g_param_spec_string ("device-name", "Device name",
@@ -330,6 +337,7 @@ gst_pulsesrc_finalize (GObject * object)
g_free (pulsesrc->server);
g_free (pulsesrc->device);
g_free (pulsesrc->client_name);
+ g_free (pulsesrc->current_source_name);
if (pulsesrc->properties)
gst_structure_free (pulsesrc->properties);
@@ -445,6 +453,7 @@ gst_pulsesrc_source_output_info_cb (pa_context * c,
if (i->index == psrc->source_output_idx) {
psrc->volume = pa_sw_volume_to_linear (pa_cvolume_max (&i->volume));
psrc->mute = i->mute;
+ psrc->current_source_idx = i->source;
if (G_UNLIKELY (psrc->volume > MAX_VOLUME)) {
GST_WARNING_OBJECT (psrc, "Clipped volume from %f to %f",
@@ -525,6 +534,88 @@ info_failed:
}
static void
+gst_pulsesrc_current_source_info_cb (pa_context * c, const pa_source_info * i,
+ int eol, void *userdata)
+{
+ GstPulseSrc *psrc;
+
+ psrc = GST_PULSESRC_CAST (userdata);
+
+ if (!i)
+ goto done;
+
+ /* If the index doesn't match our current stream,
+ * it implies we just recreated the stream (caps change)
+ */
+ if (i->index == psrc->current_source_idx) {
+ g_free (psrc->current_source_name);
+ psrc->current_source_name = g_strdup (i->name);
+ }
+
+done:
+ pa_threaded_mainloop_signal (psrc->mainloop, 0);
+}
+
+static gchar *
+gst_pulsesrc_get_current_device (GstPulseSrc * pulsesrc)
+{
+ pa_operation *o = NULL;
+ gchar *current_src;
+
+ if (!pulsesrc->mainloop)
+ goto no_mainloop;
+
+ if (pulsesrc->source_output_idx == PA_INVALID_INDEX)
+ goto no_index;
+
+ gst_pulsesrc_get_source_output_info (pulsesrc, NULL, NULL);
+
+ pa_threaded_mainloop_lock (pulsesrc->mainloop);
+
+
+ if (!(o = pa_context_get_source_info_by_index (pulsesrc->context,
+ pulsesrc->current_source_idx, gst_pulsesrc_current_source_info_cb,
+ pulsesrc)))
+ goto info_failed;
+
+ while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) {
+ pa_threaded_mainloop_wait (pulsesrc->mainloop);
+ if (gst_pulsesrc_is_dead (pulsesrc, TRUE))
+ goto unlock;
+ }
+
+unlock:
+
+ current_src = g_strdup (pulsesrc->current_source_name);
+
+ if (o)
+ pa_operation_unref (o);
+
+ pa_threaded_mainloop_unlock (pulsesrc->mainloop);
+
+ return current_src;
+
+ /* ERRORS */
+no_mainloop:
+ {
+ GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop");
+ return NULL;
+ }
+no_index:
+ {
+ GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index");
+ return NULL;
+ }
+info_failed:
+ {
+ GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
+ ("pa_context_get_source_output_info() failed: %s",
+ pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
+ goto unlock;
+ }
+}
+
+static void
gst_pulsesrc_set_stream_volume (GstPulseSrc * pulsesrc, gdouble volume)
{
pa_cvolume v;
@@ -743,6 +834,15 @@ gst_pulsesrc_get_property (GObject * object,
case PROP_DEVICE:
g_value_set_string (value, pulsesrc->device);
break;
+ case PROP_CURRENT_DEVICE:
+ {
+ gchar *current_device = gst_pulsesrc_get_current_device (pulsesrc);
+ if (current_device)
+ g_value_take_string (value, current_device);
+ else
+ g_value_set_string (value, "");
+ break;
+ }
case PROP_DEVICE_NAME:
g_value_take_string (value, gst_pulsesrc_device_description (pulsesrc));
break;
@@ -990,6 +1090,7 @@ gst_pulsesrc_read (GstAudioSrc * asrc, gpointer data, guint length,
if (g_atomic_int_compare_and_exchange (&pulsesrc->notify, 1, 0)) {
g_object_notify (G_OBJECT (pulsesrc), "volume");
g_object_notify (G_OBJECT (pulsesrc), "mute");
+ g_object_notify (G_OBJECT (pulsesrc), "current-device");
}
pa_threaded_mainloop_lock (pulsesrc->mainloop);
diff --git a/ext/pulse/pulsesrc.h b/ext/pulse/pulsesrc.h
index 967fc41548..efa7d97edc 100644
--- a/ext/pulse/pulsesrc.h
+++ b/ext/pulse/pulsesrc.h
@@ -71,6 +71,8 @@ struct _GstPulseSrc
gboolean volume_set:1;
gboolean mute:1;
gboolean mute_set:1;
+ guint32 current_source_idx;
+ gchar *current_source_name;
gint notify; /* atomic */