[Spice-devel] [PATCH 2/7] worker: Move stream functions to stream.c
Frediano Ziglio
fziglio at redhat.com
Thu Nov 12 08:33:37 PST 2015
>
> On Thu, Nov 12, 2015 at 3:00 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 1403b33..27e5203 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)
> > @@ -338,6 +336,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 d33a352..6e1535b 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);
> > }
> > }
> > }
> > @@ -7397,7 +7321,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);
> > }
> > }
> >
> > @@ -8460,7 +8384,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:
> > @@ -8468,7 +8392,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:
> > @@ -8523,19 +8447,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;
> > @@ -8584,11 +8495,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);
> > + }
> > +}
> > +
> > +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
>
> This discussion must be considered:
> http://lists.freedesktop.org/archives/spice-devel/2015-November/023529.html
>
Personally I would rename stream_init to display_channel_init_streams.
About stream_mark_as_free instead of stream_free I think the code
uses a static fixed pool to allocate streams so I think stream_free is good.
OT: as a design prospective I think stream.c should not use any DisplayChannel
at all but define its structure incorporated by DisplayChannel.
Or at least it should use DisplayChannel as an abstract type (that is in C not
having the structure definition but just use the pointer!).
Frediano
More information about the Spice-devel
mailing list