[Spice-devel] [opus 4/spice-gtk] Add support for the Opus codec.

Jeremy White jwhite at codeweavers.com
Tue Oct 15 16:29:54 CEST 2013


Signed-off-by: Jeremy White <jwhite at codeweavers.com>
---
 configure.ac           |    9 +++++++++
 gtk/Makefile.am        |    2 ++
 gtk/channel-playback.c |   48 +++++++++++++++++-------------------------------
 gtk/channel-record.c   |   14 +++++++++++---
 4 files changed, 39 insertions(+), 34 deletions(-)

diff --git a/configure.ac b/configure.ac
index 8953446..52a6f5f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -114,6 +114,15 @@ fi
 AM_CONDITIONAL([HAVE_CELT051], [test "x$have_celt051" = "xyes"])
 AM_COND_IF([HAVE_CELT051], AC_DEFINE([HAVE_CELT051], 1, [Define if we have celt051 codec]))
 
+PKG_CHECK_MODULES([OPUS], [opus >= 0.9.14], have_opus=yes, have_opus=no)
+
+AM_CONDITIONAL([HAVE_OPUS], [test "x$have_opus" = "xyes"])
+if test "x$have_opus" = "xyes" ; then
+  AC_DEFINE([HAVE_OPUS], [1], [Define if we have OPUS])
+  SPICE_REQUIRES+=" opus >= 0.9.14"
+  opus_version=`pkg-config --modversion opus`
+fi
+
 PKG_CHECK_MODULES(SSL, openssl)
 AC_SUBST(SSL_CFLAGS)
 AC_SUBST(SSL_LIBS)
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 5af6642..fa4c8e5 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -79,6 +79,7 @@ SPICE_COMMON_CPPFLAGS =						\
 	$(COMMON_CFLAGS)					\
 	$(PIXMAN_CFLAGS)					\
 	$(CELT051_CFLAGS)					\
+	$(OPUS_CFLAGS)  					\
 	$(PULSE_CFLAGS)						\
 	$(GTK_CFLAGS)						\
 	$(CAIRO_CFLAGS)						\
@@ -185,6 +186,7 @@ libspice_client_glib_2_0_la_LIBADD =					\
 	$(GIO_LIBS)							\
 	$(GOBJECT2_LIBS)						\
 	$(CELT051_LIBS)							\
+	$(OPUS_LIBS)							\
 	$(JPEG_LIBS)							\
 	$(Z_LIBS)							\
 	$(PIXMAN_LIBS)							\
diff --git a/gtk/channel-playback.c b/gtk/channel-playback.c
index b692d70..9d13b2d 100644
--- a/gtk/channel-playback.c
+++ b/gtk/channel-playback.c
@@ -92,6 +92,9 @@ static void spice_playback_channel_reset_capabilities(SpiceChannel *channel)
     if (!g_getenv("SPICE_DISABLE_CELT"))
         if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1))
             spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_CELT_0_5_1);
+    if (!g_getenv("SPICE_DISABLE_OPUS"))
+        if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_OPUS))
+            spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_OPUS);
     spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_VOLUME);
     spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_LATENCY);
 }
@@ -357,29 +360,23 @@ static void playback_handle_data(SpiceChannel *channel, SpiceMsgIn *in)
 
     c->last_time = packet->time;
 
-    switch (c->mode) {
-    case SPICE_AUDIO_DATA_MODE_RAW:
-        emit_main_context(channel, SPICE_PLAYBACK_DATA,
-                          packet->data, packet->data_size);
-        break;
-    case SPICE_AUDIO_DATA_MODE_CELT_0_5_1: {
-        uint8_t pcm[SND_CODEC_CELT_FRAME_SIZE * 2 * 2];
-        int n = sizeof(pcm);
+    uint8_t *data = packet->data;
+    int n = packet->data_size;
+    uint8_t pcm[SND_CODEC_MAX_FRAME_SIZE * 2 * 2];
+
+    if (c->mode != SPICE_AUDIO_DATA_MODE_RAW) {
+        n = sizeof(pcm);
+        data = pcm;
 
         if (snd_codec_decode(&c->codec, packet->data, packet->data_size,
                     pcm, &n) != SND_CODEC_OK) {
-            g_warning("celt_decode() error");
+            g_warning("snd_codec_decode() error");
             return;
         }
-
-        emit_main_context(channel, SPICE_PLAYBACK_DATA, pcm, n);
-        break;
-    }
-    default:
-        g_warning("%s: unhandled mode", __FUNCTION__);
-        break;
     }
 
+    emit_main_context(channel, SPICE_PLAYBACK_DATA, data, n);
+
     if ((c->frame_count++ % 100) == 0) {
         emit_main_context(channel, SPICE_PLAYBACK_GET_DELAY);
     }
@@ -398,6 +395,7 @@ static void playback_handle_mode(SpiceChannel *channel, SpiceMsgIn *in)
     switch (c->mode) {
     case SPICE_AUDIO_DATA_MODE_RAW:
     case SPICE_AUDIO_DATA_MODE_CELT_0_5_1:
+    case SPICE_AUDIO_DATA_MODE_OPUS:
         break;
     default:
         g_warning("%s: unhandled mode", __FUNCTION__);
@@ -418,24 +416,12 @@ static void playback_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
     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:
-        emit_main_context(channel, SPICE_PLAYBACK_START,
-                          start->format, start->channels, start->frequency);
-        break;
-    case SPICE_AUDIO_DATA_MODE_CELT_0_5_1: {
+    if (c->mode != SPICE_AUDIO_DATA_MODE_RAW) {
         if (snd_codec_create(&c->codec, c->mode, start->frequency, FALSE, TRUE) != SND_CODEC_OK)
             g_warning("create decoder failed");
-
-        emit_main_context(channel, SPICE_PLAYBACK_START,
-                          start->format, start->channels, start->frequency);
-        break;
-    }
-    default:
-        g_warning("%s: unhandled mode", __FUNCTION__);
-        break;
     }
+    emit_main_context(channel, SPICE_PLAYBACK_START,
+         start->format, start->channels, start->frequency);
 }
 
 /* coroutine context */
diff --git a/gtk/channel-record.c b/gtk/channel-record.c
index a80385b..a0aca3e 100644
--- a/gtk/channel-record.c
+++ b/gtk/channel-record.c
@@ -90,6 +90,9 @@ static void spice_record_channel_reset_capabilities(SpiceChannel *channel)
     if (!g_getenv("SPICE_DISABLE_CELT"))
         if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1))
             spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_RECORD_CAP_CELT_0_5_1);
+    if (!g_getenv("SPICE_DISABLE_OPUS"))
+        if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_OPUS))
+            spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_RECORD_CAP_OPUS);
     spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_RECORD_CAP_VOLUME);
 }
 
@@ -305,7 +308,11 @@ static void channel_up(SpiceChannel *channel)
     SpiceRecordChannelPrivate *rc;
 
     rc = SPICE_RECORD_CHANNEL(channel)->priv;
-    if (!g_getenv("SPICE_DISABLE_CELT") &&
+    if (!g_getenv("SPICE_DISABLE_OPUS") &&
+        snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_OPUS) &&
+        spice_channel_test_capability(channel, SPICE_RECORD_CAP_OPUS)) {
+        rc->mode = SPICE_AUDIO_DATA_MODE_OPUS;
+    } else if (!g_getenv("SPICE_DISABLE_CELT") &&
         snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1) &&
         spice_channel_test_capability(channel, SPICE_RECORD_CAP_CELT_0_5_1)) {
         rc->mode = SPICE_AUDIO_DATA_MODE_CELT_0_5_1;
@@ -432,10 +439,11 @@ static void record_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
 
     c->frame_bytes = SND_CODEC_MAX_FRAME_SIZE * 16 * start->channels / 8;
 
-    if (c->mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1)
-    {
+    if (c->mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1) {
         c->frame_bytes = SND_CODEC_CELT_FRAME_SIZE * 16 * start->channels / 8;
+    }
 
+    if (c->mode != SPICE_AUDIO_DATA_MODE_RAW) {
         if (snd_codec_create(&c->codec, c->mode, start->frequency, TRUE, FALSE) != SND_CODEC_OK)
             g_warning("Failed to create encoder");
     }
-- 
1.7.10.4




More information about the Spice-devel mailing list