[Spice-devel] [spice-gtk sound rework 3/4 (take 6)] Use the new snd_codec interface to process encoded audio.

Jeremy White jwhite at codeweavers.com
Wed Nov 27 11:31:55 PST 2013


Signed-off-by: Jeremy White <jwhite at codeweavers.com>
---
  README                 |    2 +-
  configure.ac           |    8 +---
  gtk/channel-playback.c |   59 ++++++++---------------------
  gtk/channel-record.c   |   99 ++++++++++++++++--------------------------------
  4 files changed, 49 insertions(+), 119 deletions(-)

diff --git a/README b/README
index 530a495..634592c 100644
--- a/README
+++ b/README
@@ -40,7 +40,7 @@ Build dependencies:
  
  . On Fedora: (gtk2-devel if building with --with-gtk=2.0)
  
-gtk3-devel spice-protocol intltool celt051-devel
+gtk3-devel spice-protocol intltool
  openssl-devel pulseaudio-libs-devel pixman-devel
  gobject-introspection-devel libjpeg-turbo-devel zlib-devel
  cyrus-sasl-devel gtk-doc
diff --git a/configure.ac b/configure.ac
index 8efa998..dccc231 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,12 +97,6 @@ AC_SUBST(PIXMAN_CFLAGS)
  AC_SUBST(PIXMAN_LIBS)
  SPICE_GLIB_REQUIRES="${SPICE_GLIB_REQUIRES} pixman-1 >= 0.17.7"
  
-PKG_CHECK_MODULES(CELT051, celt051 >= 0.5.1.1)
-AC_SUBST(CELT051_CFLAGS)
-AC_SUBST(CELT051_LIBS)
-AC_SUBST(CELT051_LIBDIR)
-SPICE_GLIB_REQUIRES="${SPICE_GLIB_REQUIRES} celt051 >= 0.5.1.1"
-
  PKG_CHECK_MODULES(SSL, openssl)
  AC_SUBST(SSL_CFLAGS)
  AC_SUBST(SSL_LIBS)
@@ -687,7 +681,7 @@ SPICE_CFLAGS="$SPICE_CFLAGS $WARN_CFLAGS"
  
  AC_SUBST(SPICE_CFLAGS)
  
-SPICE_GLIB_CFLAGS="$PROTOCOL_CFLAGS $PIXMAN_CFLAGS $CELT051_CFLAGS $PULSE_CFLAGS $GST_CFLAGS $GLIB2_CFLAGS $GIO_CFLAGS $GOBJECT2_CFLAGS $SSL_CFLAGS $SASL_CFLAGS"
+SPICE_GLIB_CFLAGS="$PROTOCOL_CFLAGS $PIXMAN_CFLAGS $PULSE_CFLAGS $GST_CFLAGS $GLIB2_CFLAGS $GIO_CFLAGS $GOBJECT2_CFLAGS $SSL_CFLAGS $SASL_CFLAGS"
  SPICE_GTK_CFLAGS="$SPICE_GLIB_CFLAGS $GTK_CFLAGS "
  
  AC_SUBST(SPICE_GLIB_CFLAGS)
diff --git a/gtk/channel-playback.c b/gtk/channel-playback.c
index 60fc113..37e5c40 100644
--- a/gtk/channel-playback.c
+++ b/gtk/channel-playback.c
@@ -15,8 +15,6 @@
     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/>.
  */
-#include <celt051/celt.h>
-
  #include "spice-client.h"
  #include "spice-common.h"
  #include "spice-channel-priv.h"
@@ -24,6 +22,8 @@
  
  #include "spice-marshal.h"
  
+#include "common/snd_codec.h"
+
  /**
   * SECTION:channel-playback
   * @short_description: audio stream for playback
@@ -48,8 +48,7 @@
  
  struct _SpicePlaybackChannelPrivate {
      int                         mode;
-    CELTMode                    *celt_mode;
-    CELTDecoder                 *celt_decoder;
+    SndCodec                    codec;
      guint32                     frame_count;
      guint32                     last_time;
      guint8                      nchannels;
@@ -91,7 +90,8 @@ static void channel_set_handlers(SpiceChannelClass *klass);
  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);
+        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);
      spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_VOLUME);
      spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_LATENCY);
  }
@@ -107,15 +107,7 @@ static void spice_playback_channel_finalize(GObject *obj)
  {
      SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(obj)->priv;
  
-    if (c->celt_decoder) {
-        celt051_decoder_destroy(c->celt_decoder);
-        c->celt_decoder = NULL;
-    }
-
-    if (c->celt_mode) {
-        celt051_mode_destroy(c->celt_mode);
-        c->celt_mode = NULL;
-    }
+    snd_codec_destroy(&c->codec);
  
      g_free(c->volume);
      c->volume = NULL;
@@ -174,15 +166,7 @@ static void spice_playback_channel_reset(SpiceChannel *channel, gboolean migrati
  {
      SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
  
-    if (c->celt_decoder) {
-        celt051_decoder_destroy(c->celt_decoder);
-        c->celt_decoder = NULL;
-    }
-
-    if (c->celt_mode) {
-        celt051_mode_destroy(c->celt_mode);
-        c->celt_mode = NULL;
-    }
+    snd_codec_destroy(&c->codec);
  
      SPICE_CHANNEL_CLASS(spice_playback_channel_parent_class)->channel_reset(channel, migrating);
  }
@@ -379,18 +363,16 @@ static void playback_handle_data(SpiceChannel *channel, SpiceMsgIn *in)
                            packet->data, packet->data_size);
          break;
      case SPICE_AUDIO_DATA_MODE_CELT_0_5_1: {
-        celt_int16_t pcm[256 * 2];
+        uint8_t pcm[SND_CODEC_CELT_FRAME_SIZE * 2 * 2];
+        int n = sizeof(pcm);
  
-        g_return_if_fail(c->celt_decoder != NULL);
-
-        if (celt051_decode(c->celt_decoder, packet->data,
-                           packet->data_size, pcm) != CELT_OK) {
+        if (snd_codec_decode(c->codec, packet->data, packet->data_size,
+                    pcm, &n) != SND_CODEC_OK) {
              g_warning("celt_decode() error");
              return;
          }
  
-        emit_main_context(channel, SPICE_PLAYBACK_DATA,
-                          (uint8_t *)pcm, sizeof(pcm));
+        emit_main_context(channel, SPICE_PLAYBACK_DATA, pcm, n);
          break;
      }
      default:
@@ -428,7 +410,6 @@ static void playback_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
  {
      SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
      SpiceMsgPlaybackStart *start = spice_msg_in_parsed(in);
-    int celt_mode_err;
  
      CHANNEL_DEBUG(channel, "%s: fmt %d channels %d freq %d time %d", __FUNCTION__,
                    start->format, start->channels, start->frequency, start->time);
@@ -437,6 +418,7 @@ 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;
+    c->codec = NULL;
  
      switch (c->mode) {
      case SPICE_AUDIO_DATA_MODE_RAW:
@@ -444,19 +426,8 @@ static void playback_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
                            start->format, start->channels, start->frequency);
          break;
      case SPICE_AUDIO_DATA_MODE_CELT_0_5_1: {
-        /* TODO: only support one setting now */
-        int frame_size = 256;
-        if (!c->celt_mode)
-            c->celt_mode = celt051_mode_create(start->frequency, start->channels,
-                                               frame_size, &celt_mode_err);
-        if (!c->celt_mode)
-            g_warning("create celt mode failed %d", celt_mode_err);
-
-        if (!c->celt_decoder)
-            c->celt_decoder = celt051_decoder_create(c->celt_mode);
-
-        if (!c->celt_decoder)
-            g_warning("create celt decoder failed");
+        if (snd_codec_create(&c->codec, c->mode, start->frequency, SND_CODEC_DECODE) != SND_CODEC_OK)
+            g_warning("create decoder failed");
  
          emit_main_context(channel, SPICE_PLAYBACK_START,
                            start->format, start->channels, start->frequency);
diff --git a/gtk/channel-record.c b/gtk/channel-record.c
index e1f3ec7..5561358 100644
--- a/gtk/channel-record.c
+++ b/gtk/channel-record.c
@@ -15,8 +15,6 @@
     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/>.
  */
-#include <celt051/celt.h>
-
  #include "spice-client.h"
  #include "spice-common.h"
  #include "spice-channel-priv.h"
@@ -24,6 +22,8 @@
  #include "spice-marshal.h"
  #include "spice-session-priv.h"
  
+#include "common/snd_codec.h"
+
  /**
   * SECTION:channel-record
   * @short_description: audio stream for recording
@@ -51,8 +51,7 @@
  struct _SpiceRecordChannelPrivate {
      int                         mode;
      gboolean                    started;
-    CELTMode                    *celt_mode;
-    CELTEncoder                 *celt_encoder;
+    SndCodec                    codec;
      gsize                       frame_bytes;
      guint8                      *last_frame;
      gsize                       last_frame_current;
@@ -84,15 +83,13 @@ static guint signals[SPICE_RECORD_LAST_SIGNAL];
  static void channel_set_handlers(SpiceChannelClass *klass);
  static void channel_up(SpiceChannel *channel);
  
-#define FRAME_SIZE 256
-#define CELT_BIT_RATE (64 * 1024)
-
  /* ------------------------------------------------------------------ */
  
  static void spice_record_channel_reset_capabilities(SpiceChannel *channel)
  {
      if (!g_getenv("SPICE_DISABLE_CELT"))
-        spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_RECORD_CAP_CELT_0_5_1);
+        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);
      spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_RECORD_CAP_VOLUME);
  }
  
@@ -110,15 +107,7 @@ static void spice_record_channel_finalize(GObject *obj)
      g_free(c->last_frame);
      c->last_frame = NULL;
  
-    if (c->celt_encoder) {
-        celt051_encoder_destroy(c->celt_encoder);
-        c->celt_encoder = NULL;
-    }
-
-    if (c->celt_mode) {
-        celt051_mode_destroy(c->celt_mode);
-        c->celt_mode = NULL;
-    }
+    snd_codec_destroy(&c->codec);
  
      g_free(c->volume);
      c->volume = NULL;
@@ -176,15 +165,7 @@ static void channel_reset(SpiceChannel *channel, gboolean migrating)
      g_free(c->last_frame);
      c->last_frame = NULL;
  
-    if (c->celt_encoder) {
-        celt051_encoder_destroy(c->celt_encoder);
-        c->celt_encoder = NULL;
-    }
-
-    if (c->celt_mode) {
-        celt051_mode_destroy(c->celt_mode);
-        c->celt_mode = NULL;
-    }
+    snd_codec_destroy(&c->codec);
  
      SPICE_CHANNEL_CLASS(spice_record_channel_parent_class)->channel_reset(channel, migrating);
  }
@@ -325,6 +306,7 @@ static void channel_up(SpiceChannel *channel)
  
      rc = SPICE_RECORD_CHANNEL(channel)->priv;
      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;
      } else {
@@ -363,12 +345,12 @@ void spice_record_send_data(SpiceRecordChannel *channel, gpointer data,
  {
      SpiceRecordChannelPrivate *rc;
      SpiceMsgcRecordPacket p = {0, };
-    int celt_compressed_frame_bytes = FRAME_SIZE * CELT_BIT_RATE / 44100 / 8;
-    uint8_t *celt_buf = NULL;
  
      g_return_if_fail(channel != NULL);
      g_return_if_fail(spice_channel_get_read_only(SPICE_CHANNEL(channel)) == FALSE);
  
+    uint8_t *encode_buf = NULL;
+
      rc = channel->priv;
  
      if (!rc->started) {
@@ -377,8 +359,8 @@ void spice_record_send_data(SpiceRecordChannel *channel, gpointer data,
          rc->started = TRUE;
      }
  
-    if (rc->mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1)
-        celt_buf = g_alloca(celt_compressed_frame_bytes);
+    if (rc->mode != SPICE_AUDIO_DATA_MODE_RAW)
+        encode_buf = g_alloca(SND_CODEC_MAX_COMPRESSED_BYTES);
  
      p.time = time;
  
@@ -412,14 +394,14 @@ void spice_record_send_data(SpiceRecordChannel *channel, gpointer data,
              break;
          }
  
-        if (rc->mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1) {
-            frame_size = celt051_encode(rc->celt_encoder, (celt_int16_t *)frame, NULL, celt_buf,
-                               celt_compressed_frame_bytes);
-            if (frame_size < 0) {
-                g_warning("celt encode failed");
+        if (rc->mode != SPICE_AUDIO_DATA_MODE_RAW) {
+            int len = SND_CODEC_MAX_COMPRESSED_BYTES;
+            if (snd_codec_encode(rc->codec, frame, frame_size, encode_buf, &len) != SND_CODEC_OK) {
+                g_warning("encode failed");
                  return;
              }
-            frame = celt_buf;
+            frame = encode_buf;
+            frame_size = len;
          }
  
          msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_RECORD_DATA);
@@ -446,42 +428,25 @@ static void record_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
      CHANNEL_DEBUG(channel, "%s: fmt %d channels %d freq %d", __FUNCTION__,
                    start->format, start->channels, start->frequency);
  
-    c->frame_bytes = FRAME_SIZE * 16 * start->channels / 8;
+    g_return_if_fail(start->format == SPICE_AUDIO_FMT_S16);
  
-    g_free(c->last_frame);
-    c->last_frame = g_malloc(c->frame_bytes);
-    c->last_frame_current = 0;
+    c->codec = NULL;
+    c->frame_bytes = SND_CODEC_MAX_FRAME_SIZE * 16 * start->channels / 8;
  
-    switch (c->mode) {
-    case SPICE_AUDIO_DATA_MODE_RAW:
-        emit_main_context(channel, SPICE_RECORD_START,
-                          start->format, start->channels, start->frequency);
-        break;
-    case SPICE_AUDIO_DATA_MODE_CELT_0_5_1: {
-        int celt_mode_err;
-
-        g_return_if_fail(start->format == SPICE_AUDIO_FMT_S16);
-
-        if (!c->celt_mode)
-            c->celt_mode = celt051_mode_create(start->frequency, start->channels, FRAME_SIZE,
-                                               &celt_mode_err);
-        if (!c->celt_mode)
-            g_warning("Failed to create celt mode");
+    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->celt_encoder)
-            c->celt_encoder = celt051_encoder_create(c->celt_mode);
+        if (snd_codec_create(&c->codec, c->mode, start->frequency, SND_CODEC_ENCODE) != SND_CODEC_OK)
+            g_warning("Failed to create encoder");
+    }
  
-        if (!c->celt_encoder)
-            g_warning("Failed to create celt encoder");
+    g_free(c->last_frame);
+    c->last_frame = g_malloc(c->frame_bytes);
+    c->last_frame_current = 0;
  
-        emit_main_context(channel, SPICE_RECORD_START,
-                          start->format, start->channels, start->frequency);
-        break;
-    }
-    default:
-        g_warning("%s: unhandled mode %d", __FUNCTION__, c->mode);
-        break;
-    }
+    emit_main_context(channel, SPICE_RECORD_START,
+                      start->format, start->channels, start->frequency);
  }
  
  /* coroutine context */
-- 
1.7.10.4



More information about the Spice-devel mailing list