[Spice-devel] [spice-gtk opus support 5/6 (take 4)] Add support for the Opus codec.

Jeremy White jwhite at codeweavers.com
Wed Nov 27 11:33:20 PST 2013


Signed-off-by: Jeremy White <jwhite at codeweavers.com>
---
  gtk/Makefile.am        |    2 ++
  gtk/channel-playback.c |   49 ++++++++++++++++++------------------------------
  gtk/channel-record.c   |   36 ++++++++++++++++++-----------------
  3 files changed, 39 insertions(+), 48 deletions(-)

diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 9c7300f..62afd36 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 acb6e4e..bff5428 100644
--- a/gtk/channel-playback.c
+++ b/gtk/channel-playback.c
@@ -90,8 +90,11 @@ static void channel_set_handlers(SpiceChannelClass *klass);
  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))
+        if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY))
              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, SND_CODEC_ANY_FREQUENCY))
+            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__);
@@ -420,25 +418,14 @@ static void playback_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
      c->min_latency = SPICE_PLAYBACK_DEFAULT_LATENCY_MS;
      c->codec = NULL;
  
-    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, SND_CODEC_DECODE) != SND_CODEC_OK) {
              g_warning("create decoder failed");
              return;
          }
-
-        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 c99eae3..6b5e944 100644
--- a/gtk/channel-record.c
+++ b/gtk/channel-record.c
@@ -81,15 +81,17 @@ enum {
  static guint signals[SPICE_RECORD_LAST_SIGNAL];
  
  static void channel_set_handlers(SpiceChannelClass *klass);
-static void channel_up(SpiceChannel *channel);
  
  /* ------------------------------------------------------------------ */
  
  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))
+        if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY))
              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, SND_CODEC_ANY_FREQUENCY))
+            spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_RECORD_CAP_OPUS);
      spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_RECORD_CAP_VOLUME);
  }
  
@@ -178,7 +180,6 @@ static void spice_record_channel_class_init(SpiceRecordChannelClass *klass)
      gobject_class->finalize     = spice_record_channel_finalize;
      gobject_class->get_property = spice_record_channel_get_property;
      gobject_class->set_property = spice_record_channel_set_property;
-    channel_class->channel_up   = channel_up;
      channel_class->channel_reset = channel_reset;
      channel_class->channel_reset_capabilities = spice_record_channel_reset_capabilities;
  
@@ -299,18 +300,18 @@ static void spice_record_mode(SpiceRecordChannel *channel, uint32_t time,
      spice_msg_out_send(msg);
  }
  
-/* coroutine context */
-static void channel_up(SpiceChannel *channel)
+static int spice_record_desired_mode(SpiceChannel *channel, int frequency)
  {
-    SpiceRecordChannelPrivate *rc;
-
-    rc = SPICE_RECORD_CHANNEL(channel)->priv;
-    if (!g_getenv("SPICE_DISABLE_CELT") &&
-        snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1) &&
+    if (!g_getenv("SPICE_DISABLE_OPUS") &&
+        snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_OPUS, frequency) &&
+        spice_channel_test_capability(channel, SPICE_RECORD_CAP_OPUS)) {
+        return SPICE_AUDIO_DATA_MODE_OPUS;
+    } else if (!g_getenv("SPICE_DISABLE_CELT") &&
+        snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, frequency) &&
          spice_channel_test_capability(channel, SPICE_RECORD_CAP_CELT_0_5_1)) {
-        rc->mode = SPICE_AUDIO_DATA_MODE_CELT_0_5_1;
+        return SPICE_AUDIO_DATA_MODE_CELT_0_5_1;
      } else {
-        rc->mode = SPICE_AUDIO_DATA_MODE_RAW;
+        return SPICE_AUDIO_DATA_MODE_RAW;
      }
  }
  
@@ -424,6 +425,9 @@ static void record_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
  {
      SpiceRecordChannelPrivate *c = SPICE_RECORD_CHANNEL(channel)->priv;
      SpiceMsgRecordStart *start = spice_msg_in_parsed(in);
+    int frame_size = SND_CODEC_MAX_FRAME_SIZE;
+
+    c->mode = spice_record_desired_mode(channel, start->frequency);
  
      CHANNEL_DEBUG(channel, "%s: fmt %d channels %d freq %d", __FUNCTION__,
                    start->format, start->channels, start->frequency);
@@ -431,19 +435,17 @@ static void record_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
      g_return_if_fail(start->format == SPICE_AUDIO_FMT_S16);
  
      c->codec = NULL;
-    c->frame_bytes = SND_CODEC_MAX_FRAME_SIZE * 16 * start->channels / 8;
-
-    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, SND_CODEC_ENCODE) != SND_CODEC_OK) {
              g_warning("Failed to create encoder");
              return;
          }
+        frame_size = snd_codec_frame_size(c->codec);
      }
  
      g_free(c->last_frame);
+    c->frame_bytes = frame_size * 16 * start->channels / 8;
      c->last_frame = g_malloc(c->frame_bytes);
      c->last_frame_current = 0;
  
-- 
1.7.10.4



More information about the Spice-devel mailing list