> 
> This is in preparation for making them inherit from RedChannelClient.
> Doing it in one go would result in a very huge commit, so this commit
> starts by turning these into GObjects, while still using a
> DummyChannelClient instance for sending the data.
> 
> Based on a patch from Frediano Ziglio <fzig...@redhat.com>
> 
> Signed-off-by: Christophe Fergeau <cferg...@redhat.com>

IMO this patch is too artificial, I would merge to 10/10

Frediano

> ---
>  server/sound.c | 326
>  +++++++++++++++++++++++++++++++++++++--------------------
>  1 file changed, 210 insertions(+), 116 deletions(-)
> 
> diff --git a/server/sound.c b/server/sound.c
> index d0cfbf1..7738de4 100644
> --- a/server/sound.c
> +++ b/server/sound.c
> @@ -83,14 +83,17 @@ typedef struct SpicePlaybackState PlaybackChannel;
>  typedef struct SpiceRecordState RecordChannel;
>  
>  typedef void (*snd_channel_on_message_done_proc)(SndChannelClient *client);
> -typedef void (*snd_channel_cleanup_channel_proc)(SndChannelClient *client);
>  
> -#define SND_CHANNEL_CLIENT(obj) (&(obj)->base)
> +#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 {
> -    int refs;
> -
> +    GObject parent;
>      RedChannelClient *channel_client;
>  
>      int active;
> @@ -104,9 +107,14 @@ struct SndChannelClient {
>      RedPipeItem persistent_pipe_item;
>  
>      snd_channel_on_message_done_proc on_message_done;
> -    snd_channel_cleanup_channel_proc cleanup;
>  };
>  
> +typedef struct SndChannelClientClass {
> +    GObjectClass parent_class;
> +} SndChannelClientClass;
> +
> +G_DEFINE_TYPE(SndChannelClient, snd_channel_client, G_TYPE_OBJECT)
> +
>  
>  enum {
>      RED_PIPE_ITEM_PERSISTENT = RED_PIPE_ITEM_TYPE_CHANNEL_BASE,
> @@ -129,8 +137,13 @@ struct AudioFrameContainer
>      AudioFrame items[NUM_AUDIO_FRAMES];
>  };
>  
> +#define TYPE_PLAYBACK_CHANNEL_CLIENT playback_channel_client_get_type()
> +#define PLAYBACK_CHANNEL_CLIENT(obj) \
> +    (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_PLAYBACK_CHANNEL_CLIENT,
> PlaybackChannelClient))
> +GType playback_channel_client_get_type(void) G_GNUC_CONST;
> +
>  struct PlaybackChannelClient {
> -    SndChannelClient base;
> +    SndChannelClient parent;
>  
>      AudioFrameContainer *frames;
>      AudioFrame *free_frames;
> @@ -142,6 +155,13 @@ struct PlaybackChannelClient {
>      uint8_t  encode_buf[SND_CODEC_MAX_COMPRESSED_BYTES];
>  };
>  
> +typedef struct PlaybackChannelClientClass {
> +    SndChannelClientClass parent_class;
> +} PlaybackChannelClientClass;
> +
> +G_DEFINE_TYPE(PlaybackChannelClient, playback_channel_client,
> TYPE_SND_CHANNEL_CLIENT)
> +
> +
>  typedef struct SpiceVolumeState {
>      uint16_t *volume;
>      uint8_t volume_nchannels;
> @@ -202,8 +222,13 @@ typedef struct RecordChannelClass {
>  G_DEFINE_TYPE(RecordChannel, record_channel, TYPE_SND_CHANNEL)
>  
>  
> +#define TYPE_RECORD_CHANNEL_CLIENT record_channel_client_get_type()
> +#define RECORD_CHANNEL_CLIENT(obj) \
> +    (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_RECORD_CHANNEL_CLIENT,
> RecordChannelClient))
> +GType record_channel_client_get_type(void) G_GNUC_CONST;
> +
>  struct RecordChannelClient {
> -    SndChannelClient base;
> +    SndChannelClient parent;
>      uint32_t samples[RECORD_SAMPLES_SIZE];
>      uint32_t write_pos;
>      uint32_t read_pos;
> @@ -214,22 +239,41 @@ struct RecordChannelClient {
>      uint8_t  decode_buf[SND_CODEC_MAX_FRAME_BYTES];
>  };
>  
> +typedef struct RecordChannelClientClass {
> +    SndChannelClientClass parent_class;
> +} RecordChannelClientClass;
> +
> +G_DEFINE_TYPE(RecordChannelClient, record_channel_client,
> TYPE_SND_CHANNEL_CLIENT)
> +
> +
>  /* A list of all Spice{Playback,Record}State objects */
>  static SndChannel *snd_channels;
>  
>  static void snd_playback_start(SndChannel *channel);
>  static void snd_record_start(SndChannel *channel);
> -static void snd_playback_alloc_frames(PlaybackChannelClient *playback);
>  static void snd_send(SndChannelClient * client);
>  
> -static SndChannelClient *snd_channel_unref(SndChannelClient *client)
> +enum {
> +    PROP0,
> +    PROP_CHANNEL_CLIENT
> +};
> +
> +static void
> +snd_channel_client_set_property(GObject *object,
> +                                guint property_id,
> +                                const GValue *value,
> +                                GParamSpec *pspec)
>  {
> -    if (!--client->refs) {
> -        spice_printerr("SndChannelClient=%p freed", client);
> -        free(client);
> -        return NULL;
> +    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);
>      }
> -    return client;
>  }
>  
>  static SndChannelClient *snd_channel_client_from_dummy(RedChannelClient
>  *dummy)
> @@ -238,6 +282,7 @@ static SndChannelClient
> *snd_channel_client_from_dummy(RedChannelClient *dummy)
>  
>      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;
>  }
> @@ -263,10 +308,9 @@ static void snd_disconnect_channel(SndChannelClient
> *client)
>      spice_debug("SndChannelClient=%p rcc=%p type=%d",
>                   client, client->channel_client, type);
>      channel = SND_CHANNEL(red_channel);
> -    client->cleanup(client);
>      red_channel_client_disconnect(channel->connection->channel_client);
>      channel->connection->channel_client = NULL;
> -    snd_channel_unref(client);
> +    g_object_unref(client);
>      channel->connection = NULL;
>  }
>  
> @@ -290,10 +334,6 @@ static void
> snd_playback_on_message_done(SndChannelClient *client)
>      }
>  }
>  
> -static void snd_record_on_message_done(SndChannelClient *client)
> -{
> -}
> -
>  static int snd_record_handle_write(RecordChannelClient *record_client,
>  size_t size, void *message)
>  {
>      SpiceMsgcRecordPacket *packet;
> @@ -355,7 +395,7 @@ 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 = SPICE_CONTAINEROF(snd_client,
> RecordChannelClient, base);
> +    RecordChannelClient *record_client = RECORD_CHANNEL_CLIENT(snd_client);
>  
>      switch (type) {
>      case SPICE_MSGC_RECORD_DATA:
> @@ -648,49 +688,6 @@ static int playback_send_mode(PlaybackChannelClient
> *playback_client)
>      return TRUE;
>  }
>  
> -static int snd_channel_config_socket(RedChannelClient *rcc);
> -
> -static SndChannelClient *__new_channel(SndChannel *channel, int size,
> uint32_t channel_id,
> -                                       RedClient *red_client,
> -                                       RedsStream *stream,
> -                                       snd_channel_on_message_done_proc
> on_message_done,
> -                                       snd_channel_cleanup_channel_proc
> cleanup,
> -                                       uint32_t *common_caps, int
> num_common_caps,
> -                                       uint32_t *caps, int num_caps)
> -{
> -    SndChannelClient *client;
> -
> -    spice_assert(size >= sizeof(*client));
> -    client = spice_malloc0(size);
> -    client->refs = 1;
> -    client->on_message_done = on_message_done;
> -    client->cleanup = cleanup;
> -
> -    client->channel_client =
> -        dummy_channel_client_create(RED_CHANNEL(channel), red_client,
> stream,
> -                                    num_common_caps, common_caps, num_caps,
> caps);
> -    if (!client->channel_client) {
> -        goto error2;
> -    }
> -
> -    /* 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);
> -
> -    if
> (!snd_channel_config_socket(RED_CHANNEL_CLIENT(client->channel_client))) {
> -        goto error2;
> -    }
> -
> -    return client;
> -
> -error2:
> -    free(client);
> -    reds_stream_free(stream);
> -    return NULL;
> -}
> -
>  /* This function is called when the "persistent" item is removed from the
>   * queue. Note that there is not free call as the item is allocated into
>   * SndChannelClient.
> @@ -729,7 +726,7 @@ 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 = SPICE_CONTAINEROF(client,
> PlaybackChannelClient, base);
> +    PlaybackChannelClient *playback_client =
> PLAYBACK_CHANNEL_CLIENT(client);
>  
>      client->command &= SND_PLAYBACK_MODE_MASK|SND_PLAYBACK_PCM_MASK|
>                         SND_CTRL_MASK|SND_VOLUME_MUTE_MASK|
> @@ -788,7 +785,7 @@ 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 = SPICE_CONTAINEROF(client,
> RecordChannelClient, base);
> +    RecordChannelClient *record_client = RECORD_CHANNEL_CLIENT(client);
>  
>      client->command &= SND_CTRL_MASK|SND_VOLUME_MUTE_MASK|SND_MIGRATE_MASK;
>      while (client->command) {
> @@ -985,7 +982,7 @@ SPICE_GNUC_VISIBLE void
> spice_server_playback_stop(SpicePlaybackInstance *sin)
>      sin->st->channel.active = 0;
>      if (!client)
>          return;
> -    PlaybackChannelClient *playback_client = SPICE_CONTAINEROF(client,
> PlaybackChannelClient, base);
> +    PlaybackChannelClient *playback_client =
> PLAYBACK_CHANNEL_CLIENT(client);
>      spice_assert(client->active);
>      reds_enable_mm_time(snd_channel_get_server(client));
>      client->active = FALSE;
> @@ -1015,7 +1012,7 @@ SPICE_GNUC_VISIBLE void
> spice_server_playback_get_buffer(SpicePlaybackInstance *
>      if (!client) {
>          return;
>      }
> -    PlaybackChannelClient *playback_client = SPICE_CONTAINEROF(client,
> PlaybackChannelClient, base);
> +    PlaybackChannelClient *playback_client =
> PLAYBACK_CHANNEL_CLIENT(client);
>      if (!playback_client->free_frames) {
>          return;
>      }
> @@ -1118,10 +1115,12 @@ static void on_new_playback_channel_client(SndChannel
> *channel, SndChannelClient
>      }
>  }
>  
> -static void snd_playback_cleanup(SndChannelClient *client)
> +static void
> +playback_channel_client_finalize(GObject *object)
>  {
> -    PlaybackChannelClient *playback_client = SPICE_CONTAINEROF(client,
> PlaybackChannelClient, base);
>      int i;
> +    PlaybackChannelClient *playback_client =
> PLAYBACK_CHANNEL_CLIENT(object);
> +    SndChannelClient *client = SND_CHANNEL_CLIENT(playback_client);
>  
>      // free frames, unref them
>      for (i = 0; i < NUM_AUDIO_FRAMES; ++i) {
> @@ -1136,41 +1135,42 @@ static void snd_playback_cleanup(SndChannelClient
> *client)
>      }
>  
>      snd_codec_destroy(&playback_client->codec);
> +
> +    G_OBJECT_CLASS(playback_channel_client_parent_class)->finalize(object);
>  }
>  
> -static void snd_set_playback_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)
> +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);
>      SndChannel *channel = SND_CHANNEL(red_channel);
> -    PlaybackChannelClient *playback_client;
>  
> -    snd_disconnect_channel(channel->connection);
> +
> G_OBJECT_CLASS(playback_channel_client_parent_class)->constructed(object);
>  
> -    if (!(playback_client = (PlaybackChannelClient *)__new_channel(channel,
> -
> sizeof(*playback_client),
> -
> SPICE_CHANNEL_PLAYBACK,
> -                                                                   client,
> -                                                                   stream,
> -
> snd_playback_on_message_done,
> -
> snd_playback_cleanup,
> -
> common_caps,
> num_common_caps,
> -                                                                   caps,
> num_caps))) {
> -        return;
> +    if
> (!snd_channel_config_socket(RED_CHANNEL_CLIENT(client->channel_client))) {
> +        g_warning("failed to set sound channel socket parameters");
>      }
>  
> -    snd_playback_alloc_frames(playback_client);
> +    /* 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);
>  
> -    int client_can_celt =
> red_channel_client_test_remote_cap(playback_client->base.channel_client,
> +    SND_CHANNEL_CLIENT(playback_client)->on_message_done =
> snd_playback_on_message_done;
> +
> +    RedChannelClient *rcc = client->channel_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(playback_client->base.channel_client,
> +    int client_can_opus = red_channel_client_test_remote_cap(rcc,
>                                            SPICE_PLAYBACK_CAP_OPUS);
>      int playback_compression =
>          
> reds_config_get_playback_compression(red_channel_get_server(red_channel));
>      int desired_mode = snd_desired_audio_mode(playback_compression,
>      channel->frequency,
>                                                client_can_celt,
>                                                client_can_opus);
> -    playback_client->mode = SPICE_AUDIO_DATA_MODE_RAW;
>      if (desired_mode != SPICE_AUDIO_DATA_MODE_RAW) {
>          if (snd_codec_create(&playback_client->codec, desired_mode,
>          channel->frequency,
>                               SND_CODEC_ENCODE) == SND_CODEC_OK) {
> @@ -1180,7 +1180,7 @@ static void snd_set_playback_peer(RedChannel
> *red_channel, RedClient *client, Re
>          }
>      }
>  
> -    if (!red_client_during_migrate_at_target(client)) {
> +    if (!red_client_during_migrate_at_target(red_client)) {
>          on_new_playback_channel_client(channel,
>          SND_CHANNEL_CLIENT(playback_client));
>      }
>  
> @@ -1190,6 +1190,28 @@ static void snd_set_playback_peer(RedChannel
> *red_channel, RedClient *client, Re
>      snd_send(channel->connection);
>  }
>  
> +static void snd_set_playback_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);
> +    PlaybackChannelClient *playback_client;
> +
> +    snd_disconnect_channel(channel->connection);
> +
> +    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);
> +    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
> +     */
> +}
> +
>  static void snd_record_migrate_channel_client(RedChannelClient *rcc)
>  {
>      SndChannel *channel;
> @@ -1244,7 +1266,7 @@ static void snd_record_start(SndChannel *channel)
>      channel->active = 1;
>      if (!client)
>          return;
> -    RecordChannelClient *record_client = SPICE_CONTAINEROF(client,
> RecordChannelClient, base);
> +    RecordChannelClient *record_client = RECORD_CHANNEL_CLIENT(client);
>      spice_assert(!client->active);
>      record_client->read_pos = record_client->write_pos = 0;   //todo:
>      improve by
>                                                                //stream
>                                                                generation
> @@ -1289,7 +1311,7 @@ SPICE_GNUC_VISIBLE uint32_t
> spice_server_record_get_samples(SpiceRecordInstance
>  
>      if (!client)
>          return 0;
> -    RecordChannelClient *record_client = SPICE_CONTAINEROF(client,
> RecordChannelClient, base);
> +    RecordChannelClient *record_client = RECORD_CHANNEL_CLIENT(client);
>      spice_assert(client->active);
>  
>      if (record_client->write_pos < RECORD_SAMPLES_SIZE / 2) {
> @@ -1363,10 +1385,41 @@ static void on_new_record_channel_client(SndChannel
> *channel, SndChannelClient *
>      }
>  }
>  
> -static void snd_record_cleanup(SndChannelClient *client)
> +static void
> +record_channel_client_finalize(GObject *object)
>  {
> -    RecordChannelClient *record_client = SPICE_CONTAINEROF(client,
> RecordChannelClient, base);
> +    RecordChannelClient *record_client = RECORD_CHANNEL_CLIENT(object);
> +
>      snd_codec_destroy(&record_client->codec);
> +
> +    G_OBJECT_CLASS(record_channel_client_parent_class)->finalize(object);
> +}
> +
> +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);
> +    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);
>  }
>  
>  static void snd_set_record_peer(RedChannel *red_channel, RedClient *client,
>  RedsStream *stream,
> @@ -1379,27 +1432,16 @@ static void snd_set_record_peer(RedChannel
> *red_channel, RedClient *client, Reds
>  
>      snd_disconnect_channel(channel->connection);
>  
> -    if (!(record_client = (RecordChannelClient *)__new_channel(channel,
> -
> sizeof(*record_client),
> -
> SPICE_CHANNEL_RECORD,
> -                                                               client,
> -                                                               stream,
> -
> snd_record_on_message_done,
> -
> snd_record_cleanup,
> -                                                               common_caps,
> num_common_caps,
> -                                                               caps,
> num_caps))) {
> -        return;
> -    }
> -
> -    record_client->mode = SPICE_AUDIO_DATA_MODE_RAW;
> -
> -    on_new_record_channel_client(channel,
> SND_CHANNEL_CLIENT(record_client));
> -    if (channel->active) {
> -        snd_record_start(channel);
> -    }
> -    snd_send(channel->connection);
> +    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);
> +    g_warn_if_fail(record_client != NULL);
>  }
>  
> +
>  static void snd_playback_migrate_channel_client(RedChannelClient *rcc)
>  {
>      SndChannel *channel;
> @@ -1588,9 +1630,10 @@ 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;
> -            int client_can_celt =
> red_channel_client_test_remote_cap(playback->base.channel_client,
> +            RedChannelClient *rcc =
> SND_CHANNEL_CLIENT(playback)->channel_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(playback->base.channel_client,
> +            int client_can_opus = red_channel_client_test_remote_cap(rcc,
>                                      SPICE_PLAYBACK_CAP_OPUS);
>              int desired_mode = snd_desired_audio_mode(on, now->frequency,
>                                                        client_can_opus,
>                                                        client_can_celt);
> @@ -1602,6 +1645,36 @@ void snd_set_playback_compression(int on)
>      }
>  }
>  
> +static void
> +snd_channel_client_class_init(SndChannelClientClass *klass)
> +{
> +    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
> +snd_channel_client_init(SndChannelClient *self)
> +{
> +}
> +
> +static void
> +playback_channel_client_class_init(PlaybackChannelClientClass *klass)
> +{
> +    GObjectClass *object_class = G_OBJECT_CLASS(klass);
> +    object_class->constructed = playback_channel_client_constructed;
> +    object_class->finalize = playback_channel_client_finalize;
> +}
> +
>  static void snd_playback_alloc_frames(PlaybackChannelClient *playback)
>  {
>      int i;
> @@ -1613,3 +1686,24 @@ static void
> snd_playback_alloc_frames(PlaybackChannelClient *playback)
>          snd_playback_free_frame(playback, &playback->frames->items[i]);
>      }
>  }
> +
> +static void
> +playback_channel_client_init(PlaybackChannelClient *playback)
> +{
> +    playback->mode = SPICE_AUDIO_DATA_MODE_RAW;
> +    snd_playback_alloc_frames(playback);
> +}
> +
> +static void
> +record_channel_client_class_init(RecordChannelClientClass *klass)
> +{
> +    GObjectClass *object_class = G_OBJECT_CLASS(klass);
> +    object_class->constructed = record_channel_client_constructed;
> +    object_class->finalize = record_channel_client_finalize;
> +}
> +
> +static void
> +record_channel_client_init(RecordChannelClient *record)
> +{
> +    record->mode = SPICE_AUDIO_DATA_MODE_RAW;
> +}

_______________________________________________
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/spice-devel

Reply via email to