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

Jeremy White jwhite at codeweavers.com
Tue Nov 5 14:25:23 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 c42066f..a11d434 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)
@@ -653,7 +647,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..bcb4728 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, FALSE, TRUE) != 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..67d4a26 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, TRUE, FALSE) != 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