[Spice-devel] [PATCH 26/35] SoundInterfaces: redesign

Gerd Hoffmann kraxel at redhat.com
Wed May 12 04:32:20 PDT 2010


---
 server/reds.c         |   30 +++++-----
 server/snd_worker.c   |  160 ++++++++++++++++++++++++------------------------
 server/snd_worker.h   |    8 +-
 server/vd_interface.h |   84 +++++++++++++-------------
 4 files changed, 141 insertions(+), 141 deletions(-)

diff --git a/server/reds.c b/server/reds.c
index 24b1507..e8fa763 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -4126,23 +4126,23 @@ __visible__ int spice_server_add_interface(SpiceServer *s,
                                   reds->monitor_mode.y_res);
         }
 
-    } else if (strcmp(interface->type, VD_INTERFACE_PLAYBACK) == 0) {
-        red_printf("VD_INTERFACE_PLAYBACK");
-        if (interface->major_version != VD_INTERFACE_PLAYBACK_MAJOR ||
-            interface->minor_version < VD_INTERFACE_PLAYBACK_MINOR) {
+    } else if (strcmp(interface->type, SPICE_INTERFACE_PLAYBACK) == 0) {
+        red_printf("SPICE_INTERFACE_PLAYBACK");
+        if (interface->major_version != SPICE_INTERFACE_PLAYBACK_MAJOR ||
+            interface->minor_version < SPICE_INTERFACE_PLAYBACK_MINOR) {
             red_printf("unsuported playback interface");
             return -1;
         }
-        snd_attach_playback((PlaybackInterface *)interface);
+        snd_attach_playback(SPICE_CONTAINEROF(sin, SpicePlaybackInstance, base));
 
-    } else if (strcmp(interface->type, VD_INTERFACE_RECORD) == 0) {
+    } else if (strcmp(interface->type, SPICE_INTERFACE_RECORD) == 0) {
         red_printf("VD_INTERFACE_RECORD");
-        if (interface->major_version != VD_INTERFACE_RECORD_MAJOR ||
-            interface->minor_version < VD_INTERFACE_RECORD_MINOR) {
+        if (interface->major_version != SPICE_INTERFACE_RECORD_MAJOR ||
+            interface->minor_version < SPICE_INTERFACE_RECORD_MINOR) {
             red_printf("unsuported record interface");
             return -1;
         }
-        snd_attach_record((RecordInterface *)interface);
+        snd_attach_record(SPICE_CONTAINEROF(sin, SpiceRecordInstance, base));
 
     } else if (strcmp(interface->type, VD_INTERFACE_VDI_PORT) == 0) {
         red_printf("VD_INTERFACE_VDI_PORT");
@@ -4190,13 +4190,13 @@ __visible__ int spice_server_remove_interface(SpiceBaseInstance *sin)
             reds_update_mouse_mode();
         }
 
-    } else if (strcmp(interface->type, VD_INTERFACE_PLAYBACK) == 0) {
-        red_printf("remove VD_INTERFACE_PLAYBACK");
-        snd_detach_playback((PlaybackInterface *)interface);
+    } else if (strcmp(interface->type, SPICE_INTERFACE_PLAYBACK) == 0) {
+        red_printf("remove SPICE_INTERFACE_PLAYBACK");
+        snd_detach_playback(SPICE_CONTAINEROF(sin, SpicePlaybackInstance, base));
 
-    } else if (strcmp(interface->type, VD_INTERFACE_RECORD) == 0) {
-        red_printf("remove VD_INTERFACE_RECORD");
-        snd_detach_record((RecordInterface *)interface);
+    } else if (strcmp(interface->type, SPICE_INTERFACE_RECORD) == 0) {
+        red_printf("remove SPICE_INTERFACE_RECORD");
+        snd_detach_record(SPICE_CONTAINEROF(sin, SpiceRecordInstance, base));
 
     } else if (strcmp(interface->type, VD_INTERFACE_VDI_PORT) == 0) {
         red_printf("remove VD_INTERFACE_VDI_PORT");
diff --git a/server/snd_worker.c b/server/snd_worker.c
index afffb00..6a08e92 100644
--- a/server/snd_worker.c
+++ b/server/snd_worker.c
@@ -37,7 +37,7 @@
 #define PLAYBACK_BUF_SIZE (FRAME_SIZE * 4)
 
 #define CELT_BIT_RATE (64 * 1024)
-#define CELT_COMPRESSED_FRAME_BYTES (FRAME_SIZE * CELT_BIT_RATE / VD_INTERFACE_PLAYBACK_FREQ / 8)
+#define CELT_COMPRESSED_FRAME_BYTES (FRAME_SIZE * CELT_BIT_RATE / SPICE_INTERFACE_PLAYBACK_FREQ / 8)
 
 #define RECORD_SAMPLES_SIZE (RECIVE_BUF_SIZE >> 2)
 
@@ -121,7 +121,6 @@ struct AudioFrame {
 typedef struct PlaybackChannel {
     SndChannel base;
     AudioFrame frames[3];
-    PlaybackPlug plug;
     VDObjectRef plug_ref;
     AudioFrame *free_frames;
     AudioFrame *in_progress;
@@ -147,6 +146,14 @@ struct SndWorker {
     SndWorker *next;
 };
 
+struct SpicePlaybackState {
+    struct SndWorker worker;
+};
+
+struct SpiceRecordState {
+    struct SndWorker worker;
+};
+
 #define RECORD_MIG_VERSION 1
 
 typedef struct __attribute__ ((__packed__)) RecordMigrateData {
@@ -165,7 +172,6 @@ typedef struct __attribute__ ((__packed__)) RecordMigrateMessage {
 
 typedef struct RecordChannel {
     SndChannel base;
-    RecordPlug plug;
     VDObjectRef plug_ref;
     uint32_t samples[RECORD_SAMPLES_SIZE];
     uint32_t write_pos;
@@ -551,9 +557,9 @@ static int snd_playback_send_start(PlaybackChannel *playback_channel)
     }
 
     start = &playback_channel->send_data.u.start;
-    start->channels = VD_INTERFACE_PLAYBACK_CHAN;
-    start->frequency = VD_INTERFACE_PLAYBACK_FREQ;
-    ASSERT(VD_INTERFACE_PLAYBACK_FMT == VD_INTERFACE_AUDIO_FMT_S16);
+    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));
@@ -592,9 +598,9 @@ static int snd_record_send_start(RecordChannel *record_channel)
     }
 
     start = &record_channel->send_data.u.start;
-    start->channels = VD_INTERFACE_RECORD_CHAN;
-    start->frequency = VD_INTERFACE_RECORD_FREQ;
-    ASSERT(VD_INTERFACE_RECORD_FMT == VD_INTERFACE_AUDIO_FMT_S16);
+    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));
 
@@ -846,10 +852,13 @@ static void snd_set_command(SndChannel *channel, uint32_t command)
     channel->command |= command;
 }
 
-static void snd_playback_start(PlaybackPlug *plug)
+__visible__ void spice_server_playback_start(SpicePlaybackInstance *sin)
 {
-    PlaybackChannel *playback_channel = SPICE_CONTAINEROF(plug, PlaybackChannel, plug);
+    SndChannel *channel = sin->st->worker.connection;
+    PlaybackChannel *playback_channel = SPICE_CONTAINEROF(channel, PlaybackChannel, base);
 
+    if (!channel)
+        return;
     ASSERT(!playback_channel->base.active);
     reds_desable_mm_timer();
     playback_channel->base.active = TRUE;
@@ -861,10 +870,13 @@ static void snd_playback_start(PlaybackPlug *plug)
     }
 }
 
-static void snd_playback_stop(PlaybackPlug *plug)
+__visible__ void spice_server_playback_stop(SpicePlaybackInstance *sin)
 {
-    PlaybackChannel *playback_channel = SPICE_CONTAINEROF(plug, PlaybackChannel, plug);
+    SndChannel *channel = sin->st->worker.connection;
+    PlaybackChannel *playback_channel = SPICE_CONTAINEROF(channel, PlaybackChannel, base);
 
+    if (!channel)
+        return;
     ASSERT(playback_channel->base.active);
     reds_enable_mm_timer();
     playback_channel->base.active = FALSE;
@@ -884,27 +896,32 @@ static void snd_playback_stop(PlaybackPlug *plug)
     }
 }
 
-static void snd_playback_get_frame(PlaybackPlug *plug, uint32_t **frame, uint32_t *num_samples)
+__visible__ void spice_server_playback_get_buffer(SpicePlaybackInstance *sin,
+                                                  uint32_t **frame, uint32_t *num_samples)
 {
-    PlaybackChannel *playback_channel = SPICE_CONTAINEROF(plug, PlaybackChannel, plug);
+    SndChannel *channel = sin->st->worker.connection;
+    PlaybackChannel *playback_channel = SPICE_CONTAINEROF(channel, PlaybackChannel, base);
 
-    ASSERT(playback_channel->base.active);
-    if (!playback_channel->free_frames) {
+    if (!channel || !playback_channel->free_frames) {
         *frame = NULL;
         *num_samples = 0;
         return;
     }
+    ASSERT(playback_channel->base.active);
 
     *frame = playback_channel->free_frames->samples;
     playback_channel->free_frames = playback_channel->free_frames->next;
     *num_samples = FRAME_SIZE;
 }
 
-static void snd_playback_put_frame(PlaybackPlug *plug, uint32_t *samples)
+__visible__ void spice_server_playback_put_samples(SpicePlaybackInstance *sin, uint32_t *samples)
 {
-    PlaybackChannel *playback_channel = SPICE_CONTAINEROF(plug, PlaybackChannel, plug);
+    SndChannel *channel = sin->st->worker.connection;
+    PlaybackChannel *playback_channel = SPICE_CONTAINEROF(channel, PlaybackChannel, base);
     AudioFrame *frame;
 
+    if (!channel)
+        return;
     ASSERT(playback_channel->base.active);
 
     if (playback_channel->pending_frame) {
@@ -920,12 +937,11 @@ static void snd_playback_put_frame(PlaybackPlug *plug, uint32_t *samples)
 
 static void on_new_playback_channel(SndWorker *worker)
 {
-    PlaybackChannel *playback_channel = (PlaybackChannel *)worker->connection;
-    PlaybackInterface *interface = (PlaybackInterface *)worker->interface;
+    PlaybackChannel *playback_channel =
+        SPICE_CONTAINEROF(worker->connection, PlaybackChannel, base);
+
     ASSERT(playback_channel);
 
-    playback_channel->plug_ref = interface->plug(interface, &playback_channel->plug,
-                                                 &playback_channel->base.active);
     snd_set_command((SndChannel *)playback_channel, SND_PLAYBACK_MODE_MASK);
     if (!playback_channel->base.migrate && playback_channel->base.active) {
         snd_set_command((SndChannel *)playback_channel, SND_PLAYBACK_CTRL_MASK);
@@ -937,13 +953,11 @@ static void on_new_playback_channel(SndWorker *worker)
 
 static void snd_playback_cleanup(SndChannel *channel)
 {
-    PlaybackChannel *playback_channel = (PlaybackChannel *)channel;
-    PlaybackInterface *interface = (PlaybackInterface *)channel->worker->interface;
+    PlaybackChannel *playback_channel = SPICE_CONTAINEROF(channel, PlaybackChannel, base);
 
     if (playback_channel->base.active) {
         reds_enable_mm_timer();
     }
-    interface->unplug(interface, playback_channel->plug_ref);
 
     celt051_encoder_destroy(playback_channel->celt_encoder);
     celt051_mode_destroy(playback_channel->celt_mode);
@@ -961,7 +975,8 @@ static void snd_set_playback_peer(Channel *channel, RedsStreamContext *peer, int
 
     snd_disconnect_channel(worker->connection);
 
-    if (!(celt_mode = celt051_mode_create(VD_INTERFACE_PLAYBACK_FREQ, VD_INTERFACE_PLAYBACK_CHAN,
+    if (!(celt_mode = celt051_mode_create(SPICE_INTERFACE_PLAYBACK_FREQ,
+                                          SPICE_INTERFACE_PLAYBACK_CHAN,
                                           FRAME_SIZE, &celt_error))) {
         red_printf("create celt mode failed %d", celt_error);
         return;
@@ -987,12 +1002,6 @@ static void snd_set_playback_peer(Channel *channel, RedsStreamContext *peer, int
     snd_playback_free_frame(playback_channel, &playback_channel->frames[1]);
     snd_playback_free_frame(playback_channel, &playback_channel->frames[2]);
 
-    playback_channel->plug.major_version = VD_INTERFACE_PLAYBACK_MAJOR;
-    playback_channel->plug.minor_version = VD_INTERFACE_PLAYBACK_MINOR;
-    playback_channel->plug.start = snd_playback_start;
-    playback_channel->plug.stop = snd_playback_stop;
-    playback_channel->plug.get_frame = snd_playback_get_frame;
-    playback_channel->plug.put_frame = snd_playback_put_frame;
     playback_channel->celt_mode = celt_mode;
     playback_channel->celt_encoder = celt_encoder;
     playback_channel->celt_allowed = num_caps > 0 && (caps[0] & (1 << SPICE_PLAYBACK_CAP_CELT_0_5_1));
@@ -1019,10 +1028,13 @@ static void snd_record_migrate(Channel *channel)
     }
 }
 
-static void snd_record_start(RecordPlug *plug)
+__visible__ void spice_server_record_start(SpiceRecordInstance *sin)
 {
-    RecordChannel *record_channel = SPICE_CONTAINEROF(plug, RecordChannel, plug);
+    SndChannel *channel = sin->st->worker.connection;
+    RecordChannel *record_channel = SPICE_CONTAINEROF(channel, RecordChannel, base);
 
+    if (!channel)
+        return;
     ASSERT(!record_channel->base.active);
     record_channel->base.active = TRUE;
     record_channel->read_pos = record_channel->write_pos = 0;   //todo: improve by
@@ -1035,10 +1047,13 @@ static void snd_record_start(RecordPlug *plug)
     }
 }
 
-static void snd_record_stop(RecordPlug *plug)
+__visible__ void spice_server_record_stop(SpiceRecordInstance *sin)
 {
-    RecordChannel *record_channel = SPICE_CONTAINEROF(plug, RecordChannel, plug);
+    SndChannel *channel = sin->st->worker.connection;
+    RecordChannel *record_channel = SPICE_CONTAINEROF(channel, RecordChannel, base);
 
+    if (!channel)
+        return;
     ASSERT(record_channel->base.active);
     record_channel->base.active = FALSE;
     if (record_channel->base.client_active) {
@@ -1049,28 +1064,32 @@ static void snd_record_stop(RecordPlug *plug)
     }
 }
 
-static uint32_t snd_record_read(RecordPlug *plug, uint32_t num_samples, uint32_t *samples)
+__visible__ uint32_t spice_server_record_get_samples(SpiceRecordInstance *sin,
+                                                     uint32_t *samples, uint32_t bufsize)
 {
-    RecordChannel *record_channel = SPICE_CONTAINEROF(plug, RecordChannel, plug);
+    SndChannel *channel = sin->st->worker.connection;
+    RecordChannel *record_channel = SPICE_CONTAINEROF(channel, RecordChannel, base);
     uint32_t read_pos;
     uint32_t now;
     uint32_t len;
 
+    if (!channel)
+        return 0;
     ASSERT(record_channel->base.active);
 
     if (record_channel->write_pos < RECORD_SAMPLES_SIZE / 2) {
         return 0;
     }
 
-    len = MIN(record_channel->write_pos - record_channel->read_pos, num_samples);
+    len = MIN(record_channel->write_pos - record_channel->read_pos, bufsize);
 
-    if (len < num_samples) {
+    if (len < bufsize) {
         SndWorker *worker = record_channel->base.worker;
         snd_receive(record_channel);
         if (!worker->connection) {
             return 0;
         }
-        len = MIN(record_channel->write_pos - record_channel->read_pos, num_samples);
+        len = MIN(record_channel->write_pos - record_channel->read_pos, bufsize);
     }
 
     read_pos = record_channel->read_pos % RECORD_SAMPLES_SIZE;
@@ -1086,11 +1105,8 @@ static uint32_t snd_record_read(RecordPlug *plug, uint32_t num_samples, uint32_t
 static void on_new_record_channel(SndWorker *worker)
 {
     RecordChannel *record_channel = (RecordChannel *)worker->connection;
-    RecordInterface *interface = (RecordInterface *)worker->interface;
     ASSERT(record_channel);
 
-    record_channel->plug_ref = interface->plug(interface, &record_channel->plug,
-                                               &record_channel->base.active);
     if (!record_channel->base.migrate) {
         if (record_channel->base.active) {
             snd_set_command((SndChannel *)record_channel, SND_RECORD_CTRL_MASK);
@@ -1101,8 +1117,6 @@ static void on_new_record_channel(SndWorker *worker)
 static void snd_record_cleanup(SndChannel *channel)
 {
     RecordChannel *record_channel = (RecordChannel *)channel;
-    RecordInterface *interface = (RecordInterface *)channel->worker->interface;
-    interface->unplug(interface, record_channel->plug_ref);
 
     celt051_decoder_destroy(record_channel->celt_decoder);
     celt051_mode_destroy(record_channel->celt_mode);
@@ -1120,7 +1134,8 @@ static void snd_set_record_peer(Channel *channel, RedsStreamContext *peer, int m
 
     snd_disconnect_channel(worker->connection);
 
-    if (!(celt_mode = celt051_mode_create(VD_INTERFACE_RECORD_FREQ, VD_INTERFACE_RECORD_CHAN,
+    if (!(celt_mode = celt051_mode_create(SPICE_INTERFACE_RECORD_FREQ,
+                                          SPICE_INTERFACE_RECORD_CHAN,
                                           FRAME_SIZE, &celt_error))) {
         red_printf("create celt mode failed %d", celt_error);
         return;
@@ -1144,11 +1159,6 @@ static void snd_set_record_peer(Channel *channel, RedsStreamContext *peer, int m
 
     worker->connection = &record_channel->base;
 
-    record_channel->plug.major_version = VD_INTERFACE_RECORD_MAJOR;
-    record_channel->plug.minor_version = VD_INTERFACE_RECORD_MINOR;
-    record_channel->plug.start = snd_record_start;
-    record_channel->plug.stop = snd_record_stop;
-    record_channel->plug.read = snd_record_read;
     record_channel->celt_mode = celt_mode;
     record_channel->celt_decoder = celt_decoder;
 
@@ -1192,29 +1202,19 @@ static void remove_worker(SndWorker *worker)
     red_printf("not found");
 }
 
-static SndWorker *find_worker(SpiceBaseInterface *interface)
-{
-    SndWorker *worker = workers;
-    while (worker) {
-        if (worker->interface == interface) {
-            break;
-        }
-        worker = worker->next;
-    }
-    return worker;
-}
-
-void snd_attach_playback(PlaybackInterface *interface)
+void snd_attach_playback(SpicePlaybackInstance *sin)
 {
     SndWorker *playback_worker;
-    playback_worker = spice_new0(SndWorker, 1);
+
+    sin->st = spice_new0(SpicePlaybackState, 1);
+    playback_worker = &sin->st->worker;
+
     playback_worker->base.type = SPICE_CHANNEL_PLAYBACK;
     playback_worker->base.link = snd_set_playback_peer;
     playback_worker->base.shutdown = snd_shutdown;
     playback_worker->base.migrate = snd_playback_migrate;
     playback_worker->base.data = NULL;
 
-    playback_worker->interface = &interface->base;
     playback_worker->base.num_caps = 1;
     playback_worker->base.caps = spice_new(uint32_t, 1);
     playback_worker->base.caps[0] = (1 << SPICE_PLAYBACK_CAP_CELT_0_5_1);
@@ -1223,18 +1223,19 @@ void snd_attach_playback(PlaybackInterface *interface)
     reds_register_channel(&playback_worker->base);
 }
 
-void snd_attach_record(RecordInterface *interface)
+void snd_attach_record(SpiceRecordInstance *sin)
 {
     SndWorker *record_worker;
-    record_worker = spice_new0(SndWorker, 1);
+
+    sin->st = spice_new0(SpiceRecordState, 1);
+    record_worker = &sin->st->worker;
+
     record_worker->base.type = SPICE_CHANNEL_RECORD;
     record_worker->base.link = snd_set_record_peer;
     record_worker->base.shutdown = snd_shutdown;
     record_worker->base.migrate = snd_record_migrate;
     record_worker->base.data = NULL;
 
-    record_worker->interface = &interface->base;
-
     record_worker->base.num_caps = 1;
     record_worker->base.caps = spice_new(uint32_t, 1);
     record_worker->base.caps[0] = (1 << SPICE_RECORD_CAP_CELT_0_5_1);
@@ -1242,10 +1243,8 @@ void snd_attach_record(RecordInterface *interface)
     reds_register_channel(&record_worker->base);
 }
 
-static void snd_detach_common(SpiceBaseInterface *interface)
+static void snd_detach_common(SndWorker *worker)
 {
-    SndWorker *worker = find_worker(interface);
-
     if (!worker) {
         return;
     }
@@ -1255,17 +1254,18 @@ static void snd_detach_common(SpiceBaseInterface *interface)
 
     free(worker->base.common_caps);
     free(worker->base.caps);
-    free(worker);
 }
 
-void snd_detach_playback(PlaybackInterface *interface)
+void snd_detach_playback(SpicePlaybackInstance *sin)
 {
-    snd_detach_common(&interface->base);
+    snd_detach_common(&sin->st->worker);
+    free(sin->st);
 }
 
-void snd_detach_record(RecordInterface *interface)
+void snd_detach_record(SpiceRecordInstance *sin)
 {
-    snd_detach_common(&interface->base);
+    snd_detach_common(&sin->st->worker);
+    free(sin->st);
 }
 
 void snd_set_playback_compression(int on)
diff --git a/server/snd_worker.h b/server/snd_worker.h
index d7f9674..291f321 100644
--- a/server/snd_worker.h
+++ b/server/snd_worker.h
@@ -20,11 +20,11 @@
 
 #include "vd_interface.h"
 
-void snd_attach_playback(PlaybackInterface *interface);
-void snd_detach_playback(PlaybackInterface *interface);
+void snd_attach_playback(SpicePlaybackInstance *sin);
+void snd_detach_playback(SpicePlaybackInstance *sin);
 
-void snd_attach_record(RecordInterface *interface);
-void snd_detach_record(RecordInterface *interface);
+void snd_attach_record(SpiceRecordInstance *sin);
+void snd_detach_record(SpiceRecordInstance *sin);
 
 void snd_set_playback_compression(int on);
 int snd_get_playback_compression();
diff --git a/server/vd_interface.h b/server/vd_interface.h
index 6b1315a..d3ce999 100644
--- a/server/vd_interface.h
+++ b/server/vd_interface.h
@@ -311,62 +311,62 @@ typedef struct VDICmdArg {
 typedef void (*VDICmdHandler)(const VDICmdArg* args);
 typedef void (*VDIInfoCmdHandler)(void);
 
-#define VD_INTERFACE_PLAYBACK "playback"
-#define VD_INTERFACE_PLAYBACK_MAJOR 1
-#define VD_INTERFACE_PLAYBACK_MINOR 1
-typedef struct PlaybackInterface PlaybackInterface;
+#define SPICE_INTERFACE_PLAYBACK "playback"
+#define SPICE_INTERFACE_PLAYBACK_MAJOR 1
+#define SPICE_INTERFACE_PLAYBACK_MINOR 1
+typedef struct SpicePlaybackInterface SpicePlaybackInterface;
+typedef struct SpicePlaybackInstance SpicePlaybackInstance;
+typedef struct SpicePlaybackState SpicePlaybackState;
 
 enum {
-    VD_INTERFACE_AUDIO_FMT_S16 = 1,
+    SPICE_INTERFACE_AUDIO_FMT_S16 = 1,
 };
 
-#define VD_INTERFACE_PLAYBACK_FREQ 44100
-#define VD_INTERFACE_PLAYBACK_CHAN 2
-#define VD_INTERFACE_PLAYBACK_FMT VD_INTERFACE_AUDIO_FMT_S16
+#define SPICE_INTERFACE_PLAYBACK_FREQ  44100
+#define SPICE_INTERFACE_PLAYBACK_CHAN  2
+#define SPICE_INTERFACE_PLAYBACK_FMT   SPICE_INTERFACE_AUDIO_FMT_S16
 
-typedef struct PlaybackPlug PlaybackPlug;
-struct PlaybackPlug {
-    uint32_t minor_version;
-    uint32_t major_version;
-    void (*start)(PlaybackPlug *plug);
-    void (*stop)(PlaybackPlug *plug);
-    void (*get_frame)(PlaybackPlug *plug, uint32_t **frame, uint32_t *samples);
-    void (*put_frame)(PlaybackPlug *plug, uint32_t *frame);
-};
-
-struct PlaybackInterface {
+struct SpicePlaybackInterface {
     SpiceBaseInterface base;
-
-    VDObjectRef (*plug)(PlaybackInterface *playback, PlaybackPlug* plug, int *enable);
-    void (*unplug)(PlaybackInterface *playback, VDObjectRef);
 };
 
-#define VD_INTERFACE_RECORD "record"
-#define VD_INTERFACE_RECORD_MAJOR 2
-#define VD_INTERFACE_RECORD_MINOR 1
-typedef struct RecordInterface RecordInterface;
-
-#define VD_INTERFACE_RECORD_FREQ 44100
-#define VD_INTERFACE_RECORD_CHAN 2
-#define VD_INTERFACE_RECORD_FMT VD_INTERFACE_AUDIO_FMT_S16
-
-
-typedef struct RecordPlug RecordPlug;
-struct RecordPlug {
-    uint32_t minor_version;
-    uint32_t major_version;
-    void (*start)(RecordPlug *plug);
-    void (*stop)(RecordPlug *plug);
-    uint32_t (*read)(RecordPlug *plug, uint32_t num_samples, uint32_t *samples);
+struct SpicePlaybackInstance {
+    SpiceBaseInstance  base;
+    SpicePlaybackState *st;
 };
 
-struct RecordInterface {
+void spice_server_playback_start(SpicePlaybackInstance *sin);
+void spice_server_playback_stop(SpicePlaybackInstance *sin);
+void spice_server_playback_get_buffer(SpicePlaybackInstance *sin,
+                                      uint32_t **samples, uint32_t *nsamples);
+void spice_server_playback_put_samples(SpicePlaybackInstance *sin,
+                                       uint32_t *samples);
+
+#define SPICE_INTERFACE_RECORD "record"
+#define SPICE_INTERFACE_RECORD_MAJOR 2
+#define SPICE_INTERFACE_RECORD_MINOR 1
+typedef struct SpiceRecordInterface SpiceRecordInterface;
+typedef struct SpiceRecordInstance SpiceRecordInstance;
+typedef struct SpiceRecordState SpiceRecordState;
+
+#define SPICE_INTERFACE_RECORD_FREQ  44100
+#define SPICE_INTERFACE_RECORD_CHAN  2
+#define SPICE_INTERFACE_RECORD_FMT   SPICE_INTERFACE_AUDIO_FMT_S16
+
+struct SpiceRecordInterface {
     SpiceBaseInterface base;
+};
 
-    VDObjectRef (*plug)(RecordInterface *recorder, RecordPlug* plug, int *enable);
-    void (*unplug)(RecordInterface *recorder, VDObjectRef);
+struct SpiceRecordInstance {
+    SpiceBaseInstance base;
+    SpiceRecordState  *st;
 };
 
+void spice_server_record_start(SpiceRecordInstance *sin);
+void spice_server_record_stop(SpiceRecordInstance *sin);
+uint32_t spice_server_record_get_samples(SpiceRecordInstance *sin,
+                                         uint32_t *samples, uint32_t bufsize);
+
 #define VD_INTERFACE_VDI_PORT "vdi_port"
 #define VD_INTERFACE_VDI_PORT_MAJOR 1
 #define VD_INTERFACE_VDI_PORT_MINOR 1
-- 
1.6.6.1



More information about the Spice-devel mailing list