[Spice-devel] [PATCH spice-server 23/28] red_worker: video streams - adjust client playback latency

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


On Tue, Feb 26, 2013 at 01:04:09PM -0500, Yonit Halperin wrote:

ACK

one comment below

> ---
>  server/red_worker.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 51 insertions(+), 5 deletions(-)
> 
> diff --git a/server/red_worker.c b/server/red_worker.c
> index 46dd069..acf391d 100644
> --- a/server/red_worker.c
> +++ b/server/red_worker.c
> @@ -81,6 +81,7 @@
>  #include "main_channel.h"
>  #include "migration_protocol.h"
>  #include "spice_timer_queue.h"
> +#include "main_dispatcher.h"
>  
>  //#define COMPRESS_STAT
>  //#define DUMP_BITMAP
> @@ -470,6 +471,7 @@ typedef struct StreamAgent {
>      int fps;
>  
>      uint32_t report_id;
> +    uint32_t client_required_latency;
>  } StreamAgent;
>  
>  typedef struct StreamClipItem {
> @@ -690,6 +692,7 @@ struct DisplayChannelClient {
>  
>      StreamAgent stream_agents[NUM_STREAMS];
>      int use_mjpeg_encoder_rate_control;
> +    uint32_t streams_max_latency;
>  };
>  
>  struct DisplayChannel {
> @@ -2901,6 +2904,52 @@ static uint32_t red_stream_mjpeg_encoder_get_source_fps(void *opaque)
>      return agent->stream->input_fps;
>  }
>  
> +static void red_display_update_streams_max_latency(DisplayChannelClient *dcc, StreamAgent *remove_agent)
> +{

Would require less indenting if the body was moved after the if and the
condition negated.

> +    if (dcc->streams_max_latency == remove_agent->client_required_latency) {
> +        dcc->streams_max_latency = 0;
> +        if (dcc->common.worker->stream_count > 1) {
> +            uint32_t new_max_latency = 0;
> +            int i;
> +
> +            for (i = 0; i < NUM_STREAMS; i++) {
> +                StreamAgent *other_agent = &dcc->stream_agents[i];
> +                if (other_agent == remove_agent || !other_agent->mjpeg_encoder) {
> +                    continue;
> +                }
> +                if (other_agent->client_required_latency > new_max_latency) {
> +                    new_max_latency = other_agent->client_required_latency;
> +                }
> +            }
> +            dcc->streams_max_latency = new_max_latency;
> +        }
> +    }
> +}
> +
> +static void red_display_stream_agent_stop(DisplayChannelClient *dcc, StreamAgent *agent)
> +{
> +    red_display_update_streams_max_latency(dcc, agent);
> +    if (agent->mjpeg_encoder) {
> +        mjpeg_encoder_destroy(agent->mjpeg_encoder);
> +        agent->mjpeg_encoder = NULL;
> +    }
> +}
> +
> +static void red_stream_update_client_playback_latency(void *opaque, uint32_t delay_ms)
> +{
> +    StreamAgent *agent = opaque;
> +    DisplayChannelClient *dcc = agent->dcc;
> +
> +    red_display_update_streams_max_latency(dcc, agent);
> +
> +    agent->client_required_latency = delay_ms;
> +    if (delay_ms > agent->dcc->streams_max_latency) {
> +         agent->dcc->streams_max_latency = delay_ms;
> +    }
> +    spice_debug("reseting client latency: %u", agent->dcc->streams_max_latency);
> +    main_dispatcher_set_mm_time_latency(agent->dcc->common.base.client, agent->dcc->streams_max_latency);
> +}
> +
>  static void red_display_create_stream(DisplayChannelClient *dcc, Stream *stream)
>  {
>      StreamAgent *agent = &dcc->stream_agents[get_stream_id(dcc->common.worker, stream)];
> @@ -2924,6 +2973,7 @@ static void red_display_create_stream(DisplayChannelClient *dcc, Stream *stream)
>  
>          mjpeg_cbs.get_roundtrip_ms = red_stream_mjpeg_encoder_get_roundtrip;
>          mjpeg_cbs.get_source_fps = red_stream_mjpeg_encoder_get_source_fps;
> +        mjpeg_cbs.update_client_playback_delay = red_stream_update_client_playback_latency;
>  
>          initial_bit_rate = red_stream_get_initial_bit_rate(dcc, stream);
>          agent->mjpeg_encoder = mjpeg_encoder_new(TRUE, initial_bit_rate, &mjpeg_cbs, agent);
> @@ -8894,11 +8944,7 @@ static void red_display_marshall_stream_end(RedChannelClient *rcc,
>  
>      red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_STREAM_DESTROY, NULL);
>      destroy.id = get_stream_id(dcc->common.worker, agent->stream);
> -
> -    if (agent->mjpeg_encoder) {
> -        mjpeg_encoder_destroy(agent->mjpeg_encoder);
> -        agent->mjpeg_encoder = NULL;
> -    }
> +    red_display_stream_agent_stop(dcc, agent);
>      spice_marshall_msg_display_stream_destroy(base_marshaller, &destroy);
>  }
>  
> -- 
> 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