mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice-gtk
synced 2026-01-16 06:17:50 +00:00
Add support for the Opus codec.
Signed-off-by: Jeremy White <jwhite@codeweavers.com>
This commit is contained in:
parent
2db6067269
commit
15dc23327e
@ -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) \
|
||||
|
||||
@ -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,28 +360,22 @@ 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 */
|
||||
|
||||
@ -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 +1 @@
|
||||
Subproject commit c108e4ee8cb33218d9a64e25de9e79b63d23a8e7
|
||||
Subproject commit 57ce430ccd66bd1ca2447c14503234cfb88e2365
|
||||
Loading…
Reference in New Issue
Block a user