Signed-off-by: Jeremy White <jwhite@xxxxxxxxxxxxxxx> --- 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 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel