diff options
author | Alexander Larsson <alexl@redhat.com> | 2010-06-15 17:36:04 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2010-06-18 20:27:31 +0200 |
commit | 8418da7ab24eb46547543a886d798759f39891f1 (patch) | |
tree | cb7bdc6c23d10240828929c027f14aecd0b56316 /server | |
parent | cfc86f33409ad1e401ad9107d51aba68123971ec (diff) | |
download | spice-8418da7ab24eb46547543a886d798759f39891f1.tar.gz spice-8418da7ab24eb46547543a886d798759f39891f1.tar.xz spice-8418da7ab24eb46547543a886d798759f39891f1.zip |
Convert snd_worker.c to use SpiceMarshaller and generated marshallers
Diffstat (limited to 'server')
-rw-r--r-- | server/snd_worker.c | 239 |
1 files changed, 94 insertions, 145 deletions
diff --git a/server/snd_worker.c b/server/snd_worker.c index 2deb8a3a..cd9af971 100644 --- a/server/snd_worker.c +++ b/server/snd_worker.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* Copyright (C) 2009 Red Hat, Inc. @@ -27,9 +28,10 @@ #include "reds.h" #include "red_dispatcher.h" #include "snd_worker.h" +#include "marshaller.h" +#include "generated_marshallers.h" #define MAX_SEND_VEC 100 -#define MAX_SEND_BUFS 200 #define RECIVE_BUF_SIZE (16 * 1024 * 2) @@ -61,11 +63,6 @@ enum RecordCommand { #define SND_RECORD_MIGRATE_MASK (1 << SND_RECORD_MIGRATE) #define SND_RECORD_CTRL_MASK (1 << SND_RECORD_CTRL) -typedef struct BufDescriptor { - uint32_t size; - uint8_t *data; -} BufDescriptor; - typedef struct SndChannel SndChannel; typedef void (*send_messages_proc)(void *in_channel); typedef int (*handle_message_proc)(SndChannel *channel, SpiceDataHeader *message); @@ -90,10 +87,9 @@ struct SndChannel { uint32_t ack_messages; struct { - SpiceDataHeader header; - uint32_t n_bufs; - BufDescriptor bufs[MAX_SEND_BUFS]; - + uint64_t serial; + SpiceDataHeader *header; + SpiceMarshaller *marshaller; uint32_t size; uint32_t pos; } send_data; @@ -129,12 +125,7 @@ typedef struct PlaybackChannel { int celt_allowed; uint32_t mode; struct { - union { - SpiceMsgPlaybackMode mode; - SpiceMsgPlaybackStart start; - SpiceMsgMigrate migrate; - uint8_t celt_buf[CELT_COMPRESSED_FRAME_BYTES]; - } u; + uint8_t celt_buf[CELT_COMPRESSED_FRAME_BYTES]; } send_data; } PlaybackChannel; @@ -165,12 +156,6 @@ typedef struct __attribute__ ((__packed__)) RecordMigrateData { uint32_t mode_time; } RecordMigrateData; -typedef struct __attribute__ ((__packed__)) RecordMigrateMessage { - SpiceMsgMigrate migrate; - SpiceDataHeader header; - RecordMigrateData data; -} RecordMigrateMessage; - typedef struct RecordChannel { SndChannel base; uint32_t samples[RECORD_SAMPLES_SIZE]; @@ -182,12 +167,6 @@ typedef struct RecordChannel { CELTDecoder *celt_decoder; CELTMode *celt_mode; uint32_t celt_buf[FRAME_SIZE]; - struct { - union { - SpiceMsgRecordStart start; - RecordMigrateMessage migrate; - } u; - } send_data; } RecordChannel; static SndWorker *workers = NULL; @@ -195,46 +174,6 @@ static uint32_t playback_compression = SPICE_AUDIO_DATA_MODE_CELT_0_5_1; static void snd_receive(void* data); -static inline BufDescriptor *snd_find_buf(SndChannel *channel, int buf_pos, int *buf_offset) -{ - BufDescriptor *buf; - int pos = 0; - - for (buf = channel->send_data.bufs; buf_pos >= pos + buf->size; buf++) { - pos += buf->size; - ASSERT(buf != &channel->send_data.bufs[channel->send_data.n_bufs - 1]); - } - *buf_offset = buf_pos - pos; - return buf; -} - -static inline uint32_t __snd_fill_iovec(BufDescriptor *buf, int skip, struct iovec *vec, - int *vec_index, long phys_delta) -{ - uint32_t size = 0; - vec[*vec_index].iov_base = buf->data + skip; - vec[*vec_index].iov_len = size = buf->size - skip; - (*vec_index)++; - return size; -} - -static inline void snd_fill_iovec(SndChannel *channel, struct iovec *vec, int *vec_size) -{ - int vec_index = 0; - uint32_t pos = channel->send_data.pos; - ASSERT(channel->send_data.size != pos && channel->send_data.size > pos); - - do { - BufDescriptor *buf; - int buf_offset; - - buf = snd_find_buf(channel, pos, &buf_offset); - ASSERT(buf); - pos += __snd_fill_iovec(buf, buf_offset, vec, &vec_index, 0); - } while (vec_index < MAX_SEND_VEC && pos != channel->send_data.size); - *vec_size = vec_index; -} - static void snd_disconnect_channel(SndChannel *channel) { SndWorker *worker; @@ -248,6 +187,7 @@ static void snd_disconnect_channel(SndChannel *channel) core->watch_remove(channel->peer->watch); channel->peer->watch = NULL; channel->peer->cb_free(channel->peer); + spice_marshaller_destroy(channel->send_data.marshaller); free(channel); } @@ -299,7 +239,8 @@ static int snd_send_data(SndChannel *channel) break; } - snd_fill_iovec(channel, vec, &vec_size); + vec_size = spice_marshaller_fill_iovec(channel->send_data.marshaller, + vec, MAX_SEND_VEC, channel->send_data.pos); if ((n = channel->peer->cb_writev(channel->peer->ctx, vec, vec_size)) == -1) { switch (errno) { case EAGAIN: @@ -506,76 +447,75 @@ static void snd_event(int fd, int event, void *data) } } -static inline void __snd_add_buf(SndChannel *channel, void *data, uint32_t size) -{ - int pos = channel->send_data.n_bufs++; - ASSERT(pos < MAX_SEND_BUFS); - channel->send_data.bufs[pos].size = size; - channel->send_data.bufs[pos].data = data; -} - -static void snd_add_buf(SndChannel *channel, void *data, uint32_t size) -{ - __snd_add_buf(channel, data, size); - channel->send_data.header.size += size; -} - static inline int snd_reset_send_data(SndChannel *channel, uint16_t verb) { if (!channel) { return FALSE; } + spice_marshaller_reset(channel->send_data.marshaller); + channel->send_data.header = (SpiceDataHeader *) + spice_marshaller_reserve_space(channel->send_data.marshaller, sizeof(SpiceDataHeader)); + spice_marshaller_set_base(channel->send_data.marshaller, sizeof(SpiceDataHeader)); channel->send_data.pos = 0; - channel->send_data.n_bufs = 0; - channel->send_data.header.sub_list = 0; - channel->send_data.header.size = 0; - channel->send_data.header.type = verb; - ++channel->send_data.header.serial; - __snd_add_buf(channel, &channel->send_data.header, sizeof(SpiceDataHeader)); + channel->send_data.header->sub_list = 0; + channel->send_data.header->size = 0; + channel->send_data.header->type = verb; + channel->send_data.header->serial = ++channel->send_data.serial; return TRUE; } +static int snd_begin_send_message(SndChannel *channel) +{ + spice_marshaller_flush(channel->send_data.marshaller); + channel->send_data.size = spice_marshaller_get_total_size(channel->send_data.marshaller); + channel->send_data.header->size = channel->send_data.size - sizeof(SpiceDataHeader); + channel->send_data.header = NULL; /* avoid writing to this until we have a new message */ + return snd_send_data(channel); +} + + static int snd_playback_send_migrate(PlaybackChannel *channel) { + SpiceMsgMigrate migrate; + if (!snd_reset_send_data((SndChannel *)channel, SPICE_MSG_MIGRATE)) { return FALSE; } - channel->send_data.u.migrate.flags = 0; - snd_add_buf((SndChannel *)channel, &channel->send_data.u.migrate, - sizeof(channel->send_data.u.migrate)); - channel->base.send_data.size = channel->base.send_data.header.size + sizeof(SpiceDataHeader); - return snd_send_data((SndChannel *)channel); + migrate.flags = 0; + spice_marshall_msg_migrate(channel->base.send_data.marshaller, &migrate); + + return snd_begin_send_message((SndChannel *)channel); } static int snd_playback_send_start(PlaybackChannel *playback_channel) { SndChannel *channel = (SndChannel *)playback_channel; - SpiceMsgPlaybackStart *start; + SpiceMsgPlaybackStart start; + if (!snd_reset_send_data(channel, SPICE_MSG_PLAYBACK_START)) { return FALSE; } - start = &playback_channel->send_data.u.start; - start->channels = SPICE_INTERFACE_PLAYBACK_CHAN; - start->frequency = SPICE_INTERFACE_PLAYBACK_FREQ; + start.channels = SPICE_INTERFACE_PLAYBACK_CHAN; + start.frequency = SPICE_INTERFACE_PLAYBACK_FREQ; ASSERT(SPICE_INTERFACE_PLAYBACK_FMT == SPICE_INTERFACE_AUDIO_FMT_S16); - start->format = SPICE_AUDIO_FMT_S16; - start->time = reds_get_mm_time(); - snd_add_buf(channel, start, sizeof(*start)); + start.format = SPICE_AUDIO_FMT_S16; + start.time = reds_get_mm_time(); + spice_marshall_msg_playback_start(channel->send_data.marshaller, &start); - channel->send_data.size = sizeof(SpiceDataHeader) + sizeof(*start); - return snd_send_data(channel); + return snd_begin_send_message(channel); } static int snd_playback_send_stop(PlaybackChannel *playback_channel) { SndChannel *channel = (SndChannel *)playback_channel; + if (!snd_reset_send_data(channel, SPICE_MSG_PLAYBACK_STOP)) { return FALSE; } - channel->send_data.size = sizeof(SpiceDataHeader); - return snd_send_data(channel); + + return snd_begin_send_message(channel); } static int snd_playback_send_ctl(PlaybackChannel *playback_channel) @@ -592,30 +532,30 @@ static int snd_playback_send_ctl(PlaybackChannel *playback_channel) static int snd_record_send_start(RecordChannel *record_channel) { SndChannel *channel = (SndChannel *)record_channel; - SpiceMsgRecordStart *start; + SpiceMsgRecordStart start; + if (!snd_reset_send_data(channel, SPICE_MSG_RECORD_START)) { return FALSE; } - start = &record_channel->send_data.u.start; - start->channels = SPICE_INTERFACE_RECORD_CHAN; - start->frequency = SPICE_INTERFACE_RECORD_FREQ; + start.channels = SPICE_INTERFACE_RECORD_CHAN; + start.frequency = SPICE_INTERFACE_RECORD_FREQ; ASSERT(SPICE_INTERFACE_RECORD_FMT == SPICE_INTERFACE_AUDIO_FMT_S16); - start->format = SPICE_AUDIO_FMT_S16; - snd_add_buf(channel, start, sizeof(*start)); + start.format = SPICE_AUDIO_FMT_S16; + spice_marshall_msg_record_start(channel->send_data.marshaller, &start); - channel->send_data.size = sizeof(SpiceDataHeader) + sizeof(*start); - return snd_send_data(channel); + return snd_begin_send_message(channel); } static int snd_record_send_stop(RecordChannel *record_channel) { SndChannel *channel = (SndChannel *)record_channel; + if (!snd_reset_send_data(channel, SPICE_MSG_RECORD_STOP)) { return FALSE; } - channel->send_data.size = sizeof(SpiceDataHeader); - return snd_send_data(channel); + + return snd_begin_send_message(channel); } static int snd_record_send_ctl(RecordChannel *record_channel) @@ -632,29 +572,35 @@ static int snd_record_send_ctl(RecordChannel *record_channel) static int snd_record_send_migrate(RecordChannel *record_channel) { SndChannel *channel = (SndChannel *)record_channel; - RecordMigrateMessage* migrate; + SpiceMsgMigrate migrate; + SpiceDataHeader *header; + RecordMigrateData *data; if (!snd_reset_send_data(channel, SPICE_MSG_MIGRATE)) { return FALSE; } - migrate = &record_channel->send_data.u.migrate; - migrate->migrate.flags = SPICE_MIGRATE_NEED_DATA_TRANSFER; - migrate->header.type = SPICE_MSG_MIGRATE_DATA; - migrate->header.size = sizeof(RecordMigrateData); - migrate->header.serial = ++channel->send_data.header.serial; - migrate->header.sub_list = 0; + migrate.flags = SPICE_MIGRATE_NEED_DATA_TRANSFER; + spice_marshall_msg_migrate(channel->send_data.marshaller, &migrate); + + header = (SpiceDataHeader *)spice_marshaller_reserve_space(channel->send_data.marshaller, + sizeof(SpiceDataHeader)); + header->type = SPICE_MSG_MIGRATE_DATA; + header->size = sizeof(RecordMigrateData); + header->serial = ++channel->send_data.serial; + header->sub_list = 0; - migrate->data.version = RECORD_MIG_VERSION; - migrate->data.serial = channel->send_data.header.serial; - migrate->data.start_time = record_channel->start_time; - migrate->data.mode = record_channel->mode; - migrate->data.mode_time = record_channel->mode_time; + data = (RecordMigrateData *)spice_marshaller_reserve_space(channel->send_data.marshaller, + sizeof(RecordMigrateData)); + data->version = RECORD_MIG_VERSION; + data->serial = channel->send_data.serial; + data->start_time = record_channel->start_time; + data->mode = record_channel->mode; + data->mode_time = record_channel->mode_time; + + channel->send_data.size = spice_marshaller_get_total_size(channel->send_data.marshaller); + channel->send_data.header->size = channel->send_data.size - sizeof(SpiceDataHeader) - sizeof(SpiceDataHeader) - sizeof(*data); - snd_add_buf(channel, migrate, sizeof(*migrate)); - channel->send_data.size = channel->send_data.header.size + sizeof(SpiceDataHeader); - channel->send_data.header.size -= sizeof(migrate->header); - channel->send_data.header.size -= sizeof(migrate->data); return snd_send_data(channel); } @@ -662,46 +608,48 @@ static int snd_playback_send_write(PlaybackChannel *playback_channel) { SndChannel *channel = (SndChannel *)playback_channel; AudioFrame *frame; + SpiceMsgPlaybackPacket msg; if (!snd_reset_send_data(channel, SPICE_MSG_PLAYBACK_DATA)) { return FALSE; } frame = playback_channel->in_progress; - snd_add_buf(channel, &frame->time, sizeof(frame->time)); + msg.time = frame->time; + + spice_marshall_msg_playback_data(channel->send_data.marshaller, &msg); + if (playback_channel->mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1) { int n = celt051_encode(playback_channel->celt_encoder, (celt_int16_t *)frame->samples, NULL, - playback_channel->send_data.u.celt_buf, CELT_COMPRESSED_FRAME_BYTES); + playback_channel->send_data.celt_buf, CELT_COMPRESSED_FRAME_BYTES); if (n < 0) { red_printf("celt encode failed"); snd_disconnect_channel(channel); return FALSE; } - snd_add_buf(channel, playback_channel->send_data.u.celt_buf, n); + spice_marshaller_add_ref(channel->send_data.marshaller, + playback_channel->send_data.celt_buf, n); } else { - snd_add_buf(channel, frame->samples, sizeof(frame->samples)); + spice_marshaller_add_ref(channel->send_data.marshaller, + (uint8_t *)frame->samples, sizeof(frame->samples)); } - channel->send_data.size = channel->send_data.header.size + sizeof(SpiceDataHeader); - - return snd_send_data(channel); + return snd_begin_send_message(channel); } static int playback_send_mode(PlaybackChannel *playback_channel) { SndChannel *channel = (SndChannel *)playback_channel; - SpiceMsgPlaybackMode *mode; + SpiceMsgPlaybackMode mode; if (!snd_reset_send_data(channel, SPICE_MSG_PLAYBACK_MODE)) { return FALSE; } - mode = &playback_channel->send_data.u.mode; - mode->time = reds_get_mm_time(); - mode->mode = playback_channel->mode; - snd_add_buf(channel, mode, sizeof(*mode)); + mode.time = reds_get_mm_time(); + mode.mode = playback_channel->mode; + spice_marshall_msg_playback_mode(channel->send_data.marshaller, &mode); - channel->send_data.size = channel->send_data.header.size + sizeof(SpiceDataHeader); - return snd_send_data(channel); + return snd_begin_send_message(channel); } static void snd_playback_send(void* data) @@ -815,6 +763,7 @@ static SndChannel *__new_channel(SndWorker *worker, int size, RedsStreamContext channel->recive_data.message = (SpiceDataHeader *)channel->recive_data.buf; channel->recive_data.now = channel->recive_data.buf; channel->recive_data.end = channel->recive_data.buf + sizeof(channel->recive_data.buf); + channel->send_data.marshaller = spice_marshaller_new(); peer->watch = core->watch_add(peer->socket, SPICE_WATCH_EVENT_READ, snd_event, channel); |