This patch resets the host and guest video streams when the client changes the preferred video-codecs or when the host admin updates the list of video-codecs allowed. TODO: restart only the streams of the client that changed codecs Signed-off-by: Kevin Pouget <kpouget@xxxxxxxxxx> --- server/main-dispatcher.c | 31 ++++++++++++++++++++++++++++++- server/main-dispatcher.h | 1 + server/red-stream-device.c | 6 +++--- server/red-stream-device.h | 2 +- server/reds.c | 11 +++++++++++ server/reds.h | 2 +- server/stream-channel.c | 6 ++++++ 7 files changed, 53 insertions(+), 6 deletions(-) diff --git a/server/main-dispatcher.c b/server/main-dispatcher.c index 2ca68a4d..04f5ac88 100644 --- a/server/main-dispatcher.c +++ b/server/main-dispatcher.c @@ -126,7 +126,7 @@ enum { MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE, MAIN_DISPATCHER_SET_MM_TIME_LATENCY, MAIN_DISPATCHER_CLIENT_DISCONNECT, - + MAIN_DISPATCHER_RESET_STREAM_CHANNELS, MAIN_DISPATCHER_NUM_MESSAGES }; @@ -148,6 +148,11 @@ typedef struct MainDispatcherClientDisconnectMessage { RedClient *client; } MainDispatcherClientDisconnectMessage; + +typedef struct MainDispatcherResetStreamChannelMessage { + RedClient *client; +} MainDispatcherResetStreamChannelMessage; + /* channel_event - calls core->channel_event, must be done in main thread */ static void main_dispatcher_handle_channel_event(void *opaque, void *payload) @@ -203,6 +208,17 @@ static void main_dispatcher_handle_client_disconnect(void *opaque, g_object_unref(msg->client); } +static void main_dispatcher_handle_reset_stream_channel(void *opaque, + void *payload) +{ + RedsState *reds = opaque; + MainDispatcherResetStreamChannelMessage __attribute__((unused)) *msg = payload; + + /* TODO: reset only the char device linked to msg.client */ + + reds_reset_all_stream_char_devices(reds); +} + void main_dispatcher_seamless_migrate_dst_complete(MainDispatcher *self, RedClient *client) { @@ -247,6 +263,16 @@ void main_dispatcher_client_disconnect(MainDispatcher *self, RedClient *client) } } +void main_dispatcher_reset_stream_channels(MainDispatcher *self, RedClient *client) +{ + MainDispatcherResetStreamChannelMessage msg; + + msg.client = client; + + dispatcher_send_message(DISPATCHER(self), MAIN_DISPATCHER_RESET_STREAM_CHANNELS, + &msg); +} + /* * FIXME: * Reds routines shouldn't be exposed. Instead reds.c should register the callbacks, @@ -282,6 +308,9 @@ void main_dispatcher_constructed(GObject *object) dispatcher_register_handler(DISPATCHER(self), MAIN_DISPATCHER_CLIENT_DISCONNECT, main_dispatcher_handle_client_disconnect, sizeof(MainDispatcherClientDisconnectMessage), false); + dispatcher_register_handler(DISPATCHER(self), MAIN_DISPATCHER_RESET_STREAM_CHANNELS, + main_dispatcher_handle_reset_stream_channel, + sizeof(MainDispatcherResetStreamChannelMessage), false); } static void main_dispatcher_finalize(GObject *object) diff --git a/server/main-dispatcher.h b/server/main-dispatcher.h index e1244f83..6d5f50a0 100644 --- a/server/main-dispatcher.h +++ b/server/main-dispatcher.h @@ -58,6 +58,7 @@ void main_dispatcher_set_mm_time_latency(MainDispatcher *self, RedClient *client * that triggered the client destruction. */ void main_dispatcher_client_disconnect(MainDispatcher *self, RedClient *client); +void main_dispatcher_reset_stream_channels(MainDispatcher *self, RedClient *client); MainDispatcher* main_dispatcher_new(RedsState *reds); diff --git a/server/red-stream-device.c b/server/red-stream-device.c index 620e581e..c551de69 100644 --- a/server/red-stream-device.c +++ b/server/red-stream-device.c @@ -702,8 +702,8 @@ stream_device_create_channel(StreamDevice *dev) stream_channel_register_queue_stat_cb(stream_channel, stream_device_stream_queue_stat, dev); } -static void -reset_channels(StreamDevice *dev) +void +stream_device_reset_channels(StreamDevice *dev) { if (dev->stream_channel) { stream_channel_reset(dev->stream_channel); @@ -763,7 +763,7 @@ stream_device_port_event(RedCharDevice *char_dev, uint8_t event) dev->has_error = false; dev->flow_stopped = false; red_char_device_reset(char_dev); - reset_channels(dev); + stream_device_reset_channels(dev); // enable the device again. We re-enable it on close as otherwise we don't want to get a // failure when we try to re-open the device as would happen if we keep it disabled diff --git a/server/red-stream-device.h b/server/red-stream-device.h index aa2b23a2..0f080228 100644 --- a/server/red-stream-device.h +++ b/server/red-stream-device.h @@ -55,7 +55,7 @@ StreamDevice *stream_device_connect(RedsState *reds, SpiceCharDeviceInstance *si * If the channel already exists the function does nothing. */ void stream_device_create_channel(StreamDevice *dev); - +void stream_device_reset_channels(StreamDevice *dev); const StreamDeviceDisplayInfo *stream_device_get_device_display_info(StreamDevice *dev); /** diff --git a/server/reds.c b/server/reds.c index a3795ab9..9aae838d 100644 --- a/server/reds.c +++ b/server/reds.c @@ -3301,6 +3301,17 @@ static void reds_on_char_device_destroy(RedsState *reds, reds->char_devices = g_list_remove(reds->char_devices, dev); } +void reds_reset_all_stream_char_devices(RedsState *reds) +{ + RedCharDevice *dev; + + GLIST_FOREACH(reds->char_devices, RedCharDevice, dev) { + if (IS_STREAM_DEVICE(dev)) { + stream_device_reset_channels(STREAM_DEVICE(dev)); + } + } +} + static int spice_server_char_device_add_interface(SpiceServer *reds, SpiceBaseInstance *sin) { diff --git a/server/reds.h b/server/reds.h index e3355f81..ec106394 100644 --- a/server/reds.h +++ b/server/reds.h @@ -53,7 +53,7 @@ bool reds_config_get_playback_compression(RedsState *reds); // used by playback void reds_send_device_display_info(RedsState *reds); void reds_handle_agent_mouse_event(RedsState *reds, const VDAgentMouseState *mouse_state); // used by inputs_channel - +void reds_reset_all_stream_char_devices(RedsState *reds); GArray* reds_get_renderers(RedsState *reds); char *reds_get_video_codec_fullname(RedVideoCodec *codec); diff --git a/server/stream-channel.c b/server/stream-channel.c index e0e41895..99ce7c9a 100644 --- a/server/stream-channel.c +++ b/server/stream-channel.c @@ -465,6 +465,12 @@ stream_channel_handle_preferred_video_codec_type(RedChannelClient *rcc, g_clear_pointer(&scc->client_preferred_video_codecs, g_array_unref); scc->client_preferred_video_codecs = video_stream_parse_preferred_codecs(msg); + /* Reset video streams */ + RedClient *client = red_channel_client_get_client(rcc); + RedsState *reds = red_client_get_server(client); + + main_dispatcher_reset_stream_channels(reds_get_main_dispatcher(reds), client); + return TRUE; } -- 2.21.0 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel