[Spice-devel] [PATCH spice-gtk 3/8] channel-playback: provide access to playback properties via the session

Yonit Halperin yhalperi at redhat.com
Tue Feb 26 10:04:53 PST 2013


Support checking whether an audio playback is active and what its latency
is.
---
 gtk/Makefile.am             |  1 +
 gtk/channel-playback-priv.h | 23 +++++++++++++++++++++++
 gtk/channel-playback.c      | 24 ++++++++++++++++++++++++
 gtk/spice-session-priv.h    |  3 +++
 gtk/spice-session.c         | 30 ++++++++++++++++++++++++++++++
 5 files changed, 81 insertions(+)
 create mode 100644 gtk/channel-playback-priv.h

diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index eb64b13..6b4219f 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -235,6 +235,7 @@ libspice_client_glib_2_0_la_SOURCES =			\
 	channel-inputs.c				\
 	channel-main.c					\
 	channel-playback.c				\
+	channel-playback-priv.h				\
 	channel-port.c					\
 	channel-record.c				\
 	channel-smartcard.c				\
diff --git a/gtk/channel-playback-priv.h b/gtk/channel-playback-priv.h
new file mode 100644
index 0000000..dc89e2d
--- /dev/null
+++ b/gtk/channel-playback-priv.h
@@ -0,0 +1,23 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+   Copyright (C) 2013 Red Hat, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_PLAYBACK_CHANNEL_PRIV_H__
+#define __SPICE_CLIENT_PLAYBACK_CHANNEL_PRIV_H__
+
+gboolean spice_playback_channel_is_active(SpicePlaybackChannel *channel);
+guint32 spice_playback_channel_get_latency(SpicePlaybackChannel *channel);
+#endif
diff --git a/gtk/channel-playback.c b/gtk/channel-playback.c
index 2d542a7..7cbfa36 100644
--- a/gtk/channel-playback.c
+++ b/gtk/channel-playback.c
@@ -55,6 +55,8 @@ struct _SpicePlaybackChannelPrivate {
     guint8                      nchannels;
     guint16                     *volume;
     guint8                      mute;
+    gboolean                    is_active;
+    guint32                     latency;
 };
 
 G_DEFINE_TYPE(SpicePlaybackChannel, spice_playback_channel, SPICE_TYPE_CHANNEL)
@@ -416,6 +418,7 @@ static void playback_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
 
     c->frame_count = 0;
     c->last_time = start->time;
+    c->is_active = TRUE;
 
     switch (c->mode) {
     case SPICE_AUDIO_DATA_MODE_RAW:
@@ -450,7 +453,10 @@ static void playback_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
 /* coroutine context */
 static void playback_handle_stop(SpiceChannel *channel, SpiceMsgIn *in)
 {
+    SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
+
     emit_main_context(channel, SPICE_PLAYBACK_STOP);
+    c->is_active = FALSE;
 }
 
 /* coroutine context */
@@ -512,6 +518,24 @@ void spice_playback_channel_set_delay(SpicePlaybackChannel *channel, guint32 del
     CHANNEL_DEBUG(channel, "playback set_delay %u ms", delay_ms);
 
     c = channel->priv;
+    c->latency = delay_ms;
     spice_session_set_mm_time(spice_channel_get_session(SPICE_CHANNEL(channel)),
                               c->last_time - delay_ms);
 }
+
+G_GNUC_INTERNAL
+gboolean spice_playback_channel_is_active(SpicePlaybackChannel *channel)
+{
+    g_return_val_if_fail(SPICE_IS_PLAYBACK_CHANNEL(channel), FALSE);
+    return channel->priv->is_active;
+}
+
+G_GNUC_INTERNAL
+guint32 spice_playback_channel_get_latency(SpicePlaybackChannel *channel)
+{
+    g_return_val_if_fail(SPICE_IS_PLAYBACK_CHANNEL(channel), 0);
+    if (!channel->priv->is_active) {
+        return 0;
+    }
+    return channel->priv->latency;
+}
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index 7ee6b6c..4cf5fe9 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -106,6 +106,7 @@ struct _SpiceSessionPrivate {
     SpiceDesktopIntegration *desktop_integration;
     SpiceGtkSession   *gtk_session;
     SpiceUsbDeviceManager *usb_manager;
+    SpicePlaybackChannel *playback_channel;
 };
 
 SpiceSession *spice_session_new_from_session(SpiceSession *session);
@@ -154,6 +155,8 @@ gboolean spice_session_migrate_after_main_init(SpiceSession *session);
 SpiceChannel* spice_session_lookup_channel(SpiceSession *session, gint id, gint type);
 void spice_session_set_uuid(SpiceSession *session, guint8 uuid[16]);
 void spice_session_set_name(SpiceSession *session, const gchar *name);
+gboolean spice_session_is_playback_active(SpiceSession *session);
+guint32 spice_session_get_playback_latency(SpiceSession *session);
 
 G_END_DECLS
 
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index ccc9367..25cd6e4 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -29,6 +29,7 @@
 #include "glib-compat.h"
 #include "wocky-http-proxy.h"
 #include "spice-proxy.h"
+#include "channel-playback-priv.h"
 
 struct channel {
     SpiceChannel      *channel;
@@ -1800,6 +1801,8 @@ void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel)
 
         CHANNEL_DEBUG(channel, "new main channel, switching");
         s->cmain = channel;
+    } else if (SPICE_IS_PLAYBACK_CHANNEL(channel)) {
+        s->playback_channel = SPICE_PLAYBACK_CHANNEL(channel);
     }
 
     g_signal_emit(session, signals[SPICE_SESSION_CHANNEL_NEW], 0, channel);
@@ -2062,3 +2065,30 @@ void spice_session_set_name(SpiceSession *session, const gchar *name)
 
     g_object_notify(G_OBJECT(session), "name");
 }
+
+G_GNUC_INTERNAL
+gboolean spice_session_is_playback_active(SpiceSession *session)
+{
+    SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session);
+
+    g_return_val_if_fail(s != NULL, FALSE);
+
+    return (s->playback_channel &&
+        spice_playback_channel_is_active(s->playback_channel));
+}
+
+G_GNUC_INTERNAL
+guint32 spice_session_get_playback_latency(SpiceSession *session)
+{
+    SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session);
+
+    g_return_val_if_fail(s != NULL, 0);
+
+    if (s->playback_channel &&
+        spice_playback_channel_is_active(s->playback_channel)) {
+        return spice_playback_channel_get_latency(s->playback_channel);
+    } else {
+        SPICE_DEBUG("%s: not implemented when there isn't audio playback", __FUNCTION__);
+        return 0;
+    }
+}
-- 
1.8.1



More information about the Spice-devel mailing list