summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/snd_worker.c44
-rw-r--r--server/snd_worker.h2
m---------spice-common0
3 files changed, 46 insertions, 0 deletions
diff --git a/server/snd_worker.c b/server/snd_worker.c
index 2647d87..d6ec47a 100644
--- a/server/snd_worker.c
+++ b/server/snd_worker.c
@@ -58,6 +58,7 @@ enum PlaybackeCommand {
SND_PLAYBACK_CTRL,
SND_PLAYBACK_PCM,
SND_PLAYBACK_VOLUME,
+ SND_PLAYBACK_LATENCY,
};
enum RecordCommand {
@@ -71,6 +72,7 @@ enum RecordCommand {
#define SND_PLAYBACK_CTRL_MASK (1 << SND_PLAYBACK_CTRL)
#define SND_PLAYBACK_PCM_MASK (1 << SND_PLAYBACK_PCM)
#define SND_PLAYBACK_VOLUME_MASK (1 << SND_PLAYBACK_VOLUME)
+#define SND_PLAYBACK_LATENCY_MASK ( 1 << SND_PLAYBACK_LATENCY)
#define SND_RECORD_MIGRATE_MASK (1 << SND_RECORD_MIGRATE)
#define SND_RECORD_CTRL_MASK (1 << SND_RECORD_CTRL)
@@ -144,6 +146,7 @@ struct PlaybackChannel {
struct {
uint8_t celt_buf[CELT_COMPRESSED_FRAME_BYTES];
} send_data;
+ uint32_t latency;
};
struct SndWorker {
@@ -610,6 +613,20 @@ static int snd_playback_send_mute(PlaybackChannel *playback_channel)
return snd_send_mute(channel, &st->volume, SPICE_MSG_PLAYBACK_MUTE);
}
+static int snd_playback_send_latency(PlaybackChannel *playback_channel)
+{
+ SndChannel *channel = &playback_channel->base;
+ SpiceMsgPlaybackLatency latency_msg;
+
+ spice_debug("latency %u", playback_channel->latency);
+ if (!snd_reset_send_data(channel, SPICE_MSG_PLAYBACK_LATENCY)) {
+ return FALSE;
+ }
+ latency_msg.latency_ms = playback_channel->latency;
+ spice_marshall_msg_playback_latency(channel->send_data.marshaller, &latency_msg);
+
+ return snd_begin_send_message(channel);
+}
static int snd_playback_send_start(PlaybackChannel *playback_channel)
{
SndChannel *channel = (SndChannel *)playback_channel;
@@ -819,6 +836,12 @@ static void snd_playback_send(void* data)
}
channel->command &= ~SND_PLAYBACK_MIGRATE_MASK;
}
+ if (channel->command & SND_PLAYBACK_LATENCY_MASK) {
+ if (!snd_playback_send_latency(playback_channel)) {
+ return;
+ }
+ channel->command &= ~SND_PLAYBACK_LATENCY_MASK;
+ }
}
}
@@ -1096,6 +1119,27 @@ SPICE_GNUC_VISIBLE void spice_server_playback_put_samples(SpicePlaybackInstance
snd_playback_send(&playback_channel->base);
}
+void snd_set_playback_latency(RedClient *client, uint32_t latency)
+{
+ SndWorker *now = workers;
+
+ for (; now; now = now->next) {
+ if (now->base_channel->type == SPICE_CHANNEL_PLAYBACK && now->connection &&
+ now->connection->channel_client->client == client) {
+
+ if (red_channel_client_test_remote_cap(now->connection->channel_client,
+ SPICE_PLAYBACK_CAP_LATENCY)) {
+ PlaybackChannel* playback = (PlaybackChannel*)now->connection;
+
+ playback->latency = latency;
+ snd_set_command(now->connection, SND_PLAYBACK_LATENCY_MASK);
+ snd_playback_send(now->connection);
+ } else {
+ spice_debug("client doesn't not support SPICE_PLAYBACK_CAP_LATENCY");
+ }
+ }
+ }
+}
static void on_new_playback_channel(SndWorker *worker)
{
PlaybackChannel *playback_channel =
diff --git a/server/snd_worker.h b/server/snd_worker.h
index 1811a61..8de746d 100644
--- a/server/snd_worker.h
+++ b/server/snd_worker.h
@@ -29,4 +29,6 @@ void snd_detach_record(SpiceRecordInstance *sin);
void snd_set_playback_compression(int on);
int snd_get_playback_compression(void);
+void snd_set_playback_latency(RedClient *client, uint32_t latency);
+
#endif
diff --git a/spice-common b/spice-common
-Subproject 7cdf8de00a573b6bdb4ec4582c87aa79b25796d
+Subproject 30e84783cad7a5d4cd345367a267cafbfd0571a