[Spice-devel] [PATCH spice-server 10/28] mjpeg_encoder: add stream warmup time, in which we avoid server and client drops

Alon Levy alevy at redhat.com
Sun Apr 14 06:24:22 PDT 2013


On Tue, Feb 26, 2013 at 01:03:56PM -0500, Yonit Halperin wrote:
> The stream starts after lossless frames were sent to the client,
> and without rate control (except for pipe congestion). Thus, on the beginning
> of the stream, we might observe frame drops on the client and server side which
> are not necessarily related to mis-estimation of the bit rate, and we would
> like to wait till the stream stabilizes.

ACK

> ---
>  server/mjpeg_encoder.c | 27 +++++++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/server/mjpeg_encoder.c b/server/mjpeg_encoder.c
> index 037a232..277794b 100644
> --- a/server/mjpeg_encoder.c
> +++ b/server/mjpeg_encoder.c
> @@ -59,6 +59,15 @@ static const int mjpeg_quality_samples[MJPEG_QUALITY_SAMPLE_NUM] = {20, 30, 40,
>   */
>  #define MJPEG_MAX_CLIENT_PLAYBACK_DELAY 5000 // 5 sec
>  
> +/*
> + * The stream starts after lossless frames were sent to the client,
> + * and without rate control (except for pipe congestion). Thus, on the beginning
> + * of the stream, we might observe frame drops on the client and server side which
> + * are not necessarily related to mis-estimation of the bit rate, and we would
> + * like to wait till the stream stabilizes.
> + */
> +#define MJPEG_WARMUP_TIME 3000L // 3 sec
> +
>  enum {
>      MJPEG_QUALITY_EVAL_TYPE_SET,
>      MJPEG_QUALITY_EVAL_TYPE_UPGRADE,
> @@ -140,6 +149,7 @@ typedef struct MJpegEncoderRateControl {
>      uint64_t sum_recent_enc_size;
>      uint32_t num_recent_enc_frames;
>  
> +    uint64_t warmup_start_time;
>  } MJpegEncoderRateControl;
>  
>  struct MJpegEncoder {
> @@ -182,12 +192,16 @@ MJpegEncoder *mjpeg_encoder_new(int bit_rate_control, uint64_t starting_bit_rate
>      enc->rate_control_is_active = bit_rate_control;
>      enc->rate_control.byte_rate = starting_bit_rate / 8;
>      if (bit_rate_control) {
> +        struct timespec time;
> +
> +        clock_gettime(CLOCK_MONOTONIC, &time);
>          enc->cbs = *cbs;
>          enc->cbs_opaque = opaque;
>          mjpeg_encoder_reset_quality(enc, MJPEG_QUALITY_SAMPLE_NUM / 2, 5, 0);
>          enc->rate_control.during_quality_eval = TRUE;
>          enc->rate_control.quality_eval_data.type = MJPEG_QUALITY_EVAL_TYPE_SET;
>          enc->rate_control.quality_eval_data.reason = MJPEG_QUALITY_EVAL_REASON_RATE_CHANGE;
> +        enc->rate_control.warmup_start_time = ((uint64_t) time.tv_sec) * 1000000000 + time.tv_nsec;
>      } else {
>          mjpeg_encoder_reset_quality(enc, MJPEG_LEGACY_STATIC_QUALITY_ID, MJPEG_MAX_FPS, 0);
>      }
> @@ -894,6 +908,19 @@ static void mjpeg_encoder_decrease_bit_rate(MJpegEncoder *encoder)
>  
>      rate_control->client_state.max_video_latency = 0;
>      rate_control->client_state.max_audio_latency = 0;
> +    if (rate_control->warmup_start_time) {
> +        struct timespec time;
> +        uint64_t now;
> +
> +        clock_gettime(CLOCK_MONOTONIC, &time);
> +        now = ((uint64_t) time.tv_sec) * 1000000000 + time.tv_nsec;
> +        if (now - rate_control->warmup_start_time < MJPEG_WARMUP_TIME*1000*1000) {
> +            spice_debug("during warmup. ignoring");
> +            return;
> +        } else {
> +            rate_control->warmup_start_time = 0;
> +        }
> +    }
>  
>      if (bit_rate_info->num_enc_frames > MJPEG_BIT_RATE_EVAL_MIN_NUM_FRAMES ||
>          bit_rate_info->num_enc_frames > rate_control->fps) {
> -- 
> 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