[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