On Wed, 2017-08-30 at 16:28 +0100, Frediano Ziglio wrote: > When a new client is connected we must restart the stream so new > clients can receive correct data without having to wait for the > next full screen (which on idle screen could take ages). > On disconnection we should tell the guest to stop streaming > not wasting resources to stream not needed data. > > Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> > --- > server/stream-channel.c | 77 > +++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 77 insertions(+) > > diff --git a/server/stream-channel.c b/server/stream-channel.c > index 5baaf559..6e21660a 100644 > --- a/server/stream-channel.c > +++ b/server/stream-channel.c > @@ -116,8 +116,32 @@ stream_channel_client_init(StreamChannelClient > *client) > } > > static void > +request_new_stream(StreamChannel *channel, StreamMsgStartStop > *start) > +{ > + if (channel->start_cb) { > + channel->start_cb(channel->start_opaque, start, channel); > + } > +} > + > +static void > stream_channel_client_on_disconnect(RedChannelClient *rcc) > { > + RedChannel *red_channel = red_channel_client_get_channel(rcc); > + > + // if there are still some client connected keep streaming > + // TODO, maybe would be worth sending new codecs if they are > better > + if (red_channel_is_connected(red_channel)) { > + return; > + } > + > + StreamChannel *channel = STREAM_CHANNEL(red_channel); > + channel->stream_id = -1; > + channel->width = 0; > + channel->height = 0; > + > + // send stream stop to device > + StreamMsgStartStop stop = { 0, }; > + request_new_stream(channel, &stop); > } > > static StreamChannelClient* > @@ -253,6 +277,51 @@ stream_channel_new(RedsState *server, uint32_t > id) > NULL); > } > > +// find common codecs supported by all clients > +static StreamMsgStartStop* > +stream_channel_get_supported_codecs(StreamChannel *channel) > +{ > + RedChannelClient *rcc; > + int codec; > + > + static const uint16_t codec2cap[] = { > + 0, // invalid > + SPICE_DISPLAY_CAP_CODEC_MJPEG, > + SPICE_DISPLAY_CAP_CODEC_VP8, > + SPICE_DISPLAY_CAP_CODEC_H264, > + SPICE_DISPLAY_CAP_CODEC_VP9, > + }; > + > + bool supported[SPICE_N_ELEMENTS(codec2cap)]; > + > + for (codec = 0; codec < SPICE_N_ELEMENTS(codec2cap); ++codec) { > + supported[codec] = true; > + } > + > + FOREACH_CLIENT(channel, rcc) { > + for (codec = 1; codec < SPICE_N_ELEMENTS(codec2cap); > ++codec) { > + // if do not support codec delete from list > + if (!red_channel_client_test_remote_cap(rcc, > codec2cap[codec])) { > + supported[codec] = false; > + } > + } > + } > + > + // surely mjpeg is supported > + supported[SPICE_VIDEO_CODEC_TYPE_MJPEG] = true; > + > + StreamMsgStartStop *start = spice_malloc0(sizeof(*start) + > sizeof(start->codecs[0]) * 256); I don't really understand why you use 256 here... > + int num = 0; > + for (codec = 1; codec < SPICE_N_ELEMENTS(codec2cap); ++codec) { > + if (supported[codec]) { > + start->codecs[num++] = codec; > + } > + } > + start->num_codecs = num; > + > + return start; > +} > + > static void > stream_channel_connect(RedChannel *red_channel, RedClient > *red_client, RedsStream *stream, > int migration, RedChannelCapabilities *caps) > @@ -265,6 +334,14 @@ stream_channel_connect(RedChannel *red_channel, > RedClient *red_client, RedsStrea > client = stream_channel_client_new(channel, red_client, stream, > migration, caps); > spice_return_if_fail(client != NULL); > > + // request new stream > + StreamMsgStartStop* start = > stream_channel_get_supported_codecs(channel); > + // send in any case, even if list is not changed > + // notify device about changes > + request_new_stream(channel, start); > + free(start); > + > + > // TODO set capabilities like SPICE_DISPLAY_CAP_MONITORS_CONFIG > // see guest_set_client_capabilities > RedChannelClient *rcc = RED_CHANNEL_CLIENT(client); Acked-by: Jonathon Jongsma <jjongsma@xxxxxxxxxx> _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel