[Spice-devel] [PATCH spice-gtk 5/8] channel-playback: support SPICE_MSG_PLAYBACK_LATENCY

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


Add a new property for minimum playback latency. This property is
updated with the value from SPICE_MSG_PLAYBACK_LATENCY.
I also increased the default latency from 100ms to 200ms in order to
be more robust to different bandwidth settings.
---
 gtk/channel-playback.c | 31 +++++++++++++++++++++++++++++++
 spice-common           |  2 +-
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/gtk/channel-playback.c b/gtk/channel-playback.c
index 7cbfa36..1c41940 100644
--- a/gtk/channel-playback.c
+++ b/gtk/channel-playback.c
@@ -57,6 +57,7 @@ struct _SpicePlaybackChannelPrivate {
     guint8                      mute;
     gboolean                    is_active;
     guint32                     latency;
+    guint32                     min_latency;
 };
 
 G_DEFINE_TYPE(SpicePlaybackChannel, spice_playback_channel, SPICE_TYPE_CHANNEL)
@@ -67,6 +68,7 @@ enum {
     PROP_NCHANNELS,
     PROP_VOLUME,
     PROP_MUTE,
+    PROP_MIN_LATENCY,
 };
 
 /* Signals */
@@ -85,11 +87,14 @@ static void spice_playback_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
 
 /* ------------------------------------------------------------------ */
 
+#define SPICE_PLAYBACK_DEFAULT_LATENCY_MS 200
+
 static void spice_playback_channel_reset_capabilities(SpiceChannel *channel)
 {
     if (!g_getenv("SPICE_DISABLE_CELT"))
         spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_CELT_0_5_1);
     spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_VOLUME);
+    spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_LATENCY);
 }
 
 static void spice_playback_channel_init(SpicePlaybackChannel *channel)
@@ -138,6 +143,9 @@ static void spice_playback_channel_get_property(GObject    *gobject,
     case PROP_MUTE:
         g_value_set_boolean(value, c->mute);
         break;
+    case PROP_MIN_LATENCY:
+        g_value_set_uint(value, c->min_latency);
+        break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
         break;
@@ -218,12 +226,21 @@ static void spice_playback_channel_class_init(SpicePlaybackChannelClass *klass)
                               FALSE,
                               G_PARAM_READWRITE |
                               G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property
+        (gobject_class, PROP_MIN_LATENCY,
+         g_param_spec_uint("min-latency",
+                           "Playback min buffer size (ms)",
+                           "Playback min buffer size (ms)",
+                           0, G_MAXUINT32, SPICE_PLAYBACK_DEFAULT_LATENCY_MS,
+                           G_PARAM_READWRITE |
+                           G_PARAM_STATIC_STRINGS));
     /**
      * SpicePlaybackChannel::playback-start:
      * @channel: the #SpicePlaybackChannel that emitted the signal
      * @format: a #SPICE_AUDIO_FMT
      * @channels: number of channels
      * @rate: audio rate
+     * @latency: minimum playback latency in ms
      *
      * Notify when the playback should start, and provide audio format
      * characteristics.
@@ -299,6 +316,7 @@ struct SPICE_PLAYBACK_START {
     gint format;
     gint channels;
     gint frequency;
+    gint latency;
 };
 
 struct SPICE_PLAYBACK_DATA {
@@ -419,6 +437,7 @@ static void playback_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
     c->frame_count = 0;
     c->last_time = start->time;
     c->is_active = TRUE;
+    c->min_latency = SPICE_PLAYBACK_DEFAULT_LATENCY_MS;
 
     switch (c->mode) {
     case SPICE_AUDIO_DATA_MODE_RAW:
@@ -482,6 +501,17 @@ static void playback_handle_set_mute(SpiceChannel *channel, SpiceMsgIn *in)
     g_object_notify_main_context(G_OBJECT(channel), "mute");
 }
 
+/* coroutine context */
+static void playback_handle_set_latency(SpiceChannel *channel, SpiceMsgIn *in)
+{
+    SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
+    SpiceMsgPlaybackLatency *msg = spice_msg_in_parsed(in);
+
+    c->min_latency = msg->latency_ms;
+    SPICE_DEBUG("%s: notify latency update %u", __FUNCTION__, c->min_latency);
+    g_object_notify_main_context(G_OBJECT(channel), "min-latency");
+}
+
 static const spice_msg_handler playback_handlers[] = {
     [ SPICE_MSG_PLAYBACK_DATA ]            = playback_handle_data,
     [ SPICE_MSG_PLAYBACK_MODE ]            = playback_handle_mode,
@@ -489,6 +519,7 @@ static const spice_msg_handler playback_handlers[] = {
     [ SPICE_MSG_PLAYBACK_STOP ]            = playback_handle_stop,
     [ SPICE_MSG_PLAYBACK_VOLUME ]          = playback_handle_set_volume,
     [ SPICE_MSG_PLAYBACK_MUTE ]            = playback_handle_set_mute,
+    [ SPICE_MSG_PLAYBACK_LATENCY ]         = playback_handle_set_latency,
 };
 
 /* coroutine context */
diff --git a/spice-common b/spice-common
index 09f88f4..e49fc2e 160000
--- a/spice-common
+++ b/spice-common
@@ -1 +1 @@
-Subproject commit 09f88f4a688a156b48c2058dac7a8c0f35e96abd
+Subproject commit e49fc2e7145371d4adafccb902fa3b64e19e64aa
-- 
1.8.1



More information about the Spice-devel mailing list