[Spice-devel] [PATCH spice-server 22/28] reds: support mm_time latency adjustments

Alon Levy alevy at redhat.com
Sun Apr 14 06:34:12 PDT 2013


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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel


More information about the Spice-devel mailing list