[Spice-devel] [RFC/POC PATCH spice 05/16] Handle the StreamInfo message from the streaming agent

Lukáš Hrázký lhrazky at redhat.com
Tue Jun 5 15:30:31 UTC 2018


The StreamInfo message contains the guest (xrandr) output ID of the
monitor that is being streamed. It will later be passed to the client in
the MonitorsConfig message.
---
 server/red-stream-device.c | 43 ++++++++++++++++++++++++++++++++++++--
 server/stream-channel.c    | 14 +++++++++++--
 server/stream-channel.h    |  1 +
 spice-common               |  2 +-
 4 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/server/red-stream-device.c b/server/red-stream-device.c
index da6d3094..90ab99d9 100644
--- a/server/red-stream-device.c
+++ b/server/red-stream-device.c
@@ -34,6 +34,7 @@ struct StreamDevice {
     uint8_t hdr_pos;
     union {
         StreamMsgFormat format;
+        StreamMsgInfo info;
         StreamMsgCapabilities capabilities;
         StreamMsgCursorSet cursor_set;
         StreamMsgCursorMove cursor_move;
@@ -63,8 +64,8 @@ static void char_device_set_state(RedCharDevice *char_dev, int state);
 typedef bool StreamMsgHandler(StreamDevice *dev, SpiceCharDeviceInstance *sin)
     SPICE_GNUC_WARN_UNUSED_RESULT;
 
-static StreamMsgHandler handle_msg_format, handle_msg_data, handle_msg_cursor_set,
-    handle_msg_cursor_move, handle_msg_capabilities;
+static StreamMsgHandler handle_msg_format, handle_msg_info,
+    handle_msg_data, handle_msg_cursor_set, handle_msg_cursor_move, handle_msg_capabilities;
 
 static bool handle_msg_invalid(StreamDevice *dev, SpiceCharDeviceInstance *sin,
                                const char *error_msg) SPICE_GNUC_WARN_UNUSED_RESULT;
@@ -161,6 +162,13 @@ stream_device_partial_read(StreamDevice *dev, SpiceCharDeviceInstance *sin)
     case STREAM_TYPE_CAPABILITIES:
         handled = handle_msg_capabilities(dev, sin);
         break;
+    case STREAM_TYPE_INFO:
+        if (dev->hdr.size != sizeof(StreamMsgInfo)) {
+            handled = handle_msg_invalid(dev, sin, "Wrong size for StreamMsgInfo");
+        } else {
+            handled = handle_msg_info(dev, sin);
+        }
+        break;
     default:
         handled = handle_msg_invalid(dev, sin, "Invalid message type");
         break;
@@ -264,6 +272,37 @@ handle_msg_format(StreamDevice *dev, SpiceCharDeviceInstance *sin)
     return true;
 }
 
+static bool
+handle_msg_info(StreamDevice *dev, SpiceCharDeviceInstance *sin)
+{
+    SpiceCharDeviceInterface *sif = spice_char_device_get_interface(sin);
+
+    if (spice_extra_checks) {
+        spice_assert(dev->hdr_pos >= sizeof(StreamDevHeader));
+        spice_assert(dev->hdr.type == STREAM_TYPE_INFO);
+    }
+
+    int n = sif->read(sin, dev->msg->buf + dev->msg_pos, sizeof(StreamMsgInfo) - dev->msg_pos);
+    if (n < 0) {
+        return handle_msg_invalid(dev, sin, NULL);
+    }
+
+    dev->msg_pos += n;
+
+    if (dev->msg_pos < sizeof(StreamMsgInfo)) {
+        return false;
+    }
+
+    dev->msg->info.output_id = GUINT32_FROM_LE(dev->msg->info.output_id);
+    if (dev->msg->info.output_id < 1) {
+        return handle_msg_invalid(dev, sin, "StreamMsgInfo.output_id has to be greater than 0.");
+    }
+
+    stream_channel_handle_stream_info(dev->stream_channel, &dev->msg->info);
+
+    return true;
+}
+
 static bool
 handle_msg_capabilities(StreamDevice *dev, SpiceCharDeviceInstance *sin)
 {
diff --git a/server/stream-channel.c b/server/stream-channel.c
index 680fa3d1..138f685d 100644
--- a/server/stream-channel.c
+++ b/server/stream-channel.c
@@ -71,6 +71,8 @@ struct StreamChannel {
     int stream_id;
     /* size of the current video stream */
     unsigned width, height;
+    /* the guest (xrandr) output ID for monitors_config */
+    uint32_t output_id;
 
     StreamQueueStat queue_stat;
 
@@ -198,9 +200,9 @@ marshall_monitors_config(RedChannelClient *rcc, StreamChannel *channel, SpiceMar
     } msg = {
         { 1, 1, },
         {
-            // monitor ID. These IDs are allocated per channel starting from 0
-            0,
+            0,  // monitor ID. These IDs are allocated per channel starting from 0
             PRIMARY_SURFACE_ID,
+            channel->output_id,  // The guest (xrandr) output ID from the streaming agent
             channel->width, channel->height,
             0, 0,
             0 // flags
@@ -516,6 +518,14 @@ stream_channel_change_format(StreamChannel *channel, const StreamMsgFormat *fmt)
     red_channel_pipes_add_type(red_channel, RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT);
 }
 
+void
+stream_channel_handle_stream_info(StreamChannel *channel, const StreamMsgInfo *info)
+{
+    channel->output_id = info->output_id;
+    RedChannel *red_channel = RED_CHANNEL(channel);
+    red_channel_pipes_add_type(red_channel, RED_PIPE_ITEM_TYPE_MONITORS_CONFIG);
+}
+
 static inline void
 stream_channel_update_queue_stat(StreamChannel *channel,
                                  int32_t num_diff, int32_t size_diff)
diff --git a/server/stream-channel.h b/server/stream-channel.h
index e8bec80b..83c73012 100644
--- a/server/stream-channel.h
+++ b/server/stream-channel.h
@@ -60,6 +60,7 @@ struct StreamMsgStartStop;
 
 void stream_channel_change_format(StreamChannel *channel,
                                   const struct StreamMsgFormat *fmt);
+void stream_channel_handle_stream_info(StreamChannel *channel, const struct StreamMsgInfo *info);
 void stream_channel_send_data(StreamChannel *channel,
                               const void *data, size_t size,
                               uint32_t mm_time);
diff --git a/spice-common b/spice-common
index 4c2d0e97..151fd26c 160000
--- a/spice-common
+++ b/spice-common
@@ -1 +1 @@
-Subproject commit 4c2d0e977272c5540634d24f485dd64c424f6748
+Subproject commit 151fd26ce7032c062c097deabfd003549ebb3cc8
-- 
2.17.1



More information about the Spice-devel mailing list