[Spice-devel] [spice-gtk PATCH v4 2/6] audio: restore stream data from pulse
Victor Toso
victortoso at redhat.com
Mon Mar 30 04:09:11 PDT 2015
Using ext-stream-restore we can get the last stream data of the
application. This is helpful to spice-pulse in order to provide this
values in case of volume-sync between client and guest.
---
gtk/spice-pulse.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/gtk/spice-pulse.c b/gtk/spice-pulse.c
index 6b27c97..81a5588 100644
--- a/gtk/spice-pulse.c
+++ b/gtk/spice-pulse.c
@@ -25,6 +25,7 @@
#include <pulse/glib-mainloop.h>
#include <pulse/pulseaudio.h>
+#include <pulse/ext-stream-restore.h>
#define SPICE_PULSE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_PULSE, SpicePulsePrivate))
@@ -788,6 +789,52 @@ static gboolean connect_channel(SpiceAudio *audio, SpiceChannel *channel)
return FALSE;
}
+static void stream_restore_read_cb(pa_context *context,
+ const pa_ext_stream_restore_info *info,
+ int eol,
+ void *userdata)
+{
+ SpicePulsePrivate *p = SPICE_PULSE(userdata)->priv;
+ gint i;
+ gchar *sink_name;
+ gchar *source_name;
+ struct stream *pstream = NULL;
+
+ if (eol)
+ return;
+
+ sink_name = g_strconcat("sink-input-by-application-name:",
+ g_get_application_name(), NULL);
+ source_name = g_strconcat("source-output-by-application-name:",
+ g_get_application_name(), NULL);
+
+ if (g_strcmp0(info->name, sink_name) == 0) {
+ pstream = &p->playback;
+ } else if (g_strcmp0(info->name, source_name) == 0) {
+ pstream = &p->record;
+ } else {
+ /* This is not the stream you are looking for. */
+ goto cleanup;
+ }
+
+ if (info->channel_map.channels == 0) {
+ SPICE_DEBUG("%s - Number of channels stored is zero. Ignore.", __func__);
+ goto cleanup;
+ }
+
+ pstream->mute = (info->mute) ? TRUE : FALSE;
+ pstream->nchannels = info->channel_map.channels;
+ pstream->volume = g_new(guint16, pstream->nchannels);
+ for (i = 0; i < pstream->nchannels; i++) {
+ pstream->volume[i] = (guint16) info->volume.values[i];
+ SPICE_DEBUG("%s - volume[%d] %u", __func__, i, pstream->volume[i]);
+ }
+
+cleanup:
+ g_free(sink_name);
+ g_free(source_name);
+}
+
static void sink_input_info_cb(pa_context *context,
const pa_sink_input_info *info,
int eol,
@@ -915,6 +962,19 @@ static void context_state_callback(pa_context *c, void *userdata)
break;
case PA_CONTEXT_READY: {
+ if (p->playback.nchannels == 0 || p->record.nchannels == 0) {
+ pa_operation *op;
+ op = pa_ext_stream_restore_read(p->context,
+ stream_restore_read_cb,
+ pulse);
+ if (op) {
+ pa_operation_unref(op);
+ } else {
+ spice_warning("Restoring stream data failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ }
+ }
+
if (!p->record.stream && p->record.started)
create_record(SPICE_PULSE(userdata));
--
2.1.0
More information about the Spice-devel
mailing list