[RFC,spice-server] fixup! streaming: Restart guest video streams on video-codec changes

Submitted by Kevin Pouget on Aug. 7, 2019, 3:39 p.m.

Details

Message ID 20190807153942.21971-1-kpouget@redhat.com
State New
Headers show
Series "fixup! streaming: Restart guest video streams on video-codec changes" ( rev: 1 ) in Spice

Not browsing as part of any series.

Commit Message

Kevin Pouget Aug. 7, 2019, 3:39 p.m.
Update of the previous patch that resets only the stream channel whose
preferred codec list has been updated

Signed-off-by: Kevin Pouget <kpouget@redhat.com>
---
 server/main-dispatcher.c | 12 +++++-------
 server/main-dispatcher.h |  2 +-
 server/reds.c            | 15 ++++++++++++---
 server/reds.h            |  2 +-
 server/stream-channel.c  |  7 ++++++-
 5 files changed, 25 insertions(+), 13 deletions(-)

--
2.21.0

Patch hide | download patch | download mbox

diff --git a/server/main-dispatcher.c b/server/main-dispatcher.c
index 04f5ac88..ef2d4fba 100644
--- a/server/main-dispatcher.c
+++ b/server/main-dispatcher.c
@@ -150,7 +150,7 @@  typedef struct MainDispatcherClientDisconnectMessage {


 typedef struct MainDispatcherResetStreamChannelMessage {
-    RedClient *client;
+    int32_t channel_id;
 } MainDispatcherResetStreamChannelMessage;

 /* channel_event - calls core->channel_event, must be done in main thread */
@@ -212,11 +212,9 @@  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 */
+    MainDispatcherResetStreamChannelMessage *msg = payload;

-    reds_reset_all_stream_char_devices(reds);
+    reds_reset_stream_channel(reds, msg->channel_id);
 }

 void main_dispatcher_seamless_migrate_dst_complete(MainDispatcher *self,
@@ -263,11 +261,11 @@  void main_dispatcher_client_disconnect(MainDispatcher *self, RedClient *client)
     }
 }

-void main_dispatcher_reset_stream_channels(MainDispatcher *self, RedClient *client)
+void main_dispatcher_reset_stream_channel(MainDispatcher *self, int32_t channel_id)
 {
     MainDispatcherResetStreamChannelMessage msg;

-    msg.client = client;
+    msg.channel_id = channel_id;

     dispatcher_send_message(DISPATCHER(self), MAIN_DISPATCHER_RESET_STREAM_CHANNELS,
                             &msg);
diff --git a/server/main-dispatcher.h b/server/main-dispatcher.h
index 6d5f50a0..5f386bf2 100644
--- a/server/main-dispatcher.h
+++ b/server/main-dispatcher.h
@@ -58,7 +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);
+void main_dispatcher_reset_stream_channel(MainDispatcher *self, int32_t channel_id);

 MainDispatcher* main_dispatcher_new(RedsState *reds);

diff --git a/server/reds.c b/server/reds.c
index 9aae838d..d47a0237 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -3301,15 +3301,24 @@  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)
+void reds_reset_stream_channel(RedsState *reds, int32_t channel_id)
 {
     RedCharDevice *dev;

     GLIST_FOREACH(reds->char_devices, RedCharDevice, dev) {
-        if (IS_STREAM_DEVICE(dev)) {
-            stream_device_reset_channels(STREAM_DEVICE(dev));
+        if (!IS_STREAM_DEVICE(dev)) {
+            continue;
         }
+
+        StreamDevice *stream_dev = STREAM_DEVICE(dev);
+        if (stream_device_get_stream_channel_id(stream_dev) != channel_id) {
+            continue;
+        }
+
+        stream_device_reset_channels(stream_dev);
+        return;
     }
+    spice_warning("channel %d not found", channel_id);
 }

 static int spice_server_char_device_add_interface(SpiceServer *reds,
diff --git a/server/reds.h b/server/reds.h
index ec106394..6d0ed3ee 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);
+void reds_reset_stream_channel(RedsState *reds, int32_t channel_id);
 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 99ce7c9a..ea53a451 100644
--- a/server/stream-channel.c
+++ b/server/stream-channel.c
@@ -468,8 +468,13 @@  stream_channel_handle_preferred_video_codec_type(RedChannelClient *rcc,
     /* Reset video streams */
     RedClient *client = red_channel_client_get_client(rcc);
     RedsState *reds = red_client_get_server(client);
+    StreamChannel *channel = STREAM_CHANNEL(red_channel_client_get_channel(rcc));
+
+    int32_t channel_id;
+    g_object_get(channel, "id", &channel_id, NULL);
+    main_dispatcher_reset_stream_channel(reds_get_main_dispatcher(reds), channel_id);

-    main_dispatcher_reset_stream_channels(reds_get_main_dispatcher(reds), client);
+    // stream_channel_reset(channel); ?

     return TRUE;
 }

Comments

> 
> Update of the previous patch that resets only the stream channel whose
> preferred codec list has been updated
> 
> Signed-off-by: Kevin Pouget <kpouget@redhat.com>

Why not just computing the list and call request_new_stream ?
This would require a single file change.

> ---
>  server/main-dispatcher.c | 12 +++++-------
>  server/main-dispatcher.h |  2 +-
>  server/reds.c            | 15 ++++++++++++---
>  server/reds.h            |  2 +-
>  server/stream-channel.c  |  7 ++++++-
>  5 files changed, 25 insertions(+), 13 deletions(-)
> 
> diff --git a/server/main-dispatcher.c b/server/main-dispatcher.c
> index 04f5ac88..ef2d4fba 100644
> --- a/server/main-dispatcher.c
> +++ b/server/main-dispatcher.c
> @@ -150,7 +150,7 @@ typedef struct MainDispatcherClientDisconnectMessage {
> 
> 
>  typedef struct MainDispatcherResetStreamChannelMessage {
> -    RedClient *client;
> +    int32_t channel_id;
>  } MainDispatcherResetStreamChannelMessage;
> 
>  /* channel_event - calls core->channel_event, must be done in main thread */
> @@ -212,11 +212,9 @@ 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 */
> +    MainDispatcherResetStreamChannelMessage *msg = payload;
> 
> -    reds_reset_all_stream_char_devices(reds);
> +    reds_reset_stream_channel(reds, msg->channel_id);
>  }
> 
>  void main_dispatcher_seamless_migrate_dst_complete(MainDispatcher *self,
> @@ -263,11 +261,11 @@ void main_dispatcher_client_disconnect(MainDispatcher
> *self, RedClient *client)
>      }
>  }
> 
> -void main_dispatcher_reset_stream_channels(MainDispatcher *self, RedClient
> *client)
> +void main_dispatcher_reset_stream_channel(MainDispatcher *self, int32_t
> channel_id)
>  {
>      MainDispatcherResetStreamChannelMessage msg;
> 
> -    msg.client = client;
> +    msg.channel_id = channel_id;
> 
>      dispatcher_send_message(DISPATCHER(self),
>      MAIN_DISPATCHER_RESET_STREAM_CHANNELS,
>                              &msg);
> diff --git a/server/main-dispatcher.h b/server/main-dispatcher.h
> index 6d5f50a0..5f386bf2 100644
> --- a/server/main-dispatcher.h
> +++ b/server/main-dispatcher.h
> @@ -58,7 +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);
> +void main_dispatcher_reset_stream_channel(MainDispatcher *self, int32_t
> channel_id);
> 
>  MainDispatcher* main_dispatcher_new(RedsState *reds);
> 
> diff --git a/server/reds.c b/server/reds.c
> index 9aae838d..d47a0237 100644
> --- a/server/reds.c
> +++ b/server/reds.c
> @@ -3301,15 +3301,24 @@ 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)
> +void reds_reset_stream_channel(RedsState *reds, int32_t channel_id)
>  {
>      RedCharDevice *dev;
> 
>      GLIST_FOREACH(reds->char_devices, RedCharDevice, dev) {
> -        if (IS_STREAM_DEVICE(dev)) {
> -            stream_device_reset_channels(STREAM_DEVICE(dev));
> +        if (!IS_STREAM_DEVICE(dev)) {
> +            continue;
>          }
> +
> +        StreamDevice *stream_dev = STREAM_DEVICE(dev);
> +        if (stream_device_get_stream_channel_id(stream_dev) != channel_id) {
> +            continue;
> +        }
> +
> +        stream_device_reset_channels(stream_dev);
> +        return;
>      }
> +    spice_warning("channel %d not found", channel_id);
>  }
> 
>  static int spice_server_char_device_add_interface(SpiceServer *reds,
> diff --git a/server/reds.h b/server/reds.h
> index ec106394..6d0ed3ee 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);
> +void reds_reset_stream_channel(RedsState *reds, int32_t channel_id);
>  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 99ce7c9a..ea53a451 100644
> --- a/server/stream-channel.c
> +++ b/server/stream-channel.c
> @@ -468,8 +468,13 @@
> stream_channel_handle_preferred_video_codec_type(RedChannelClient *rcc,
>      /* Reset video streams */
>      RedClient *client = red_channel_client_get_client(rcc);
>      RedsState *reds = red_client_get_server(client);
> +    StreamChannel *channel =
> STREAM_CHANNEL(red_channel_client_get_channel(rcc));
> +
> +    int32_t channel_id;
> +    g_object_get(channel, "id", &channel_id, NULL);
> +    main_dispatcher_reset_stream_channel(reds_get_main_dispatcher(reds),
> channel_id);
> 
> -    main_dispatcher_reset_stream_channels(reds_get_main_dispatcher(reds),
> client);
> +    // stream_channel_reset(channel); ?
> 
>      return TRUE;
>  }

Frediano