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@xxxxxxxxxx> --- server/display-channel.c | 383 +++++++++++++++++++++++++++++++++++++++++++++++ server/video-stream.c | 378 ---------------------------------------------- server/video-stream.h | 4 - 3 files changed, 383 insertions(+), 382 deletions(-) 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); -- 2.13.6 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel