[Spice-devel] [PATCH 01/11] worker: Move stream functions to stream.c

Fabiano FidĂȘncio fidencio at redhat.com
Mon Nov 16 04:28:45 PST 2015


On Mon, Nov 16, 2015 at 12:06 PM, Frediano Ziglio <fziglio at redhat.com> wrote:
> From: Jonathon Jongsma <jjongsma at redhat.com>
>
> ---
>  server/display-channel.h |  17 +++++++-
>  server/red_worker.c      | 105 ++++-------------------------------------------
>  server/stream.c          |  70 +++++++++++++++++++++++++++++++
>  server/stream.h          |  12 +++++-
>  4 files changed, 104 insertions(+), 100 deletions(-)
>
> diff --git a/server/display-channel.h b/server/display-channel.h
> index a9ae40a..9c82465 100644
> --- a/server/display-channel.h
> +++ b/server/display-channel.h
> @@ -57,8 +57,6 @@
>  #include "tree.h"
>  #include "stream.h"
>
> -typedef struct DisplayChannel DisplayChannel;
> -
>  #define PALETTE_CACHE_HASH_SHIFT 8
>  #define PALETTE_CACHE_HASH_SIZE (1 << PALETTE_CACHE_HASH_SHIFT)
>  #define PALETTE_CACHE_HASH_MASK (PALETTE_CACHE_HASH_SIZE - 1)
> @@ -345,6 +343,21 @@ struct DisplayChannel {
>      stat_info_t lz4_stat;
>  #endif
>  };
> +
> +#define LINK_TO_DCC(ptr) SPICE_CONTAINEROF(ptr, DisplayChannelClient,   \
> +                                           common.base.channel_link)
> +#define DCC_FOREACH_SAFE(link, next, dcc, channel)                      \
> +    SAFE_FOREACH(link, next, channel,  &(channel)->clients, dcc, LINK_TO_DCC(link))
> +
> +
> +#define FOREACH_DCC(display_channel, link, next, dcc)                   \
> +    DCC_FOREACH_SAFE(link, next, dcc, RED_CHANNEL(display_channel))
> +
> +static inline int get_stream_id(DisplayChannel *display, Stream *stream)
> +{
> +    return (int)(stream - display->streams_buf);
> +}
> +
>  typedef struct SurfaceDestroyItem {
>      SpiceMsgSurfaceDestroy surface_destroy;
>      PipeItem pipe_item;
> diff --git a/server/red_worker.c b/server/red_worker.c
> index 165e4c0..f72d304 100644
> --- a/server/red_worker.c
> +++ b/server/red_worker.c
> @@ -330,22 +330,6 @@ static void display_channel_client_release_item_before_push(DisplayChannelClient
>  static void display_channel_client_release_item_after_push(DisplayChannelClient *dcc,
>                                                             PipeItem *item);
>
> -/*
> - * Macros to make iterating over stuff easier
> - * The two collections we iterate over:
> - *  given a channel, iterate over it's clients
> - */
> -
> -#define LINK_TO_DCC(ptr) SPICE_CONTAINEROF(ptr, DisplayChannelClient,  \
> -                                      common.base.channel_link)
> -#define DCC_FOREACH_SAFE(link, next, dcc, channel)                       \
> -    SAFE_FOREACH(link, next, channel,  &(channel)->clients, dcc, LINK_TO_DCC(link))
> -
> -
> -#define FOREACH_DCC(display_channel, link, next, dcc)      \
> -    DCC_FOREACH_SAFE(link, next, dcc, RED_CHANNEL(display_channel))
> -
> -
>  #define LINK_TO_DPI(ptr) SPICE_CONTAINEROF((ptr), DrawablePipeItem, base)
>  #define DRAWABLE_FOREACH_DPI_SAFE(drawable, link, next, dpi)          \
>      SAFE_FOREACH(link, next, drawable,  &(drawable)->pipes, dpi, LINK_TO_DPI(link))
> @@ -357,38 +341,12 @@ static void display_channel_client_release_item_after_push(DisplayChannelClient
>      SAFE_FOREACH(link, next, drawable, &(drawable)->glz_ring, glz, LINK_TO_GLZ(link))
>
>
> -static int get_stream_id(DisplayChannel *display, Stream *stream)
> -{
> -    return (int)(stream - display->streams_buf);
> -}
> -
> -static void display_stream_free(DisplayChannel *display, Stream *stream)
> -{
> -    stream->next = display->free_streams;
> -    display->free_streams = stream;
> -}
> -
> -static void display_stream_unref(DisplayChannel *display, Stream *stream)
> -{
> -    if (--stream->refs != 0)
> -        return;
> -
> -    spice_warn_if_fail(!ring_item_is_linked(&stream->link));
> -    display_stream_free(display, stream);
> -    display->stream_count--;
> -}
> -
> -static void display_stream_agent_unref(DisplayChannel *display, StreamAgent *agent)
> -{
> -    display_stream_unref(display, agent->stream);
> -}
> -
>  static void display_stream_clip_unref(DisplayChannel *display, StreamClipItem *item)
>  {
>      if (--item->refs != 0)
>          return;
>
> -    display_stream_agent_unref(display, item->stream_agent);
> +    stream_agent_unref(display, item->stream_agent);
>      free(item->rects);
>      free(item);
>  }
> @@ -453,40 +411,6 @@ void attach_stream(DisplayChannel *display, Drawable *drawable, Stream *stream)
>      }
>  }
>
> -static void stop_stream(DisplayChannel *display, Stream *stream)
> -{
> -    DisplayChannelClient *dcc;
> -    RingItem *item, *next;
> -
> -    spice_assert(ring_item_is_linked(&stream->link));
> -    spice_assert(!stream->current);
> -    spice_debug("stream %d", get_stream_id(display, stream));
> -    FOREACH_DCC(display, item, next, dcc) {
> -        StreamAgent *stream_agent;
> -
> -        stream_agent = &dcc->stream_agents[get_stream_id(display, stream)];
> -        region_clear(&stream_agent->vis_region);
> -        region_clear(&stream_agent->clip);
> -        spice_assert(!pipe_item_is_linked(&stream_agent->destroy_item));
> -        if (stream_agent->mjpeg_encoder && dcc->use_mjpeg_encoder_rate_control) {
> -            uint64_t stream_bit_rate = mjpeg_encoder_get_bit_rate(stream_agent->mjpeg_encoder);
> -
> -            if (stream_bit_rate > dcc->streams_max_bit_rate) {
> -                spice_debug("old max-bit-rate=%.2f new=%.2f",
> -                dcc->streams_max_bit_rate / 8.0 / 1024.0 / 1024.0,
> -                stream_bit_rate / 8.0 / 1024.0 / 1024.0);
> -                dcc->streams_max_bit_rate = stream_bit_rate;
> -            }
> -        }
> -        stream->refs++;
> -        red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &stream_agent->destroy_item);
> -        stream_agent_stats_print(stream_agent);
> -    }
> -    display->streams_size_total -= stream->width * stream->height;
> -    ring_remove(&stream->link);
> -    display_stream_unref(display, stream);
> -}
> -
>  /* fixme: move to display channel */
>  DrawablePipeItem *drawable_pipe_item_new(DisplayChannelClient *dcc,
>                                           Drawable *drawable)
> @@ -822,7 +746,7 @@ static void stop_streams(DisplayChannel *display)
>          Stream *stream = SPICE_CONTAINEROF(item, Stream, link);
>          item = ring_next(ring, item);
>          if (!stream->current) {
> -            stop_stream(display, stream);
> +            stream_stop(display, stream);
>          } else {
>              spice_info("attached stream");
>          }
> @@ -1555,7 +1479,7 @@ static void display_channel_streams_timeout(DisplayChannel *display)
>          item = ring_next(ring, item);
>          if (now >= (stream->last_time + RED_STREAM_TIMEOUT)) {
>              detach_stream_gracefully(display, stream, NULL);
> -            stop_stream(display, stream);
> +            stream_stop(display, stream);
>          }
>      }
>  }
> @@ -7400,7 +7324,7 @@ static void detach_and_stop_streams(DisplayChannel *display)
>          Stream *stream = SPICE_CONTAINEROF(stream_item, Stream, link);
>
>          detach_stream_gracefully(display, stream, NULL);
> -        stop_stream(display, stream);
> +        stream_stop(display, stream);
>      }
>  }
>
> @@ -8463,7 +8387,7 @@ static void display_channel_client_release_item_before_push(DisplayChannelClient
>      }
>      case PIPE_ITEM_TYPE_STREAM_CREATE: {
>          StreamAgent *agent = SPICE_CONTAINEROF(item, StreamAgent, create_item);
> -        display_stream_agent_unref(display, agent);
> +        stream_agent_unref(display, agent);
>          break;
>      }
>      case PIPE_ITEM_TYPE_STREAM_CLIP:
> @@ -8471,7 +8395,7 @@ static void display_channel_client_release_item_before_push(DisplayChannelClient
>          break;
>      case PIPE_ITEM_TYPE_STREAM_DESTROY: {
>          StreamAgent *agent = SPICE_CONTAINEROF(item, StreamAgent, destroy_item);
> -        display_stream_agent_unref(display, agent);
> +        stream_agent_unref(display, agent);
>          break;
>      }
>      case PIPE_ITEM_TYPE_UPGRADE:
> @@ -8526,19 +8450,6 @@ static void display_channel_release_item(RedChannelClient *rcc, PipeItem *item,
>      }
>  }
>
> -static void init_streams(DisplayChannel *display)
> -{
> -    int i;
> -
> -    ring_init(&display->streams);
> -    display->free_streams = NULL;
> -    for (i = 0; i < NUM_STREAMS; i++) {
> -        Stream *stream = &display->streams_buf[i];
> -        ring_item_init(&stream->link);
> -        display_stream_free(display, stream);
> -    }
> -}
> -
>  static void display_channel_create(RedWorker *worker, int migrate, int stream_video)
>  {
>      DisplayChannel *display_channel;
> @@ -8587,11 +8498,11 @@ static void display_channel_create(RedWorker *worker, int migrate, int stream_vi
>      display_channel->num_renderers = num_renderers;
>      memcpy(display_channel->renderers, renderers, sizeof(display_channel->renderers));
>      display_channel->renderer = RED_RENDERER_INVALID;
> -    display_channel->stream_video = stream_video;
> -    init_streams(display_channel);
>      image_cache_init(&display_channel->image_cache);
>      ring_init(&display_channel->current_list);
>      drawables_init(display_channel);
> +    display_channel->stream_video = stream_video;
> +    stream_init(display_channel);
>  }
>
>  static void guest_set_client_capabilities(RedWorker *worker)
> diff --git a/server/stream.c b/server/stream.c
> index 7ef7876..d61cec1 100644
> --- a/server/stream.c
> +++ b/server/stream.c
> @@ -57,6 +57,76 @@ void stream_agent_stats_print(StreamAgent *agent)
>  #endif
>  }
>
> +void stream_stop(DisplayChannel *display, Stream *stream)
> +{
> +    DisplayChannelClient *dcc;
> +    RingItem *item, *next;
> +
> +    spice_return_if_fail(ring_item_is_linked(&stream->link));
> +    spice_return_if_fail(!stream->current);
> +
> +    spice_debug("stream %d", get_stream_id(display, stream));
> +    FOREACH_DCC(display, item, next, dcc) {
> +        StreamAgent *stream_agent;
> +
> +        stream_agent = &dcc->stream_agents[get_stream_id(display, stream)];
> +        region_clear(&stream_agent->vis_region);
> +        region_clear(&stream_agent->clip);
> +        spice_assert(!pipe_item_is_linked(&stream_agent->destroy_item));
> +        if (stream_agent->mjpeg_encoder && dcc->use_mjpeg_encoder_rate_control) {
> +            uint64_t stream_bit_rate = mjpeg_encoder_get_bit_rate(stream_agent->mjpeg_encoder);
> +
> +            if (stream_bit_rate > dcc->streams_max_bit_rate) {
> +                spice_debug("old max-bit-rate=%.2f new=%.2f",
> +                dcc->streams_max_bit_rate / 8.0 / 1024.0 / 1024.0,
> +                stream_bit_rate / 8.0 / 1024.0 / 1024.0);
> +                dcc->streams_max_bit_rate = stream_bit_rate;
> +            }
> +        }
> +        stream->refs++;
> +        red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &stream_agent->destroy_item);
> +        stream_agent_stats_print(stream_agent);
> +    }
> +    display->streams_size_total -= stream->width * stream->height;
> +    ring_remove(&stream->link);
> +    stream_unref(display, stream);
> +}
> +
> +static void stream_free(DisplayChannel *display, Stream *stream)
> +{
> +    stream->next = display->free_streams;
> +    display->free_streams = stream;
> +}
> +
> +void stream_init(DisplayChannel *display)
> +{
> +    int i;
> +
> +    ring_init(&display->streams);
> +    display->free_streams = NULL;
> +    for (i = 0; i < NUM_STREAMS; i++) {
> +        Stream *stream = &display->streams_buf[i];
> +        ring_item_init(&stream->link);
> +        stream_free(display, stream);
> +    }
> +}

It was already pointed out a few times since this patch was sent.
stream init is not exactly what this function is doing. It was,
previously, called init_streams(), what makes sense as it also
initializes the streams ring. IMHO we should differentiate between a
single stream operation and operations with the streams' ring. I don't
remember if we ended up with another suggestion, neither if it would
make sense to split more this patch.


> +
> +void stream_unref(DisplayChannel *display, Stream *stream)
> +{
> +    if (--stream->refs != 0)
> +        return;
> +
> +    spice_warn_if_fail(!ring_item_is_linked(&stream->link));
> +
> +    stream_free(display, stream);
> +    display->stream_count--;
> +}
> +
> +void stream_agent_unref(DisplayChannel *display, StreamAgent *agent)
> +{
> +    stream_unref(display, agent->stream);
> +}
> +
>  StreamClipItem *stream_clip_item_new(DisplayChannelClient* dcc, StreamAgent *agent)
>  {
>      StreamClipItem *item = spice_new(StreamClipItem, 1);
> diff --git a/server/stream.h b/server/stream.h
> index f77fa96..4704937 100644
> --- a/server/stream.h
> +++ b/server/stream.h
> @@ -40,6 +40,9 @@
>  #define RED_STREAM_DEFAULT_HIGH_START_BIT_RATE (10 * 1024 * 1024) // 10Mbps
>  #define RED_STREAM_DEFAULT_LOW_START_BIT_RATE (2.5 * 1024 * 1024) // 2.5Mbps
>
> +/* move back to display_channel once struct private */
> +typedef struct DisplayChannel DisplayChannel;
> +
>  typedef struct Stream Stream;
>
>  typedef struct StreamActivateReportItem {
> @@ -132,6 +135,13 @@ struct Stream {
>      uint32_t input_fps;
>  };
>
> -void stream_agent_stats_print(StreamAgent *agent);
> +void                  stream_init                                   (DisplayChannel *display);
> +void                  stream_stop                                   (DisplayChannel *display,
> +                                                                     Stream *stream);
> +void                  stream_unref                                  (DisplayChannel *display,
> +                                                                     Stream *stream);
> +void                  stream_agent_unref                            (DisplayChannel *display,
> +                                                                     StreamAgent *agent);
> +void                  stream_agent_stats_print                      (StreamAgent *agent);
>
>  #endif /* STREAM_H */
> --
> 2.4.3
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel

Best Regards,


More information about the Spice-devel mailing list