[Spice-devel] [spice-server v3 10/10] sound: Convert SndChannelClient to RedChannelClient

Frediano Ziglio fziglio at redhat.com
Thu Jan 26 12:39:32 UTC 2017


> 
> SndChannelClient is now inheriting from GObject, and has switched
> from using its own code for sending data to using RedChannelClient.
> This commit makes it directly inherit from RedChannelClient rather than
> having a channel_client field. This allows to get rid of the whole
> DummyChannel/DummyChannelClient code.
> 
> Based on a patch from Frediano Ziglio <fziglio at redhat.com>
> 
> Signed-off-by: Christophe Fergeau <cfergeau at redhat.com>
> ---
>  server/Makefile.am            |   2 -
>  server/dummy-channel-client.c | 140 ----------------------
>  server/dummy-channel-client.h |  65 -----------
>  server/sound.c                | 262
>  +++++++++++++++++-------------------------
>  4 files changed, 103 insertions(+), 366 deletions(-)
>  delete mode 100644 server/dummy-channel-client.c
>  delete mode 100644 server/dummy-channel-client.h
> 

...

> diff --git a/server/sound.c b/server/sound.c
> index 7738de4..899eecf 100644
> --- a/server/sound.c
> +++ b/server/sound.c
> @@ -31,13 +31,10 @@
>  
>  #include "spice.h"
>  #include "red-common.h"
> -#include "dummy-channel-client.h"
>  #include "main-channel.h"
>  #include "reds.h"
>  #include "red-qxl.h"
>  #include "red-channel-client.h"
> -/* FIXME: for now, allow sound channel access to private RedChannelClient
> data */
> -#include "red-channel-client-private.h"
>  #include "red-client.h"
>  #include "sound.h"
>  #include "main-channel-client.h"
> @@ -84,17 +81,15 @@ typedef struct SpiceRecordState RecordChannel;
>  
>  typedef void (*snd_channel_on_message_done_proc)(SndChannelClient *client);
>  
> +
>  #define TYPE_SND_CHANNEL_CLIENT snd_channel_client_get_type()
>  #define SND_CHANNEL_CLIENT(obj) \
>      (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_SND_CHANNEL_CLIENT,
>      SndChannelClient))
> -#define IS_SND_CHANNEL_CLIENT(obj) \
> -    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SND_CHANNEL_CLIENT))
>  GType snd_channel_client_get_type(void) G_GNUC_CONST;
>  
>  /* Connects an audio client to a Spice client */
>  struct SndChannelClient {
> -    GObject parent;
> -    RedChannelClient *channel_client;
> +    RedChannelClient parent;
>  
>      int active;
>      int client_active;
> @@ -110,10 +105,10 @@ struct SndChannelClient {
>  };
>  
>  typedef struct SndChannelClientClass {
> -    GObjectClass parent_class;
> +    RedChannelClientClass parent_class;
>  } SndChannelClientClass;
>  
> -G_DEFINE_TYPE(SndChannelClient, snd_channel_client, G_TYPE_OBJECT)
> +G_DEFINE_TYPE(SndChannelClient, snd_channel_client, RED_TYPE_CHANNEL_CLIENT)
>  
>  
>  enum {
> @@ -253,65 +248,10 @@ static void snd_playback_start(SndChannel *channel);
>  static void snd_record_start(SndChannel *channel);
>  static void snd_send(SndChannelClient * client);
>  
> -enum {
> -    PROP0,
> -    PROP_CHANNEL_CLIENT
> -};
> -
> -static void
> -snd_channel_client_set_property(GObject *object,
> -                                guint property_id,
> -                                const GValue *value,
> -                                GParamSpec *pspec)
> -{
> -    SndChannelClient *self = SND_CHANNEL_CLIENT(object);
> -
> -    switch (property_id)
> -    {
> -        case PROP_CHANNEL_CLIENT:
> -            self->channel_client = g_value_dup_object(value);
> -            break;
> -        default:
> -            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
> -    }
> -}
> -
> -static SndChannelClient *snd_channel_client_from_dummy(RedChannelClient
> *dummy)
> -{
> -    SndChannelClient *sound_client;
> -
> -    g_assert(IS_DUMMY_CHANNEL_CLIENT(dummy));
> -    sound_client =  g_object_get_data(G_OBJECT(dummy),
> "sound-channel-client");
> -    g_assert(IS_SND_CHANNEL_CLIENT(sound_client));
> -
> -    return sound_client;
> -}
> -
>  static RedsState* snd_channel_get_server(SndChannelClient *client)
>  {
>      g_return_val_if_fail(client != NULL, NULL);
> -    return
> red_channel_get_server(red_channel_client_get_channel(client->channel_client));
> -}
> -
> -static void snd_disconnect_channel(SndChannelClient *client)
> -{
> -    SndChannel *channel;
> -    RedChannel *red_channel;
> -    uint32_t type;
> -
> -    if (!client || !red_channel_client_is_connected(client->channel_client))
> {
> -        spice_debug("not connected");
> -        return;
> -    }
> -    red_channel = red_channel_client_get_channel(client->channel_client);
> -    g_object_get(red_channel, "channel-type", &type, NULL);
> -    spice_debug("SndChannelClient=%p rcc=%p type=%d",
> -                 client, client->channel_client, type);
> -    channel = SND_CHANNEL(red_channel);
> -    red_channel_client_disconnect(channel->connection->channel_client);
> -    channel->connection->channel_client = NULL;
> -    g_object_unref(client);
> -    channel->connection = NULL;
> +    return
> red_channel_get_server(red_channel_client_get_channel(RED_CHANNEL_CLIENT(client)));
>  }
>  
>  static void snd_playback_free_frame(PlaybackChannelClient *playback_client,
>  AudioFrame *frame)
> @@ -394,8 +334,7 @@ playback_channel_handle_parsed(RedChannelClient *rcc,
> uint32_t size, uint16_t ty
>  static int
>  record_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint16_t
>  type, void *message)
>  {
> -    SndChannelClient *snd_client = snd_channel_client_from_dummy(rcc);
> -    RecordChannelClient *record_client = RECORD_CHANNEL_CLIENT(snd_client);
> +    RecordChannelClient *record_client = RECORD_CHANNEL_CLIENT(rcc);
>  
>      switch (type) {
>      case SPICE_MSGC_RECORD_DATA:
> @@ -439,7 +378,7 @@ record_channel_handle_parsed(RedChannelClient *rcc,
> uint32_t size, uint16_t type
>  
>  static int snd_channel_send_migrate(SndChannelClient *client)
>  {
> -    RedChannelClient *rcc = client->channel_client;
> +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(client);
>      SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
>      SpiceMsgMigrate migrate;
>  
> @@ -460,7 +399,7 @@ static int snd_send_volume(SndChannelClient *client,
> uint32_t cap, int msg)
>  {
>      SpiceMsgAudioVolume *vol;
>      uint8_t c;
> -    RedChannelClient *rcc = client->channel_client;
> +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(client);
>      SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
>      SndChannel *channel = SND_CHANNEL(red_channel_client_get_channel(rcc));
>      SpiceVolumeState *st = &channel->volume;
> @@ -491,7 +430,7 @@ static int snd_playback_send_volume(PlaybackChannelClient
> *playback_client)
>  static int snd_send_mute(SndChannelClient *client, uint32_t cap, int msg)
>  {
>      SpiceMsgAudioMute mute;
> -    RedChannelClient *rcc = client->channel_client;
> +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(client);
>      SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
>      SndChannel *channel = SND_CHANNEL(red_channel_client_get_channel(rcc));
>      SpiceVolumeState *st = &channel->volume;
> @@ -516,8 +455,7 @@ static int snd_playback_send_mute(PlaybackChannelClient
> *playback_client)
>  
>  static int snd_playback_send_latency(PlaybackChannelClient *playback_client)
>  {
> -    SndChannelClient *client = SND_CHANNEL_CLIENT(playback_client);
> -    RedChannelClient *rcc = client->channel_client;
> +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(playback_client);
>      SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
>      SpiceMsgPlaybackLatency latency_msg;
>  
> @@ -532,8 +470,7 @@ static int
> snd_playback_send_latency(PlaybackChannelClient *playback_client)
>  
>  static int snd_playback_send_start(PlaybackChannelClient *playback_client)
>  {
> -    SndChannelClient *client = (SndChannelClient *)playback_client;
> -    RedChannelClient *rcc = client->channel_client;
> +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(playback_client);
>      SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
>      SpiceMsgPlaybackStart start;
>  
> @@ -551,8 +488,7 @@ static int snd_playback_send_start(PlaybackChannelClient
> *playback_client)
>  
>  static int snd_playback_send_stop(PlaybackChannelClient *playback_client)
>  {
> -    SndChannelClient *client = (SndChannelClient *)playback_client;
> -    RedChannelClient *rcc = client->channel_client;
> +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(playback_client);
>  
>      red_channel_client_init_send_data(rcc, SPICE_MSG_PLAYBACK_STOP);
>  
> @@ -573,8 +509,7 @@ static int snd_playback_send_ctl(PlaybackChannelClient
> *playback_client)
>  
>  static int snd_record_send_start(RecordChannelClient *record_client)
>  {
> -    SndChannelClient *client = (SndChannelClient *)record_client;
> -    RedChannelClient *rcc = client->channel_client;
> +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(record_client);
>      SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
>      SpiceMsgRecordStart start;
>  
> @@ -592,8 +527,7 @@ static int snd_record_send_start(RecordChannelClient
> *record_client)
>  
>  static int snd_record_send_stop(RecordChannelClient *record_client)
>  {
> -    SndChannelClient *client = (SndChannelClient *)record_client;
> -    RedChannelClient *rcc = client->channel_client;
> +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(record_client);
>  
>      red_channel_client_init_send_data(rcc, SPICE_MSG_RECORD_STOP);
>  
> @@ -635,8 +569,7 @@ static int snd_record_send_migrate(RecordChannelClient
> *record_client)
>  
>  static int snd_playback_send_write(PlaybackChannelClient *playback_client)
>  {
> -    SndChannelClient *client = (SndChannelClient *)playback_client;
> -    RedChannelClient *rcc = client->channel_client;
> +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(playback_client);
>      SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
>      AudioFrame *frame;
>      SpiceMsgPlaybackPacket msg;
> @@ -661,7 +594,7 @@ static int snd_playback_send_write(PlaybackChannelClient
> *playback_client)
>                                      snd_codec_frame_size(playback_client->codec)
>                                      * sizeof(frame->samples[0]),
>                                      playback_client->encode_buf, &n) !=
>                                      SND_CODEC_OK) {
>              spice_printerr("encode failed");
> -            snd_disconnect_channel(client);
> +            red_channel_client_disconnect(rcc);
>              return FALSE;
>          }
>          spice_marshaller_add_by_ref_full(m, playback_client->encode_buf, n,
> @@ -674,8 +607,7 @@ static int snd_playback_send_write(PlaybackChannelClient
> *playback_client)
>  
>  static int playback_send_mode(PlaybackChannelClient *playback_client)
>  {
> -    SndChannelClient *client = (SndChannelClient *)playback_client;
> -    RedChannelClient *rcc = client->channel_client;
> +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(playback_client);
>      SpiceMarshaller *m = red_channel_client_get_marshaller(rcc);
>      SpiceMsgPlaybackMode mode;
>  
> @@ -712,7 +644,7 @@ static void snd_persistent_pipe_item_free(struct
> RedPipeItem *item)
>  
>  static void snd_send(SndChannelClient * client)
>  {
> -    RedChannelClient *rcc = client->channel_client;
> +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(client);
>  
>      if (!client || !red_channel_client_pipe_is_empty(rcc) ||
>      !client->command) {
>          return;
> @@ -725,8 +657,8 @@ static void snd_send(SndChannelClient * client)
>  
>  static void playback_channel_send_item(RedChannelClient *rcc, G_GNUC_UNUSED
>  RedPipeItem *item)
>  {
> -    SndChannelClient *client = snd_channel_client_from_dummy(rcc);
> -    PlaybackChannelClient *playback_client =
> PLAYBACK_CHANNEL_CLIENT(client);
> +    PlaybackChannelClient *playback_client = PLAYBACK_CHANNEL_CLIENT(rcc);
> +    SndChannelClient *client = SND_CHANNEL_CLIENT(rcc);
>  
>      client->command &= SND_PLAYBACK_MODE_MASK|SND_PLAYBACK_PCM_MASK|
>                         SND_CTRL_MASK|SND_VOLUME_MUTE_MASK|
> @@ -784,8 +716,8 @@ static void playback_channel_send_item(RedChannelClient
> *rcc, G_GNUC_UNUSED RedP
>  
>  static void record_channel_send_item(RedChannelClient *rcc, G_GNUC_UNUSED
>  RedPipeItem *item)
>  {
> -    SndChannelClient *client = snd_channel_client_from_dummy(rcc);
> -    RecordChannelClient *record_client = RECORD_CHANNEL_CLIENT(client);
> +    RecordChannelClient *record_client = RECORD_CHANNEL_CLIENT(rcc);
> +    SndChannelClient *client = SND_CHANNEL_CLIENT(rcc);
>  
>      client->command &= SND_CTRL_MASK|SND_VOLUME_MUTE_MASK|SND_MIGRATE_MASK;
>      while (client->command) {
> @@ -877,7 +809,7 @@ static void snd_channel_on_disconnect(RedChannelClient
> *rcc)
>  static uint8_t*
>  snd_channel_client_alloc_recv_buf(RedChannelClient *rcc, uint16_t type,
>  uint32_t size)
>  {
> -    SndChannelClient *client = snd_channel_client_from_dummy(rcc);
> +    SndChannelClient *client = SND_CHANNEL_CLIENT(rcc);
>      // If message is too big allocate one, this should never happen
>      if (size > sizeof(client->receive_buf)) {
>          return spice_malloc(size);
> @@ -889,7 +821,7 @@ static void
>  snd_channel_client_release_recv_buf(RedChannelClient *rcc, uint16_t type,
>  uint32_t size,
>                                      uint8_t *msg)
>  {
> -    SndChannelClient *client = snd_channel_client_from_dummy(rcc);
> +    SndChannelClient *client = SND_CHANNEL_CLIENT(rcc);
>      if (msg != client->receive_buf) {
>          free(msg);
>      }
> @@ -907,8 +839,8 @@ static void
> snd_disconnect_channel_client(RedChannelClient *rcc)
>  
>      spice_debug("channel-type=%d", type);
>      if (channel->connection) {
> -        spice_assert(channel->connection->channel_client == rcc);
> -        snd_disconnect_channel(channel->connection);
> +        spice_assert(RED_CHANNEL_CLIENT(channel->connection) == rcc);
> +        red_channel_client_disconnect(rcc);
>      }
>  }
>  
> @@ -1065,9 +997,9 @@ void snd_set_playback_latency(RedClient *client,
> uint32_t latency)
>          uint32_t type;
>          g_object_get(RED_CHANNEL(now), "channel-type", &type, NULL);
>          if (type == SPICE_CHANNEL_PLAYBACK && now->connection &&
> -            red_channel_client_get_client(now->connection->channel_client)
> == client) {
> +
> red_channel_client_get_client(RED_CHANNEL_CLIENT(now->connection))
> == client) {
>  
> -            if
> (red_channel_client_test_remote_cap(now->connection->channel_client,
> +            if
> (red_channel_client_test_remote_cap(RED_CHANNEL_CLIENT(now->connection),
>                  SPICE_PLAYBACK_CAP_LATENCY)) {
>                  PlaybackChannelClient* playback =
>                  (PlaybackChannelClient*)now->connection;
>  
> @@ -1143,26 +1075,15 @@ static void
>  playback_channel_client_constructed(GObject *object)
>  {
>      PlaybackChannelClient *playback_client =
>      PLAYBACK_CHANNEL_CLIENT(object);
> -    SndChannelClient *client = SND_CHANNEL_CLIENT(playback_client);
> -    RedChannel *red_channel =
> red_channel_client_get_channel(client->channel_client);
> -    RedClient *red_client =
> red_channel_client_get_client(client->channel_client);
> +    RedChannel *red_channel =
> red_channel_client_get_channel(RED_CHANNEL_CLIENT(playback_client));
> +    RedClient *client =
> red_channel_client_get_client(RED_CHANNEL_CLIENT(playback_client));
>      SndChannel *channel = SND_CHANNEL(red_channel);
>  
>      G_OBJECT_CLASS(playback_channel_client_parent_class)->constructed(object);
>  
> -    if
> (!snd_channel_config_socket(RED_CHANNEL_CLIENT(client->channel_client))) {
> -        g_warning("failed to set sound channel socket parameters");
> -    }
> -
> -    /* SndChannelClient is not yet a RedChannelClient, but we still need to
> go from our
> -     * RedChannelClient implementation (DummyChannelClient) to the
> SndChannelClient instance
> -     * in various vfuncs
> -     */
> -    g_object_set_data(G_OBJECT(client->channel_client),
> "sound-channel-client", client);
> -
>      SND_CHANNEL_CLIENT(playback_client)->on_message_done =
>      snd_playback_on_message_done;
>  
> -    RedChannelClient *rcc = client->channel_client;
> +    RedChannelClient *rcc = RED_CHANNEL_CLIENT(playback_client);
>      int client_can_celt = red_channel_client_test_remote_cap(rcc,
>                                            SPICE_PLAYBACK_CAP_CELT_0_5_1);
>      int client_can_opus = red_channel_client_test_remote_cap(rcc,
> @@ -1180,14 +1101,14 @@ playback_channel_client_constructed(GObject *object)
>          }
>      }
>  
> -    if (!red_client_during_migrate_at_target(red_client)) {
> +    if (!red_client_during_migrate_at_target(client)) {
>          on_new_playback_channel_client(channel,
>          SND_CHANNEL_CLIENT(playback_client));
>      }
>  
>      if (channel->active) {
>          snd_playback_start(channel);
>      }
> -    snd_send(channel->connection);
> +    snd_send(SND_CHANNEL_CLIENT(playback_client));
>  }
>  
>  static void snd_set_playback_peer(RedChannel *red_channel, RedClient
>  *client, RedsStream *stream,
> @@ -1196,20 +1117,43 @@ static void snd_set_playback_peer(RedChannel
> *red_channel, RedClient *client, Re
>                                    int num_caps, uint32_t *caps)
>  {
>      SndChannel *channel = SND_CHANNEL(red_channel);
> +    GArray *common_caps_array = NULL, *caps_array = NULL;
>      PlaybackChannelClient *playback_client;
>  
> -    snd_disconnect_channel(channel->connection);
> +    if (channel->connection) {
> +
> red_channel_client_disconnect(RED_CHANNEL_CLIENT(channel->connection));
> +        channel->connection = NULL;
> +    }
>  
> -    RedChannelClient *rcc =
> -        dummy_channel_client_create(red_channel, client, stream,
> -                                    num_common_caps, common_caps,
> -                                    num_caps, caps);
> -    playback_client = g_object_new(TYPE_PLAYBACK_CHANNEL_CLIENT,
> "channel-client", rcc, NULL);
> -    g_object_unref(rcc);
> +    if (common_caps) {
> +        common_caps_array = g_array_sized_new(FALSE, FALSE, sizeof
> (*common_caps),
> +                                              num_common_caps);
> +        g_array_append_vals(common_caps_array, common_caps,
> num_common_caps);
> +    }
> +    if (caps) {
> +        caps_array = g_array_sized_new(FALSE, FALSE, sizeof (*caps),
> num_caps);
> +        g_array_append_vals(caps_array, caps, num_caps);
> +    }
> +
> +    playback_client = g_initable_new(TYPE_PLAYBACK_CHANNEL_CLIENT,
> +                                     NULL, NULL,
> +                                     "channel", channel,
> +                                     "client", client,
> +                                     "stream", stream,
> +                                     "caps", caps_array,
> +                                     "common-caps", common_caps_array,
> +                                     NULL);
>      g_warn_if_fail(playback_client != NULL);
>      /* FIXME: stream used to be destroyed (reds_stream_free) on failure to
>      create the initable,
>       * is it still the case
>       */

This FIXME does not apply any more.

> +
> +    if (caps_array) {
> +        g_array_unref(caps_array);
> +    }
> +    if (common_caps_array) {
> +        g_array_unref(common_caps_array);
> +    }
>  }
>  
>  static void snd_record_migrate_channel_client(RedChannelClient *rcc)
> @@ -1221,7 +1165,7 @@ static void
> snd_record_migrate_channel_client(RedChannelClient *rcc)
>      spice_assert(channel);
>  
>      if (channel->connection) {
> -        spice_assert(channel->connection->channel_client == rcc);
> +        spice_assert(RED_CHANNEL_CLIENT(channel->connection) == rcc);
>          snd_set_command(channel->connection, SND_MIGRATE_MASK);
>          snd_send(channel->connection);
>      }
> @@ -1264,8 +1208,9 @@ static void snd_record_start(SndChannel *channel)
>      SndChannelClient *client = channel->connection;
>  
>      channel->active = 1;
> -    if (!client)
> +    if (!client) {
>          return;
> +    }
>      RecordChannelClient *record_client = RECORD_CHANNEL_CLIENT(client);
>      spice_assert(!client->active);
>      record_client->read_pos = record_client->write_pos = 0;   //todo:
>      improve by
> @@ -1334,7 +1279,7 @@ static uint32_t snd_get_best_rate(SndChannelClient
> *client, uint32_t cap_opus)
>  {
>      int client_can_opus = TRUE;
>      if (client) {
> -        client_can_opus =
> red_channel_client_test_remote_cap(client->channel_client, cap_opus);
> +        client_can_opus =
> red_channel_client_test_remote_cap(RED_CHANNEL_CLIENT(client), cap_opus);
>      }
>  
>      if (client_can_opus && snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_OPUS,
>      SND_CODEC_ANY_FREQUENCY))
> @@ -1399,48 +1344,60 @@ static void
>  record_channel_client_constructed(GObject *object)
>  {
>      RecordChannelClient *record_client = RECORD_CHANNEL_CLIENT(object);
> -    SndChannelClient *client = SND_CHANNEL_CLIENT(record_client);
> -    RedChannel *red_channel =
> red_channel_client_get_channel(client->channel_client);
> +    RedChannel *red_channel =
> red_channel_client_get_channel(RED_CHANNEL_CLIENT(record_client));
>      SndChannel *channel = SND_CHANNEL(red_channel);
>  
>      G_OBJECT_CLASS(record_channel_client_parent_class)->constructed(object);
>  
> -    if
> (!snd_channel_config_socket(RED_CHANNEL_CLIENT(client->channel_client))) {
> -        g_warning("failed to set sound channel socket parameters");
> -    }
> -
> -    /* SndChannelClient is not yet a RedChannelClient, but we still need to
> go from our
> -     * RedChannelClient implementation (DummyChannelClient) to the
> SndChannelClient instance
> -     * in various vfuncs
> -     */
> -    g_object_set_data(G_OBJECT(client->channel_client),
> "sound-channel-client", client);
> -
>      on_new_record_channel_client(channel,
>      SND_CHANNEL_CLIENT(record_client));
>      if (channel->active) {
>          snd_record_start(channel);
>      }
> -    snd_send(channel->connection);
> +    snd_send(SND_CHANNEL_CLIENT(record_client));
>  }
>  
> +
>  static void snd_set_record_peer(RedChannel *red_channel, RedClient *client,
>  RedsStream *stream,
>                                  G_GNUC_UNUSED int migration,
>                                  int num_common_caps, uint32_t *common_caps,
>                                  int num_caps, uint32_t *caps)
>  {
>      SndChannel *channel = SND_CHANNEL(red_channel);
> +    GArray *common_caps_array = NULL, *caps_array = NULL;
>      RecordChannelClient *record_client;
>  
> -    snd_disconnect_channel(channel->connection);
> +    if (channel->connection) {
> +
> red_channel_client_disconnect(RED_CHANNEL_CLIENT(channel->connection));
> +        channel->connection = NULL;
> +    }
>  
> -    RedChannelClient *rcc =
> -        dummy_channel_client_create(red_channel, client, stream,
> -                                    num_common_caps, common_caps,
> -                                    num_caps, caps);
> -    record_client = g_object_new(TYPE_RECORD_CHANNEL_CLIENT,
> "channel-client", rcc, NULL);
> -    g_object_unref(rcc);
> +    if (common_caps) {
> +        common_caps_array = g_array_sized_new(FALSE, FALSE, sizeof
> (*common_caps),
> +                                              num_common_caps);
> +        g_array_append_vals(common_caps_array, common_caps,
> num_common_caps);
> +    }
> +    if (caps) {
> +        caps_array = g_array_sized_new(FALSE, FALSE, sizeof (*caps),
> num_caps);
> +        g_array_append_vals(caps_array, caps, num_caps);
> +    }
> +
> +    record_client = g_initable_new(TYPE_RECORD_CHANNEL_CLIENT,
> +                                   NULL, NULL,
> +                                   "channel", channel,
> +                                   "client", client,
> +                                   "stream", stream,
> +                                   "caps", caps_array,
> +                                   "common-caps", common_caps_array,
> +                                   NULL);
>      g_warn_if_fail(record_client != NULL);
> -}
>  
> +    if (caps_array) {
> +        g_array_unref(caps_array);
> +    }
> +    if (common_caps_array) {
> +        g_array_unref(common_caps_array);
> +    }
> +}
>  
>  static void snd_playback_migrate_channel_client(RedChannelClient *rcc)
>  {
> @@ -1452,7 +1409,7 @@ static void
> snd_playback_migrate_channel_client(RedChannelClient *rcc)
>      spice_debug(NULL);
>  
>      if (channel->connection) {
> -        spice_assert(channel->connection->channel_client == rcc);
> +        spice_assert(RED_CHANNEL_CLIENT(channel->connection) == rcc);
>          snd_set_command(channel->connection, SND_MIGRATE_MASK);
>          snd_send(channel->connection);
>      }
> @@ -1604,7 +1561,6 @@ static void snd_detach_common(SndChannel *channel)
>      RedsState *reds = red_channel_get_server(RED_CHANNEL(channel));
>  
>      remove_channel(channel);
> -    snd_disconnect_channel(channel->connection);
>      reds_unregister_channel(reds, RED_CHANNEL(channel));
>      free(channel->volume.volume);
>      channel->volume.volume = NULL;
> @@ -1630,7 +1586,7 @@ void snd_set_playback_compression(int on)
>          g_object_get(RED_CHANNEL(now), "channel-type", &type, NULL);
>          if (type == SPICE_CHANNEL_PLAYBACK && now->connection) {
>              PlaybackChannelClient* playback =
>              (PlaybackChannelClient*)now->connection;
> -            RedChannelClient *rcc =
> SND_CHANNEL_CLIENT(playback)->channel_client;
> +            RedChannelClient *rcc = RED_CHANNEL_CLIENT(playback);
>              int client_can_celt = red_channel_client_test_remote_cap(rcc,
>                                      SPICE_PLAYBACK_CAP_CELT_0_5_1);
>              int client_can_opus = red_channel_client_test_remote_cap(rcc,
> @@ -1646,20 +1602,8 @@ void snd_set_playback_compression(int on)
>  }
>  
>  static void
> -snd_channel_client_class_init(SndChannelClientClass *klass)
> +snd_channel_client_class_init(SndChannelClientClass *self)
>  {
> -    GObjectClass *object_class = G_OBJECT_CLASS(klass);
> -    GParamSpec *spec;
> -
> -    object_class->set_property = snd_channel_client_set_property;
> -
> -    spec = g_param_spec_object("channel-client", "channel-client",
> -                               "Associated dummy RedChannelClient",
> -                               RED_TYPE_CHANNEL_CLIENT,
> -                               G_PARAM_STATIC_STRINGS
> -                               | G_PARAM_WRITABLE
> -                               | G_PARAM_CONSTRUCT_ONLY);
> -    g_object_class_install_property(object_class, PROP_CHANNEL_CLIENT,
> spec);
>  }
>  
>  static void

Still think this should be merged to 9/10.

Frediano


More information about the Spice-devel mailing list