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

Yonit Halperin yhalperi at redhat.com
Tue Feb 26 10:04:09 PST 2013


---
 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)
+{
+    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



More information about the Spice-devel mailing list