[Spice-commits] server/display-channel.c server/display-channel.h server/stream.c server/stream.h

Victor Toso de Carvalho victortoso at kemper.freedesktop.org
Fri Dec 11 03:44:49 PST 2015


 server/display-channel.c |    2 +-
 server/display-channel.h |    1 +
 server/stream.c          |   21 ++++++++++++++++++---
 server/stream.h          |    1 +
 4 files changed, 21 insertions(+), 4 deletions(-)

New commits:
commit 0ad7f71e24af6c362fa6bcd30aa4ba43527974a3
Author: Francois Gouget <fgouget at codeweavers.com>
Date:   Wed Dec 2 15:36:29 2015 +0100

    server: Provide a framerate estimate based on the initial frames
    
    This way the video encoder can actually count on a real estimate when
    it is initializing.
    Note that the server only creates a video stream if at least 20 bitmap
    'blits' of the same size and type arrive, each within a maximum time
    interval from the previous one. So it was only keeping track of the
    frame to frame interval. Thus to get an average frame rate over all the
    20 frames it's necessary to also keep track of the first_frame_time.
    
    Signed-off-by: Francois Gouget <fgouget at codeweavers.com>

diff --git a/server/display-channel.c b/server/display-channel.c
index 7cbcea5..80d7335 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -1371,7 +1371,7 @@ Drawable *display_channel_drawable_try_new(DisplayChannel *display,
 
     bzero(drawable, sizeof(Drawable));
     drawable->refs = 1;
-    drawable->creation_time = red_get_monotonic_time();
+    drawable->creation_time = drawable->first_frame_time = red_get_monotonic_time();
     ring_item_init(&drawable->list_link);
     ring_item_init(&drawable->surface_list_link);
     ring_item_init(&drawable->tree_item.base.siblings_link);
diff --git a/server/display-channel.h b/server/display-channel.h
index 3d414c2..c57bc8e 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -66,6 +66,7 @@ struct Drawable {
     Ring glz_ring;
 
     red_time_t creation_time;
+    red_time_t first_frame_time;
     int frames_count;
     int gradual_frames_count;
     int last_gradual_frame;
diff --git a/server/stream.c b/server/stream.c
index cb7271e..b65d430 100644
--- a/server/stream.c
+++ b/server/stream.c
@@ -425,7 +425,16 @@ static void display_channel_create_stream(DisplayChannel *display, Drawable *dra
     SpiceBitmap *bitmap = &drawable->red_drawable->u.copy.src_bitmap->u.bitmap;
     stream->top_down = !!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN);
     drawable->stream = stream;
-    stream->input_fps = MAX_FPS;
+    /* Provide an fps estimate the video encoder can use when initializing
+     * based on the frames that lead to the creation of the stream. Round to
+     * the nearest integer, for instance 24 for 23.976.
+     */
+    uint64_t duration = drawable->creation_time - drawable->first_frame_time;
+    if (duration > (uint64_t)drawable->frames_count * 1000 * 1000 * 1000 / MAX_FPS) {
+        stream->input_fps = ((uint64_t)drawable->frames_count * 1000 * 1000 * 1000 + duration / 2) / duration;
+    } else {
+        stream->input_fps = MAX_FPS;
+    }
     stream->num_input_frames = 0;
     stream->input_fps_start_time = drawable->creation_time;
     display->streams_size_total += stream->width * stream->height;
@@ -433,21 +442,24 @@ static void display_channel_create_stream(DisplayChannel *display, Drawable *dra
     FOREACH_DCC(display, dcc_ring_item, next, dcc) {
         dcc_create_stream(dcc, stream);
     }
-    spice_debug("stream %d %dx%d (%d, %d) (%d, %d)",
+    spice_debug("stream %d %dx%d (%d, %d) (%d, %d) %u fps",
                 (int)(stream - display->streams_buf), stream->width,
                 stream->height, stream->dest_area.left, stream->dest_area.top,
-                stream->dest_area.right, stream->dest_area.bottom);
+                stream->dest_area.right, stream->dest_area.bottom,
+                stream->input_fps);
     return;
 }
 
 // returns whether a stream was created
 static int stream_add_frame(DisplayChannel *display,
                             Drawable *frame_drawable,
+                            red_time_t first_frame_time,
                             int frames_count,
                             int gradual_frames_count,
                             int last_gradual_frame)
 {
     update_copy_graduality(display, frame_drawable);
+    frame_drawable->first_frame_time = first_frame_time;
     frame_drawable->frames_count = frames_count + 1;
     frame_drawable->gradual_frames_count  = gradual_frames_count;
 
@@ -514,6 +526,7 @@ void stream_trace_update(DisplayChannel *display, Drawable *drawable)
                                        &trace->dest_area, trace->time, NULL, FALSE) !=
                                        STREAM_FRAME_NONE) {
             if (stream_add_frame(display, drawable,
+                                 trace->first_frame_time,
                                  trace->frames_count,
                                  trace->gradual_frames_count,
                                  trace->last_gradual_frame)) {
@@ -559,6 +572,7 @@ void stream_maintenance(DisplayChannel *display,
                                  FALSE);
         if (is_next_frame != STREAM_FRAME_NONE) {
             stream_add_frame(display, candidate,
+                             prev->first_frame_time,
                              prev->frames_count,
                              prev->gradual_frames_count,
                              prev->last_gradual_frame);
@@ -910,6 +924,7 @@ void stream_trace_add_drawable(DisplayChannel *display, Drawable *item)
 
     trace = &display->items_trace[display->next_item_trace++ & ITEMS_TRACE_MASK];
     trace->time = item->creation_time;
+    trace->first_frame_time = item->first_frame_time;
     trace->frames_count = item->frames_count;
     trace->gradual_frames_count = item->gradual_frames_count;
     trace->last_gradual_frame = item->last_gradual_frame;
diff --git a/server/stream.h b/server/stream.h
index 3a30172..e20c8de 100644
--- a/server/stream.h
+++ b/server/stream.h
@@ -114,6 +114,7 @@ void                  stream_clip_item_unref                        (DisplayChan
 
 typedef struct ItemTrace {
     red_time_t time;
+    red_time_t first_frame_time;
     int frames_count;
     int gradual_frames_count;
     int last_gradual_frame;


More information about the Spice-commits mailing list