On Tue, Feb 26, 2013 at 01:04:08PM -0500, Yonit Halperin wrote: > When there is no audio playback, we set the mm_time in the client to be older > than the one in the server by at least the requested latency (the delta is > actually bigger, due to the network latency). > When there is an audio playback, we adjust the mm_time in the client by > adjusting the playback buffer using SPICE_MSG_PLAYBACK_LATENCY. ACK nitpick: s/todo/TODO/ - more common to use all caps. > --- > server/main_dispatcher.c | 32 ++++++++++++++++++++++++++++++++ > server/main_dispatcher.h | 1 + > server/reds-private.h | 2 ++ > server/reds.c | 28 +++++++++++++++++++++++++++- > server/reds.h | 2 ++ > 5 files changed, 64 insertions(+), 1 deletion(-) > > diff --git a/server/main_dispatcher.c b/server/main_dispatcher.c > index 1126ec0..8402402 100644 > --- a/server/main_dispatcher.c > +++ b/server/main_dispatcher.c > @@ -40,6 +40,7 @@ MainDispatcher main_dispatcher; > enum { > MAIN_DISPATCHER_CHANNEL_EVENT = 0, > MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE, > + MAIN_DISPATCHER_SET_MM_TIME_LATENCY, > > MAIN_DISPATCHER_NUM_MESSAGES > }; > @@ -53,6 +54,11 @@ typedef struct MainDispatcherMigrateSeamlessDstCompleteMessage { > RedClient *client; > } MainDispatcherMigrateSeamlessDstCompleteMessage; > > +typedef struct MainDispatcherMmTimeLatencyMessage { > + RedClient *client; > + uint32_t latency; > +} MainDispatcherMmTimeLatencyMessage; > + > /* channel_event - calls core->channel_event, must be done in main thread */ > static void main_dispatcher_self_handle_channel_event( > int event, > @@ -96,6 +102,13 @@ static void main_dispatcher_handle_migrate_complete(void *opaque, > reds_on_client_seamless_migrate_complete(mig_complete->client); > } > > +static void main_dispatcher_handle_mm_time_latency(void *opaque, > + void *payload) > +{ > + MainDispatcherMmTimeLatencyMessage *msg = payload; > + reds_set_client_mm_time_latency(msg->client, msg->latency); > +} > + > void main_dispatcher_seamless_migrate_dst_complete(RedClient *client) > { > MainDispatcherMigrateSeamlessDstCompleteMessage msg; > @@ -109,6 +122,22 @@ void main_dispatcher_seamless_migrate_dst_complete(RedClient *client) > dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE, > &msg); > } > + > +void main_dispatcher_set_mm_time_latency(RedClient *client, uint32_t latency) > +{ > + MainDispatcherMmTimeLatencyMessage msg; > + > + if (pthread_self() == main_dispatcher.base.self) { > + reds_set_client_mm_time_latency(client, latency); > + return; > + } > + > + msg.client = client; > + msg.latency = latency; > + dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_SET_MM_TIME_LATENCY, > + &msg); > +} > + > static void dispatcher_handle_read(int fd, int event, void *opaque) > { > Dispatcher *dispatcher = opaque; > @@ -129,4 +158,7 @@ void main_dispatcher_init(SpiceCoreInterface *core) > dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE, > main_dispatcher_handle_migrate_complete, > sizeof(MainDispatcherMigrateSeamlessDstCompleteMessage), 0 /* no ack */); > + dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_SET_MM_TIME_LATENCY, > + main_dispatcher_handle_mm_time_latency, > + sizeof(MainDispatcherMmTimeLatencyMessage), 0 /* no ack */); > } > diff --git a/server/main_dispatcher.h b/server/main_dispatcher.h > index d44ee3a..0c79ca8 100644 > --- a/server/main_dispatcher.h > +++ b/server/main_dispatcher.h > @@ -6,6 +6,7 @@ > > void main_dispatcher_channel_event(int event, SpiceChannelEventInfo *info); > void main_dispatcher_seamless_migrate_dst_complete(RedClient *client); > +void main_dispatcher_set_mm_time_latency(RedClient *client, uint32_t latency); > void main_dispatcher_init(SpiceCoreInterface *core); > > #endif //MAIN_DISPATCHER_H > diff --git a/server/reds-private.h b/server/reds-private.h > index 3db6565..9358d27 100644 > --- a/server/reds-private.h > +++ b/server/reds-private.h > @@ -177,6 +177,8 @@ typedef struct RedsState { > int allow_multiple_clients; > > RedsClientMonitorsConfig client_monitors_config; > + int mm_timer_enabled; > + uint32_t mm_time_latency; > } RedsState; > > #endif > diff --git a/server/reds.c b/server/reds.c > index ec80e9e..d74f465 100644 > --- a/server/reds.c > +++ b/server/reds.c > @@ -3015,6 +3015,29 @@ listen: > return slisten; > } > > +static void reds_send_mm_time(void) > +{ > + main_channel_push_multi_media_time(reds->main_channel, > + reds_get_mm_time() - reds->mm_time_latency); > +} > + > +void reds_set_client_mm_time_latency(RedClient *client, uint32_t latency) > +{ > + // todo: multi-client support for mm_time > + if (reds->mm_timer_enabled) { > + // todo: consider network latency > + if (latency > reds->mm_time_latency) { > + reds->mm_time_latency = latency; > + reds_send_mm_time(); > + } else { > + spice_debug("new latency %u is smaller than existing %u", > + latency, reds->mm_time_latency); > + } > + } else { > + snd_set_playback_latency(client, latency); > + } > +} > + > static int reds_init_net(void) > { > if (spice_port != -1) { > @@ -3447,12 +3470,15 @@ void reds_enable_mm_timer(void) > if (!reds_main_channel_connected()) { > return; > } > - main_channel_push_multi_media_time(reds->main_channel, reds_get_mm_time() - MM_TIME_DELTA); > + reds->mm_timer_enabled = TRUE; > + reds->mm_time_latency = MM_TIME_DELTA; > + reds_send_mm_time(); > } > > void reds_disable_mm_timer(void) > { > core->timer_cancel(reds->mm_timer); > + reds->mm_timer_enabled = FALSE; > } > > static void mm_timer_proc(void *opaque) > diff --git a/server/reds.h b/server/reds.h > index f8e8d56..59f13ce 100644 > --- a/server/reds.h > +++ b/server/reds.h > @@ -164,4 +164,6 @@ void reds_on_client_seamless_migrate_complete(RedClient *client); > void reds_on_main_channel_migrate(MainChannelClient *mcc); > void reds_on_char_device_state_destroy(SpiceCharDeviceState *dev); > > +void reds_set_client_mm_time_latency(RedClient *client, uint32_t latency); > + > #endif > -- > 1.8.1 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel