> > This patch enables the SPICE_DISPLAY_CAP_PREF_VIDEO_CODEC_TYPE > capability for the stream-channel. > > video_stream_parse_preferred_codecs: new function for parsing the > SPICE protocol message. This code used to in inside > dcc_handle_preferred_video_codec_type. > > struct StreamChannelClient::client_preferred_video_codecs: new field. > > Signed-off-by: Kevin Pouget <kpouget@xxxxxxxxxx> Acked > --- > v1->v2: > - removed extra header (red-client.h) > - s/scc/client > > --- > server/dcc.c | 30 +----------------------------- > server/stream-channel.c | 38 ++++++++++++++++++++++++++++++++++++++ > server/video-stream.c | 35 +++++++++++++++++++++++++++++++++++ > server/video-stream.h | 1 + > 4 files changed, 75 insertions(+), 29 deletions(-) > > diff --git a/server/dcc.c b/server/dcc.c > index 21e8598e..538f1f51 100644 > --- a/server/dcc.c > +++ b/server/dcc.c > @@ -1158,38 +1158,10 @@ static void on_display_video_codecs_update(GObject > *gobject, GParamSpec *pspec, > static int dcc_handle_preferred_video_codec_type(DisplayChannelClient *dcc, > SpiceMsgcDisplayPreferredVideoCodecType > *msg) > { > - gint i, len; > - gint indexes[SPICE_VIDEO_CODEC_TYPE_ENUM_END]; > - GArray *client; > - > g_return_val_if_fail(msg->num_of_codecs > 0, TRUE); > > - /* set default to a big and positive number */ > - memset(indexes, 0x7f, sizeof(indexes)); > - > - for (len = 0, i = 0; i < msg->num_of_codecs; i++) { > - gint video_codec = msg->codecs[i]; > - > - if (video_codec < SPICE_VIDEO_CODEC_TYPE_MJPEG || > - video_codec >= SPICE_VIDEO_CODEC_TYPE_ENUM_END) { > - spice_debug("Client has sent unknown video-codec (value %d at > index %d). " > - "Ignoring as server can't handle it", > - video_codec, i); > - continue; > - } > - > - if (indexes[video_codec] < SPICE_VIDEO_CODEC_TYPE_ENUM_END) { > - continue; > - } > - > - len++; > - indexes[video_codec] = len; > - } > - client = g_array_sized_new(FALSE, FALSE, sizeof(gint), > SPICE_VIDEO_CODEC_TYPE_ENUM_END); > - g_array_append_vals(client, indexes, SPICE_VIDEO_CODEC_TYPE_ENUM_END); > - > g_clear_pointer(&dcc->priv->client_preferred_video_codecs, > g_array_unref); > - dcc->priv->client_preferred_video_codecs = client; > + dcc->priv->client_preferred_video_codecs = > video_stream_parse_preferred_codecs(msg); > > /* New client preference */ > dcc_update_preferred_video_codecs(dcc); > diff --git a/server/stream-channel.c b/server/stream-channel.c > index 7953018e..cc0eae5d 100644 > --- a/server/stream-channel.c > +++ b/server/stream-channel.c > @@ -52,6 +52,9 @@ struct StreamChannelClient { > /* current video stream id, <0 if not initialized or > * we are not sending a stream */ > int stream_id; > + /* Array with SPICE_VIDEO_CODEC_TYPE_ENUM_END elements, with the client > + * preference order (index) as value */ > + GArray *client_preferred_video_codecs; > }; > > struct StreamChannelClientClass { > @@ -114,15 +117,30 @@ typedef struct StreamDataItem { > #define PRIMARY_SURFACE_ID 0 > > static void stream_channel_client_on_disconnect(RedChannelClient *rcc); > +static bool > +stream_channel_handle_preferred_video_codec_type(RedChannelClient *rcc, > + > SpiceMsgcDisplayPreferredVideoCodecType > *msg); > > RECORDER(stream_channel_data, 32, "Stream channel data packet"); > > +static void > +stream_channel_client_finalize(GObject *object) > +{ > + StreamChannelClient *self = STREAM_CHANNEL_CLIENT(object); > + g_clear_pointer(&self->client_preferred_video_codecs, g_array_unref); > + > + G_OBJECT_CLASS(stream_channel_client_parent_class)->finalize(object); > +} > + > static void > stream_channel_client_class_init(StreamChannelClientClass *klass) > { > + GObjectClass *object_class = G_OBJECT_CLASS(klass); > + > RedChannelClientClass *channel_class = RED_CHANNEL_CLIENT_CLASS(klass); > > channel_class->on_disconnect = stream_channel_client_on_disconnect; > + object_class->finalize = stream_channel_client_finalize; > } > > static void > @@ -324,6 +342,9 @@ handle_message(RedChannelClient *rcc, uint16_t type, > uint32_t size, void *msg) > case SPICE_MSGC_DISPLAY_GL_DRAW_DONE: > /* client should not send this message */ > return false; > + case SPICE_MSGC_DISPLAY_PREFERRED_VIDEO_CODEC_TYPE: > + return stream_channel_handle_preferred_video_codec_type(rcc, > + (SpiceMsgcDisplayPreferredVideoCodecType *)msg); > default: > return red_channel_client_handle_message(rcc, type, size, msg); > } > @@ -390,6 +411,22 @@ stream_channel_get_supported_codecs(StreamChannel > *channel, uint8_t *out_codecs) > return num; > } > > +static bool > +stream_channel_handle_preferred_video_codec_type(RedChannelClient *rcc, > + > SpiceMsgcDisplayPreferredVideoCodecType > *msg) > +{ > + StreamChannelClient *client = STREAM_CHANNEL_CLIENT(rcc); > + > + if (msg->num_of_codecs == 0) { > + return true; > + } > + > + g_clear_pointer(&client->client_preferred_video_codecs, g_array_unref); > + client->client_preferred_video_codecs = > video_stream_parse_preferred_codecs(msg); > + > + return true; > +} > + > static void > stream_channel_connect(RedChannel *red_channel, RedClient *red_client, > RedStream *stream, > int migration, RedChannelCapabilities *caps) > @@ -448,6 +485,7 @@ stream_channel_constructed(GObject *object) > > red_channel_set_cap(red_channel, SPICE_DISPLAY_CAP_MONITORS_CONFIG); > red_channel_set_cap(red_channel, SPICE_DISPLAY_CAP_STREAM_REPORT); > + red_channel_set_cap(red_channel, > SPICE_DISPLAY_CAP_PREF_VIDEO_CODEC_TYPE); > > reds_register_channel(reds, red_channel); > } > diff --git a/server/video-stream.c b/server/video-stream.c > index 6aa859a0..6714d780 100644 > --- a/server/video-stream.c > +++ b/server/video-stream.c > @@ -468,6 +468,41 @@ static bool video_stream_add_frame(DisplayChannel > *display, > return FALSE; > } > > +/* Returns an array with SPICE_VIDEO_CODEC_TYPE_ENUM_END elements, > + * with the client preference order (index) as value */ > +GArray > *video_stream_parse_preferred_codecs(SpiceMsgcDisplayPreferredVideoCodecType > *msg) > +{ > + int i, len; > + int indexes[SPICE_VIDEO_CODEC_TYPE_ENUM_END]; > + GArray *client; > + > + /* set default to a big and positive number */ > + memset(indexes, 0x7f, sizeof(indexes)); > + > + for (len = 0, i = 0; i < msg->num_of_codecs; i++) { > + SpiceVideoCodecType video_codec = msg->codecs[i]; > + > + if (video_codec < SPICE_VIDEO_CODEC_TYPE_MJPEG || > + video_codec >= SPICE_VIDEO_CODEC_TYPE_ENUM_END) { > + spice_debug("Client has sent unknown video-codec (value %d at > index %d). " > + "Ignoring as server can't handle it", > + video_codec, i); > + continue; > + } > + > + if (indexes[video_codec] < SPICE_VIDEO_CODEC_TYPE_ENUM_END) { > + continue; > + } > + > + len++; > + indexes[video_codec] = len; > + } > + client = g_array_sized_new(FALSE, FALSE, sizeof(int), > SPICE_VIDEO_CODEC_TYPE_ENUM_END); > + g_array_append_vals(client, indexes, SPICE_VIDEO_CODEC_TYPE_ENUM_END); > + > + return client; > +} > + > /* TODO: document the difference between the 2 functions below */ > void video_stream_trace_update(DisplayChannel *display, Drawable *drawable) > { > diff --git a/server/video-stream.h b/server/video-stream.h > index 46b076fd..73435515 100644 > --- a/server/video-stream.h > +++ b/server/video-stream.h > @@ -147,6 +147,7 @@ void video_stream_detach_and_stop(DisplayChannel > *display); > void video_stream_trace_add_drawable(DisplayChannel *display, Drawable > *item); > void video_stream_detach_behind(DisplayChannel *display, QRegion *region, > Drawable *drawable); > +GArray > *video_stream_parse_preferred_codecs(SpiceMsgcDisplayPreferredVideoCodecType > *msg); > > void video_stream_agent_unref(DisplayChannel *display, VideoStreamAgent > *agent); > void video_stream_agent_stop(VideoStreamAgent *agent); _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel