[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