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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]