[Spice-devel] [spice-gtk opus support 5/6 (take 3)] Add support for the Opus codec.

Christophe Fergeau cfergeau at redhat.com
Thu Nov 21 05:28:42 PST 2013


Looks good, ACK (and works in my testing)

Christophe

On Tue, Nov 12, 2013 at 03:53:09PM -0600, Jeremy White wrote:
> Signed-off-by: Jeremy White <jwhite at codeweavers.com>
> ---
>  gtk/Makefile.am        |    2 ++
>  gtk/channel-playback.c |   49 ++++++++++++++++++------------------------------
>  gtk/channel-record.c   |   38 +++++++++++++++++++------------------
>  3 files changed, 40 insertions(+), 49 deletions(-)
> 
> diff --git a/gtk/Makefile.am b/gtk/Makefile.am
> index 5af6642..fa4c8e5 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 f02d08a..a064484 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, FALSE, TRUE) != 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 a238c85..9851b57 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 (snd_codec_create(&c->codec, c->mode, start->frequency, TRUE, FALSE) != SND_CODEC_OK){
> +    if (c->mode != SPICE_AUDIO_DATA_MODE_RAW) {
> +        if (snd_codec_create(&c->codec, c->mode, start->frequency, TRUE, FALSE) != 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20131121/3d62a23a/attachment-0001.pgp>


More information about the Spice-devel mailing list