[Spice-devel] [spice-html5 6/6] Send stream process reports after we have processed them.

Jeremy White jwhite at codeweavers.com
Fri Jul 1 20:03:06 UTC 2016


Previously, we sent them strictly upon receipt.  However, receiving
is fast; by adding in some of the processing time (i.e. queueing and
so on), we encourage the adaptive rate control to slow down.

Signed-off-by: Jeremy White <jwhite at codeweavers.com>
---
 display.js | 81 +++++++++++++++++++++++++++++++++++++++-----------------------
 main.js    |  6 +++++
 2 files changed, 57 insertions(+), 30 deletions(-)

diff --git a/display.js b/display.js
index 00b6011..12fbab0 100644
--- a/display.js
+++ b/display.js
@@ -594,18 +594,14 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
             return false;
         }
 
-        var mmtime = (Date.now() - this.parent.our_mm_time) + this.parent.mm_time;
-        var latency = m.base.multi_media_time - mmtime;
+        var time_until_due = m.base.multi_media_time - this.parent.relative_now();
 
         if (this.streams[m.base.id].codec_type === SPICE_VIDEO_CODEC_TYPE_MJPEG)
-            process_mjpeg_stream_data(this, m, latency);
+            process_mjpeg_stream_data(this, m, time_until_due);
 
         if (this.streams[m.base.id].codec_type === SPICE_VIDEO_CODEC_TYPE_VP8)
             process_video_stream_data(this.streams[m.base.id], m);
 
-        if ("report" in this.streams[m.base.id])
-            process_stream_data_report(this, m, mmtime, latency);
-
         return true;
     }
 
@@ -958,11 +954,14 @@ function handle_draw_jpeg_onload()
 
         this.o.sc.surfaces[this.o.base.surface_id].draw_count++;
     }
+
+    if ("report" in this.o.sc.streams[this.o.id])
+            process_stream_data_report(this.o.sc, this.o.id, this.o.msg_mmtime, this.o.msg_mmtime - this.o.sc.parent.relative_now())
 }
 
-function process_mjpeg_stream_data(sc, m, latency)
+function process_mjpeg_stream_data(sc, m, time_until_due)
 {
-    if (latency < 0)
+    if (time_until_due < 0)
     {
         if ("report" in sc.streams[m.base.id])
             sc.streams[m.base.id].report.num_drops++;
@@ -988,30 +987,32 @@ function process_mjpeg_stream_data(sc, m, latency)
           tag: "mjpeg." + m.base.id,
           descriptor: null,
           sc : sc,
+          id : m.base.id,
+          msg_mmtime : m.base.multi_media_time,
         };
     img.onload = handle_draw_jpeg_onload;
     img.src = tmpstr;
 }
 
-function process_stream_data_report(sc, m, mmtime, latency)
+function process_stream_data_report(sc, id, msg_mmtime, time_until_due)
 {
-    sc.streams[m.base.id].report.num_frames++;
-    if (sc.streams[m.base.id].report.start_frame_mm_time == 0)
-        sc.streams[m.base.id].report.start_frame_mm_time = m.base.multi_media_time;
+    sc.streams[id].report.num_frames++;
+    if (sc.streams[id].report.start_frame_mm_time == 0)
+        sc.streams[id].report.start_frame_mm_time = msg_mmtime;
 
-    if (sc.streams[m.base.id].report.num_frames > sc.streams[m.base.id].max_window_size ||
-        (m.base.multi_media_time - sc.streams[m.base.id].report.start_frame_mm_time) > sc.streams[m.base.id].timeout_ms)
+    if (sc.streams[id].report.num_frames > sc.streams[id].max_window_size ||
+        (msg_mmtime - sc.streams[id].report.start_frame_mm_time) > sc.streams[id].timeout_ms)
     {
-        sc.streams[m.base.id].report.end_frame_mm_time = m.base.multi_media_time;
-        sc.streams[m.base.id].report.last_frame_delay = latency;
+        sc.streams[id].report.end_frame_mm_time = msg_mmtime;
+        sc.streams[id].report.last_frame_delay = time_until_due;
 
         var msg = new SpiceMiniData();
-        msg.build_msg(SPICE_MSGC_DISPLAY_STREAM_REPORT, sc.streams[m.base.id].report);
+        msg.build_msg(SPICE_MSGC_DISPLAY_STREAM_REPORT, sc.streams[id].report);
         sc.send_msg(msg);
 
-        sc.streams[m.base.id].report.start_frame_mm_time = 0;
-        sc.streams[m.base.id].report.num_frames = 0;
-        sc.streams[m.base.id].report.num_drops = 0;
+        sc.streams[id].report.start_frame_mm_time = 0;
+        sc.streams[id].report.num_frames = 0;
+        sc.streams[id].report.num_drops = 0;
     }
 }
 
@@ -1085,10 +1086,17 @@ function handle_append_video_buffer_done(e)
 {
     var stream = this.stream;
 
+    if (stream.current_frame && "report" in stream)
+    {
+        var sc = this.stream.media.spiceconn;
+        var t = this.stream.current_frame.msg_mmtime;
+        process_stream_data_report(sc, stream.id, t, t - sc.parent.relative_now());
+    }
+
     if (stream.queue.length > 0)
     {
-        var mb = stream.queue.shift();
-        append_video_buffer(stream.source_buffer, mb);
+        stream.current_frame = stream.queue.shift();
+        append_video_buffer(stream.source_buffer, stream.current_frame.mb);
     }
     else
     {
@@ -1102,16 +1110,32 @@ function handle_video_buffer_error(e)
     p.log_err('source_buffer error ' + e.message);
 }
 
+function push_or_queue(stream, msg, mb)
+{
+    var frame =
+    {
+        msg_mmtime : msg.base.multi_media_time,
+    };
+
+    if (stream.append_okay)
+    {
+        stream.current_frame = frame;
+        append_video_buffer(stream.source_buffer, mb);
+    }
+    else
+    {
+        frame.mb = mb;
+        stream.queue.push(frame);
+    }
+}
+
 function video_simple_block(stream, msg, keyframe)
 {
     var simple = new webm_SimpleBlock(msg.base.multi_media_time - stream.cluster_time, msg.data, keyframe);
     var mb = new ArrayBuffer(simple.buffer_size());
     simple.to_buffer(mb);
 
-    if (stream.append_okay)
-        append_video_buffer(stream.source_buffer, mb);
-    else
-        stream.queue.push(mb);
+    push_or_queue(stream, msg, mb);
 }
 
 function new_video_cluster(stream, msg)
@@ -1122,10 +1146,7 @@ function new_video_cluster(stream, msg)
     var mb = new ArrayBuffer(c.buffer_size());
     c.to_buffer(mb);
 
-    if (stream.append_okay)
-        append_video_buffer(stream.source_buffer, mb);
-    else
-        stream.queue.push(mb);
+    push_or_queue(stream, msg, mb);
 
     video_simple_block(stream, msg, true);
 }
diff --git a/main.js b/main.js
index 3d9b13f..afe69bf 100644
--- a/main.js
+++ b/main.js
@@ -478,3 +478,9 @@ SpiceMainConn.prototype.handle_mouse_mode = function(current, supported)
         this.inputs.mouse_mode = current;
 }
 
+/* Shift current time to attempt to get a time matching that of the server */
+SpiceMainConn.prototype.relative_now = function()
+{
+    var ret = (Date.now() - this.our_mm_time) + this.mm_time;
+    return ret;
+}
-- 
2.1.4



More information about the Spice-devel mailing list