[Spice-devel] [spice v4] server: Provide a framerate estimate based on the initial frames
Francois Gouget
fgouget at codeweavers.com
Mon Nov 16 02:10:35 PST 2015
This way the video encoder can actually count on a real estimate when
it is initializing.
Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
server/display-channel.h | 1 +
server/red_worker.c | 22 ++++++++++++++++++----
server/stream.h | 1 +
3 files changed, 20 insertions(+), 4 deletions(-)
Check that duration is not 0 and that we don't exceed MAX_FPS.
diff --git a/server/display-channel.h b/server/display-channel.h
index a9ae40a..23d7a05 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -152,6 +152,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/red_worker.c b/server/red_worker.c
index 165e4c0..23834d3 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -984,6 +984,7 @@ static void display_stream_trace_add_drawable(DisplayChannel *display, Drawable
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;
@@ -1772,7 +1773,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;
@@ -1780,10 +1790,10 @@ 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;
}
@@ -2009,11 +2019,13 @@ static int is_stream_start(Drawable *drawable)
// returns whether a stream was created
static int display_channel_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;
@@ -2074,6 +2086,7 @@ static void display_channel_stream_maintenance(DisplayChannel *display,
FALSE);
if (is_next_frame != STREAM_FRAME_NONE) {
display_channel_stream_add_frame(display, candidate,
+ prev->first_frame_time,
prev->frames_count,
prev->gradual_frames_count,
prev->last_gradual_frame);
@@ -2235,6 +2248,7 @@ static void red_use_stream_trace(DisplayChannel *display, Drawable *drawable)
&trace->dest_area, trace->time, NULL, FALSE) !=
STREAM_FRAME_NONE) {
if (display_channel_stream_add_frame(display, drawable,
+ trace->first_frame_time,
trace->frames_count,
trace->gradual_frames_count,
trace->last_gradual_frame)) {
@@ -2664,7 +2678,7 @@ static Drawable *get_drawable(RedWorker *worker, uint8_t effect, RedDrawable *re
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/stream.h b/server/stream.h
index f77fa96..d9f1a66 100644
--- a/server/stream.h
+++ b/server/stream.h
@@ -108,6 +108,7 @@ StreamClipItem *stream_clip_item_new(DisplayChannelClient* dcc,
typedef struct ItemTrace {
red_time_t time;
+ red_time_t first_frame_time;
int frames_count;
int gradual_frames_count;
int last_gradual_frame;
--
2.6.2
More information about the Spice-devel
mailing list