[spice-server,3/7] Move stream creation/maintenance funcs to DisplayChannel

Submitted by Jonathon Jongsma on Nov. 29, 2017, 8:16 p.m.

Details

Message ID 20171129201610.30738-4-jjongsma@redhat.com
State New
Headers show
Series "Stream cleanups" ( rev: 2 1 ) in Spice

Not browsing as part of any series.

Commit Message

Jonathon Jongsma Nov. 29, 2017, 8:16 p.m.
These functions were really DisplayChannel methods but were mixed in
with the VideoStream (and some DisplayChannelClient code) in
video-stream.h. Putting it in the proper location helps organize the
code better and allows us to make several functions static.

Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
---
 server/display-channel.c | 383 +++++++++++++++++++++++++++++++++++++++++++++++
 server/video-stream.c    | 378 ----------------------------------------------
 server/video-stream.h    |   4 -
 3 files changed, 383 insertions(+), 382 deletions(-)

Patch hide | download patch | download mbox

diff --git a/server/display-channel.c b/server/display-channel.c
index d3db1e0db..96feabc3c 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -25,6 +25,10 @@ 
 
 G_DEFINE_TYPE(DisplayChannel, display_channel, TYPE_COMMON_GRAPHICS_CHANNEL)
 
+static void video_stream_maintenance(DisplayChannel *display,
+                                     Drawable *candidate,
+                                     Drawable *prev);
+static void video_stream_trace_update(DisplayChannel *display, Drawable *drawable);
 enum {
     PROP0,
     PROP_N_SURFACES,
@@ -424,6 +428,26 @@  static void current_add_drawable(DisplayChannel *display,
     drawable->refs++;
 }
 
+static void video_stream_trace_add_drawable(DisplayChannel *display,
+                                            Drawable *item)
+{
+    ItemTrace *trace;
+
+    if (item->stream || !item->streamable) {
+        return;
+    }
+
+    trace = &display->priv->items_trace[display->priv->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;
+    SpiceRect* src_area = &item->red_drawable->u.copy.src_area;
+    trace->width = src_area->right - src_area->left;
+    trace->height = src_area->bottom - src_area->top;
+    trace->dest_area = item->red_drawable->bbox;
+}
 /* Unrefs the drawable and removes it from any rings that it's in, as well as
  * removing any associated shadow item */
 static void current_remove_drawable(DisplayChannel *display, Drawable *item)
@@ -2566,3 +2590,362 @@  void display_channel_debug_oom(DisplayChannel *display, const char *msg)
                 ring_get_length(&display->priv->current_list),
                 red_channel_sum_pipes_size(channel));
 }
+
+static bool is_next_stream_frame(DisplayChannel *display,
+                                 const Drawable *candidate,
+                                 const int other_src_width,
+                                 const int other_src_height,
+                                 const SpiceRect *other_dest,
+                                 const red_time_t other_time,
+                                 const VideoStream *stream,
+                                 int container_candidate_allowed)
+{
+    RedDrawable *red_drawable;
+
+    if (!candidate->streamable) {
+        return FALSE;
+    }
+
+    if (candidate->creation_time - other_time >
+            (stream ? RED_STREAM_CONTINUOUS_MAX_DELTA : RED_STREAM_DETECTION_MAX_DELTA)) {
+        return FALSE;
+    }
+
+    red_drawable = candidate->red_drawable;
+    if (!container_candidate_allowed) {
+        SpiceRect* candidate_src;
+
+        if (!rect_is_equal(&red_drawable->bbox, other_dest)) {
+            return FALSE;
+        }
+
+        candidate_src = &red_drawable->u.copy.src_area;
+        if (candidate_src->right - candidate_src->left != other_src_width ||
+            candidate_src->bottom - candidate_src->top != other_src_height) {
+            return FALSE;
+        }
+    } else {
+        if (!rect_contains(&red_drawable->bbox, other_dest)) {
+            return FALSE;
+        }
+        int candidate_area = rect_get_area(&red_drawable->bbox);
+        int other_area = rect_get_area(other_dest);
+        /* do not stream drawables that are significantly
+         * bigger than the original frame */
+        if (candidate_area > 2 * other_area) {
+            spice_debug("too big candidate:");
+            spice_debug("prev box ==>");
+            rect_debug(other_dest);
+            spice_debug("new box ==>");
+            rect_debug(&red_drawable->bbox);
+            return FALSE;
+        }
+    }
+
+    if (stream) {
+        SpiceBitmap *bitmap = &red_drawable->u.copy.src_bitmap->u.bitmap;
+        if (stream->top_down != !!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+static void before_reattach_stream(DisplayChannel *display,
+                                   VideoStream *stream, Drawable *new_frame)
+{
+    DisplayChannelClient *dcc;
+    int index;
+    VideoStreamAgent *agent;
+    GList *dpi_link, *dpi_next;
+
+    spice_return_if_fail(stream->current);
+
+    if (!red_channel_is_connected(RED_CHANNEL(display))) {
+        return;
+    }
+
+    if (new_frame->process_commands_generation == stream->current->process_commands_generation) {
+        spice_debug("ignoring drop, same process_commands_generation as previous frame");
+        return;
+    }
+
+    index = display_channel_get_video_stream_id(display, stream);
+    for (dpi_link = stream->current->pipes; dpi_link; dpi_link = dpi_next) {
+        RedDrawablePipeItem *dpi = dpi_link->data;
+        dpi_next = dpi_link->next;
+        dcc = dpi->dcc;
+        agent = dcc_get_video_stream_agent(dcc, index);
+
+        if (red_channel_client_pipe_item_is_linked(RED_CHANNEL_CLIENT(dcc),
+                                                   &dpi->dpi_pipe_item)) {
+#ifdef STREAM_STATS
+            agent->stats.num_drops_pipe++;
+#endif
+            agent->video_encoder->notify_server_frame_drop(agent->video_encoder);
+        }
+    }
+}
+
+
+static void attach_stream(DisplayChannel *display, Drawable *drawable, VideoStream *stream)
+{
+    DisplayChannelClient *dcc;
+
+    spice_assert(drawable && stream);
+    spice_assert(!drawable->stream && !stream->current);
+    stream->current = drawable;
+    drawable->stream = stream;
+    stream->last_time = drawable->creation_time;
+
+    uint64_t duration = drawable->creation_time - stream->input_fps_start_time;
+    if (duration >= RED_STREAM_INPUT_FPS_TIMEOUT) {
+        /* Round to the nearest integer, for instance 24 for 23.976 */
+        stream->input_fps = ((uint64_t)stream->num_input_frames * 1000 * 1000 * 1000 + duration / 2) / duration;
+        spice_debug("input-fps=%u", stream->input_fps);
+        stream->num_input_frames = 0;
+        stream->input_fps_start_time = drawable->creation_time;
+    } else {
+        stream->num_input_frames++;
+    }
+
+    FOREACH_DCC(display, dcc) {
+        VideoStreamAgent *agent;
+        QRegion clip_in_draw_dest;
+        int stream_id = display_channel_get_video_stream_id(display, stream);
+
+        agent = dcc_get_video_stream_agent(dcc, stream_id);
+        region_or(&agent->vis_region, &drawable->tree_item.base.rgn);
+
+        region_init(&clip_in_draw_dest);
+        region_add(&clip_in_draw_dest, &drawable->red_drawable->bbox);
+        region_and(&clip_in_draw_dest, &agent->clip);
+
+        if (!region_is_equal(&clip_in_draw_dest, &drawable->tree_item.base.rgn)) {
+            region_remove(&agent->clip, &drawable->red_drawable->bbox);
+            region_or(&agent->clip, &drawable->tree_item.base.rgn);
+            dcc_video_stream_agent_clip(dcc, agent);
+        }
+        region_destroy(&clip_in_draw_dest);
+#ifdef STREAM_STATS
+        agent->stats.num_input_frames++;
+#endif
+    }
+}
+
+static void update_copy_graduality(DisplayChannel *display, Drawable *drawable)
+{
+    SpiceBitmap *bitmap;
+    spice_return_if_fail(drawable->red_drawable->type == QXL_DRAW_COPY);
+
+    if (display_channel_get_stream_video(display) != SPICE_STREAM_VIDEO_FILTER) {
+        drawable->copy_bitmap_graduality = BITMAP_GRADUAL_INVALID;
+        return;
+    }
+
+    if (drawable->copy_bitmap_graduality != BITMAP_GRADUAL_INVALID) {
+        return; // already set
+    }
+
+    bitmap = &drawable->red_drawable->u.copy.src_bitmap->u.bitmap;
+
+    if (!bitmap_fmt_has_graduality(bitmap->format) || bitmap_has_extra_stride(bitmap) ||
+        (bitmap->data->flags & SPICE_CHUNKS_FLAGS_UNSTABLE)) {
+        drawable->copy_bitmap_graduality = BITMAP_GRADUAL_NOT_AVAIL;
+    } else  {
+        drawable->copy_bitmap_graduality = bitmap_get_graduality_level(bitmap);
+    }
+}
+
+static int is_stream_start(Drawable *drawable)
+{
+    return ((drawable->frames_count >= RED_STREAM_FRAMES_START_CONDITION) &&
+            (drawable->gradual_frames_count >=
+             (RED_STREAM_GRADUAL_FRAMES_START_CONDITION * drawable->frames_count)));
+}
+
+static VideoStream *display_channel_stream_try_new(DisplayChannel *display)
+{
+    VideoStream *stream;
+    if (!display->priv->free_streams) {
+        return NULL;
+    }
+    stream = display->priv->free_streams;
+    display->priv->free_streams = display->priv->free_streams->next;
+    stream->display = display;
+    return stream;
+}
+
+static void display_channel_create_stream(DisplayChannel *display, Drawable *drawable)
+{
+    DisplayChannelClient *dcc;
+    VideoStream *stream;
+    SpiceRect* src_rect;
+
+    spice_assert(!drawable->stream);
+
+    if (!(stream = display_channel_stream_try_new(display))) {
+        return;
+    }
+
+    spice_assert(drawable->red_drawable->type == QXL_DRAW_COPY);
+    src_rect = &drawable->red_drawable->u.copy.src_area;
+
+    ring_add(&display->priv->streams, &stream->link);
+    stream->current = drawable;
+    stream->last_time = drawable->creation_time;
+    stream->width = src_rect->right - src_rect->left;
+    stream->height = src_rect->bottom - src_rect->top;
+    stream->dest_area = drawable->red_drawable->bbox;
+    stream->refs = 1;
+    SpiceBitmap *bitmap = &drawable->red_drawable->u.copy.src_bitmap->u.bitmap;
+    stream->top_down = !!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN);
+    drawable->stream = stream;
+    /* 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 > NSEC_PER_SEC * drawable->frames_count / MAX_FPS) {
+        stream->input_fps = (NSEC_PER_SEC * drawable->frames_count + duration / 2) / duration;
+    } else {
+        stream->input_fps = MAX_FPS;
+    }
+    stream->num_input_frames = 0;
+    stream->input_fps_start_time = drawable->creation_time;
+    display->priv->streams_size_total += stream->width * stream->height;
+    display->priv->stream_count++;
+    FOREACH_DCC(display, dcc) {
+        dcc_create_stream(dcc, stream);
+    }
+    spice_debug("stream %d %dx%d (%d, %d) (%d, %d) %u fps",
+                display_channel_get_video_stream_id(display, stream), stream->width,
+                stream->height, stream->dest_area.left, stream->dest_area.top,
+                stream->dest_area.right, stream->dest_area.bottom,
+                stream->input_fps);
+}
+
+// returns whether a stream was created
+static bool video_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;
+
+    if (frame_drawable->copy_bitmap_graduality != BITMAP_GRADUAL_LOW) {
+        if ((frame_drawable->frames_count - last_gradual_frame) >
+            RED_STREAM_FRAMES_RESET_CONDITION) {
+            frame_drawable->frames_count = 1;
+            frame_drawable->gradual_frames_count = 1;
+        } else {
+            frame_drawable->gradual_frames_count++;
+        }
+
+        frame_drawable->last_gradual_frame = frame_drawable->frames_count;
+    } else {
+        frame_drawable->last_gradual_frame = last_gradual_frame;
+    }
+
+    if (is_stream_start(frame_drawable)) {
+        display_channel_create_stream(display, frame_drawable);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/* TODO: document the difference between the 2 functions below */
+void video_stream_trace_update(DisplayChannel *display, Drawable *drawable)
+{
+    ItemTrace *trace;
+    ItemTrace *trace_end;
+    RingItem *item;
+
+    if (drawable->stream || !drawable->streamable || drawable->frames_count) {
+        return;
+    }
+
+    RING_FOREACH(item, &(display)->priv->streams) {
+        VideoStream *stream = SPICE_CONTAINEROF(item, VideoStream, link);
+        bool is_next_frame = is_next_stream_frame(display,
+                                                  drawable,
+                                                  stream->width,
+                                                  stream->height,
+                                                  &stream->dest_area,
+                                                  stream->last_time,
+                                                  stream,
+                                                  TRUE);
+        if (is_next_frame) {
+            if (stream->current) {
+                stream->current->streamable = FALSE; //prevent item trace
+                before_reattach_stream(display, stream, drawable);
+                video_stream_detach_drawable(stream);
+            }
+            attach_stream(display, drawable, stream);
+            return;
+        }
+    }
+
+    trace = display->priv->items_trace;
+    trace_end = trace + NUM_TRACE_ITEMS;
+    for (; trace < trace_end; trace++) {
+        if (is_next_stream_frame(display, drawable, trace->width, trace->height,
+                                 &trace->dest_area, trace->time, NULL, FALSE)) {
+            if (video_stream_add_frame(display, drawable,
+                                       trace->first_frame_time,
+                                       trace->frames_count,
+                                       trace->gradual_frames_count,
+                                       trace->last_gradual_frame)) {
+                return;
+            }
+        }
+    }
+}
+
+void video_stream_maintenance(DisplayChannel *display,
+                              Drawable *candidate, Drawable *prev)
+{
+    bool is_next_frame;
+
+    if (candidate->stream) {
+        return;
+    }
+
+    if (prev->stream) {
+        VideoStream *stream = prev->stream;
+
+        is_next_frame = is_next_stream_frame(display, candidate,
+                                             stream->width, stream->height,
+                                             &stream->dest_area, stream->last_time,
+                                             stream, TRUE);
+        if (is_next_frame) {
+            before_reattach_stream(display, stream, candidate);
+            video_stream_detach_drawable(stream);
+            prev->streamable = FALSE; //prevent item trace
+            attach_stream(display, candidate, stream);
+        }
+    } else if (candidate->streamable) {
+        SpiceRect* prev_src = &prev->red_drawable->u.copy.src_area;
+
+        is_next_frame =
+            is_next_stream_frame(display, candidate, prev_src->right - prev_src->left,
+                                 prev_src->bottom - prev_src->top,
+                                 &prev->red_drawable->bbox, prev->creation_time,
+                                 prev->stream,
+                                 FALSE);
+        if (is_next_frame) {
+            video_stream_add_frame(display, candidate,
+                                   prev->first_frame_time,
+                                   prev->frames_count,
+                                   prev->gradual_frames_count,
+                                   prev->last_gradual_frame);
+        }
+    }
+}
+
+
diff --git a/server/video-stream.c b/server/video-stream.c
index a24c787ef..ddb76a679 100644
--- a/server/video-stream.c
+++ b/server/video-stream.c
@@ -24,8 +24,6 @@ 
 #include "red-client.h"
 
 #define FPS_TEST_INTERVAL 1
-#define FOREACH_STREAMS(display, item)                  \
-    RING_FOREACH(item, &(display)->priv->streams)
 
 static void video_stream_agent_stats_print(VideoStreamAgent *agent)
 {
@@ -166,142 +164,6 @@  VideoStreamClipItem *video_stream_clip_item_new(VideoStreamAgent *agent)
     return item;
 }
 
-static int is_stream_start(Drawable *drawable)
-{
-    return ((drawable->frames_count >= RED_STREAM_FRAMES_START_CONDITION) &&
-            (drawable->gradual_frames_count >=
-             (RED_STREAM_GRADUAL_FRAMES_START_CONDITION * drawable->frames_count)));
-}
-
-static void update_copy_graduality(DisplayChannel *display, Drawable *drawable)
-{
-    SpiceBitmap *bitmap;
-    spice_return_if_fail(drawable->red_drawable->type == QXL_DRAW_COPY);
-
-    if (display_channel_get_stream_video(display) != SPICE_STREAM_VIDEO_FILTER) {
-        drawable->copy_bitmap_graduality = BITMAP_GRADUAL_INVALID;
-        return;
-    }
-
-    if (drawable->copy_bitmap_graduality != BITMAP_GRADUAL_INVALID) {
-        return; // already set
-    }
-
-    bitmap = &drawable->red_drawable->u.copy.src_bitmap->u.bitmap;
-
-    if (!bitmap_fmt_has_graduality(bitmap->format) || bitmap_has_extra_stride(bitmap) ||
-        (bitmap->data->flags & SPICE_CHUNKS_FLAGS_UNSTABLE)) {
-        drawable->copy_bitmap_graduality = BITMAP_GRADUAL_NOT_AVAIL;
-    } else  {
-        drawable->copy_bitmap_graduality = bitmap_get_graduality_level(bitmap);
-    }
-}
-
-static bool is_next_stream_frame(DisplayChannel *display,
-                                 const Drawable *candidate,
-                                 const int other_src_width,
-                                 const int other_src_height,
-                                 const SpiceRect *other_dest,
-                                 const red_time_t other_time,
-                                 const VideoStream *stream,
-                                 int container_candidate_allowed)
-{
-    RedDrawable *red_drawable;
-
-    if (!candidate->streamable) {
-        return FALSE;
-    }
-
-    if (candidate->creation_time - other_time >
-            (stream ? RED_STREAM_CONTINUOUS_MAX_DELTA : RED_STREAM_DETECTION_MAX_DELTA)) {
-        return FALSE;
-    }
-
-    red_drawable = candidate->red_drawable;
-    if (!container_candidate_allowed) {
-        SpiceRect* candidate_src;
-
-        if (!rect_is_equal(&red_drawable->bbox, other_dest)) {
-            return FALSE;
-        }
-
-        candidate_src = &red_drawable->u.copy.src_area;
-        if (candidate_src->right - candidate_src->left != other_src_width ||
-            candidate_src->bottom - candidate_src->top != other_src_height) {
-            return FALSE;
-        }
-    } else {
-        if (!rect_contains(&red_drawable->bbox, other_dest)) {
-            return FALSE;
-        }
-        int candidate_area = rect_get_area(&red_drawable->bbox);
-        int other_area = rect_get_area(other_dest);
-        /* do not stream drawables that are significantly
-         * bigger than the original frame */
-        if (candidate_area > 2 * other_area) {
-            spice_debug("too big candidate:");
-            spice_debug("prev box ==>");
-            rect_debug(other_dest);
-            spice_debug("new box ==>");
-            rect_debug(&red_drawable->bbox);
-            return FALSE;
-        }
-    }
-
-    if (stream) {
-        SpiceBitmap *bitmap = &red_drawable->u.copy.src_bitmap->u.bitmap;
-        if (stream->top_down != !!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
-            return FALSE;
-        }
-    }
-    return TRUE;
-}
-
-static void attach_stream(DisplayChannel *display, Drawable *drawable, VideoStream *stream)
-{
-    DisplayChannelClient *dcc;
-
-    spice_assert(drawable && stream);
-    spice_assert(!drawable->stream && !stream->current);
-    stream->current = drawable;
-    drawable->stream = stream;
-    stream->last_time = drawable->creation_time;
-
-    uint64_t duration = drawable->creation_time - stream->input_fps_start_time;
-    if (duration >= RED_STREAM_INPUT_FPS_TIMEOUT) {
-        /* Round to the nearest integer, for instance 24 for 23.976 */
-        stream->input_fps = ((uint64_t)stream->num_input_frames * 1000 * 1000 * 1000 + duration / 2) / duration;
-        spice_debug("input-fps=%u", stream->input_fps);
-        stream->num_input_frames = 0;
-        stream->input_fps_start_time = drawable->creation_time;
-    } else {
-        stream->num_input_frames++;
-    }
-
-    FOREACH_DCC(display, dcc) {
-        VideoStreamAgent *agent;
-        QRegion clip_in_draw_dest;
-        int stream_id = display_channel_get_video_stream_id(display, stream);
-
-        agent = dcc_get_video_stream_agent(dcc, stream_id);
-        region_or(&agent->vis_region, &drawable->tree_item.base.rgn);
-
-        region_init(&clip_in_draw_dest);
-        region_add(&clip_in_draw_dest, &drawable->red_drawable->bbox);
-        region_and(&clip_in_draw_dest, &agent->clip);
-
-        if (!region_is_equal(&clip_in_draw_dest, &drawable->tree_item.base.rgn)) {
-            region_remove(&agent->clip, &drawable->red_drawable->bbox);
-            region_or(&agent->clip, &drawable->tree_item.base.rgn);
-            dcc_video_stream_agent_clip(dcc, agent);
-        }
-        region_destroy(&clip_in_draw_dest);
-#ifdef STREAM_STATS
-        agent->stats.num_input_frames++;
-#endif
-    }
-}
-
 void video_stream_detach_drawable(VideoStream *stream)
 {
     spice_assert(stream->current && stream->current->stream);
@@ -310,226 +172,6 @@  void video_stream_detach_drawable(VideoStream *stream)
     stream->current = NULL;
 }
 
-static void before_reattach_stream(DisplayChannel *display,
-                                   VideoStream *stream, Drawable *new_frame)
-{
-    DisplayChannelClient *dcc;
-    int index;
-    VideoStreamAgent *agent;
-    GList *dpi_link, *dpi_next;
-
-    spice_return_if_fail(stream->current);
-
-    if (!red_channel_is_connected(RED_CHANNEL(display))) {
-        return;
-    }
-
-    if (new_frame->process_commands_generation == stream->current->process_commands_generation) {
-        spice_debug("ignoring drop, same process_commands_generation as previous frame");
-        return;
-    }
-
-    index = display_channel_get_video_stream_id(display, stream);
-    for (dpi_link = stream->current->pipes; dpi_link; dpi_link = dpi_next) {
-        RedDrawablePipeItem *dpi = dpi_link->data;
-        dpi_next = dpi_link->next;
-        dcc = dpi->dcc;
-        agent = dcc_get_video_stream_agent(dcc, index);
-
-        if (red_channel_client_pipe_item_is_linked(RED_CHANNEL_CLIENT(dcc),
-                                                   &dpi->dpi_pipe_item)) {
-#ifdef STREAM_STATS
-            agent->stats.num_drops_pipe++;
-#endif
-            agent->video_encoder->notify_server_frame_drop(agent->video_encoder);
-        }
-    }
-}
-
-static VideoStream *display_channel_stream_try_new(DisplayChannel *display)
-{
-    VideoStream *stream;
-    if (!display->priv->free_streams) {
-        return NULL;
-    }
-    stream = display->priv->free_streams;
-    display->priv->free_streams = display->priv->free_streams->next;
-    stream->display = display;
-    return stream;
-}
-
-static void display_channel_create_stream(DisplayChannel *display, Drawable *drawable)
-{
-    DisplayChannelClient *dcc;
-    VideoStream *stream;
-    SpiceRect* src_rect;
-
-    spice_assert(!drawable->stream);
-
-    if (!(stream = display_channel_stream_try_new(display))) {
-        return;
-    }
-
-    spice_assert(drawable->red_drawable->type == QXL_DRAW_COPY);
-    src_rect = &drawable->red_drawable->u.copy.src_area;
-
-    ring_add(&display->priv->streams, &stream->link);
-    stream->current = drawable;
-    stream->last_time = drawable->creation_time;
-    stream->width = src_rect->right - src_rect->left;
-    stream->height = src_rect->bottom - src_rect->top;
-    stream->dest_area = drawable->red_drawable->bbox;
-    stream->refs = 1;
-    SpiceBitmap *bitmap = &drawable->red_drawable->u.copy.src_bitmap->u.bitmap;
-    stream->top_down = !!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN);
-    drawable->stream = stream;
-    /* 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 > NSEC_PER_SEC * drawable->frames_count / MAX_FPS) {
-        stream->input_fps = (NSEC_PER_SEC * drawable->frames_count + duration / 2) / duration;
-    } else {
-        stream->input_fps = MAX_FPS;
-    }
-    stream->num_input_frames = 0;
-    stream->input_fps_start_time = drawable->creation_time;
-    display->priv->streams_size_total += stream->width * stream->height;
-    display->priv->stream_count++;
-    FOREACH_DCC(display, dcc) {
-        dcc_create_stream(dcc, stream);
-    }
-    spice_debug("stream %d %dx%d (%d, %d) (%d, %d) %u fps",
-                display_channel_get_video_stream_id(display, stream), stream->width,
-                stream->height, stream->dest_area.left, stream->dest_area.top,
-                stream->dest_area.right, stream->dest_area.bottom,
-                stream->input_fps);
-}
-
-// returns whether a stream was created
-static bool video_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;
-
-    if (frame_drawable->copy_bitmap_graduality != BITMAP_GRADUAL_LOW) {
-        if ((frame_drawable->frames_count - last_gradual_frame) >
-            RED_STREAM_FRAMES_RESET_CONDITION) {
-            frame_drawable->frames_count = 1;
-            frame_drawable->gradual_frames_count = 1;
-        } else {
-            frame_drawable->gradual_frames_count++;
-        }
-
-        frame_drawable->last_gradual_frame = frame_drawable->frames_count;
-    } else {
-        frame_drawable->last_gradual_frame = last_gradual_frame;
-    }
-
-    if (is_stream_start(frame_drawable)) {
-        display_channel_create_stream(display, frame_drawable);
-        return TRUE;
-    }
-    return FALSE;
-}
-
-/* TODO: document the difference between the 2 functions below */
-void video_stream_trace_update(DisplayChannel *display, Drawable *drawable)
-{
-    ItemTrace *trace;
-    ItemTrace *trace_end;
-    RingItem *item;
-
-    if (drawable->stream || !drawable->streamable || drawable->frames_count) {
-        return;
-    }
-
-    FOREACH_STREAMS(display, item) {
-        VideoStream *stream = SPICE_CONTAINEROF(item, VideoStream, link);
-        bool is_next_frame = is_next_stream_frame(display,
-                                                  drawable,
-                                                  stream->width,
-                                                  stream->height,
-                                                  &stream->dest_area,
-                                                  stream->last_time,
-                                                  stream,
-                                                  TRUE);
-        if (is_next_frame) {
-            if (stream->current) {
-                stream->current->streamable = FALSE; //prevent item trace
-                before_reattach_stream(display, stream, drawable);
-                video_stream_detach_drawable(stream);
-            }
-            attach_stream(display, drawable, stream);
-            return;
-        }
-    }
-
-    trace = display->priv->items_trace;
-    trace_end = trace + NUM_TRACE_ITEMS;
-    for (; trace < trace_end; trace++) {
-        if (is_next_stream_frame(display, drawable, trace->width, trace->height,
-                                 &trace->dest_area, trace->time, NULL, FALSE)) {
-            if (video_stream_add_frame(display, drawable,
-                                       trace->first_frame_time,
-                                       trace->frames_count,
-                                       trace->gradual_frames_count,
-                                       trace->last_gradual_frame)) {
-                return;
-            }
-        }
-    }
-}
-
-void video_stream_maintenance(DisplayChannel *display,
-                              Drawable *candidate, Drawable *prev)
-{
-    bool is_next_frame;
-
-    if (candidate->stream) {
-        return;
-    }
-
-    if (prev->stream) {
-        VideoStream *stream = prev->stream;
-
-        is_next_frame = is_next_stream_frame(display, candidate,
-                                             stream->width, stream->height,
-                                             &stream->dest_area, stream->last_time,
-                                             stream, TRUE);
-        if (is_next_frame) {
-            before_reattach_stream(display, stream, candidate);
-            video_stream_detach_drawable(stream);
-            prev->streamable = FALSE; //prevent item trace
-            attach_stream(display, candidate, stream);
-        }
-    } else if (candidate->streamable) {
-        SpiceRect* prev_src = &prev->red_drawable->u.copy.src_area;
-
-        is_next_frame =
-            is_next_stream_frame(display, candidate, prev_src->right - prev_src->left,
-                                 prev_src->bottom - prev_src->top,
-                                 &prev->red_drawable->bbox, prev->creation_time,
-                                 prev->stream,
-                                 FALSE);
-        if (is_next_frame) {
-            video_stream_add_frame(display, candidate,
-                                   prev->first_frame_time,
-                                   prev->frames_count,
-                                   prev->gradual_frames_count,
-                                   prev->last_gradual_frame);
-        }
-    }
-}
-
 static void dcc_update_streams_max_latency(DisplayChannelClient *dcc,
                                            VideoStreamAgent *remove_agent)
 {
@@ -924,23 +566,3 @@  void video_stream_timeout(DisplayChannel *display)
     }
 }
 
-void video_stream_trace_add_drawable(DisplayChannel *display,
-                                     Drawable *item)
-{
-    ItemTrace *trace;
-
-    if (item->stream || !item->streamable) {
-        return;
-    }
-
-    trace = &display->priv->items_trace[display->priv->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;
-    SpiceRect* src_area = &item->red_drawable->u.copy.src_area;
-    trace->width = src_area->right - src_area->left;
-    trace->height = src_area->bottom - src_area->top;
-    trace->dest_area = item->red_drawable->bbox;
-}
diff --git a/server/video-stream.h b/server/video-stream.h
index 88d59c848..e5a35dd89 100644
--- a/server/video-stream.h
+++ b/server/video-stream.h
@@ -130,12 +130,8 @@  struct VideoStream {
 
 void video_stream_stop(VideoStream *stream);
 void video_stream_unref(VideoStream *stream);
-void video_stream_trace_update(DisplayChannel *display, Drawable *drawable);
-void video_stream_maintenance(DisplayChannel *display, Drawable *candidate,
-                              Drawable *prev);
 void video_stream_timeout(DisplayChannel *display);
 void video_stream_detach_and_stop(DisplayChannel *display);
-void video_stream_trace_add_drawable(DisplayChannel *display, Drawable *item);
 void video_stream_detach_behind(DisplayChannel *display, QRegion *region,
                                 Drawable *drawable);