[Spice-devel] [RFC v2 1/2] stream-channel: Use the preferred codec list instead of supported
Kevin Pouget
kpouget at redhat.com
Fri Aug 2 13:10:42 UTC 2019
This patch computes and sends the list of the video codecs preferred
by all the clients when requesting to start a new video stream.
It used to be the list of the supported codecs.
The MJPEG codec is used as a fallback is there if no codec preferred
by all the clients.
Signed-off-by: Kevin Pouget <kpouget at redhat.com>
---
server/stream-channel.c | 42 +++++++++++++++++++++++++++++++++--------
1 file changed, 34 insertions(+), 8 deletions(-)
diff --git a/server/stream-channel.c b/server/stream-channel.c
index 7953018e..ae5d7b81 100644
--- a/server/stream-channel.c
+++ b/server/stream-channel.c
@@ -346,9 +346,9 @@ stream_channel_new(RedsState *server, uint32_t id)
#define MAX_SUPPORTED_CODECS SPICE_VIDEO_CODEC_TYPE_ENUM_END
-// find common codecs supported by all clients
+// find common codecs preferred by all clients
static uint8_t
-stream_channel_get_supported_codecs(StreamChannel *channel, uint8_t *out_codecs)
+stream_channel_get_preferred_codecs(StreamChannel *channel, uint8_t *out_codecs)
{
RedChannelClient *rcc;
int codec;
@@ -369,17 +369,38 @@ stream_channel_get_supported_codecs(StreamChannel *channel, uint8_t *out_codecs)
}
FOREACH_CLIENT(channel, rcc) {
+ RedChannel *red_channel = red_channel_client_get_channel(rcc);
+ RedsState *reds = red_channel_get_server(red_channel);
+ GArray *preferred_codecs = reds_get_video_codecs(reds);
+
for (codec = 1; codec < SPICE_N_ELEMENTS(codec2cap); ++codec) {
- // if do not support codec delete from list
+ // skip the codec if it is already not supported
+ if (!supported[codec]) {
+ continue;
+ }
+
+ // delete the codec from the list if it's not supported
if (!red_channel_client_test_remote_cap(rcc, codec2cap[codec])) {
supported[codec] = false;
+ continue;
+ }
+
+ // delete the codec from the list if it's not in the preferred list
+ bool preferred_has_codec = false;
+ int i;
+
+ for (i = 0; i < preferred_codecs->len; i++) {
+ RedVideoCodec pref_codec = g_array_index(preferred_codecs, RedVideoCodec, i);
+
+ if (pref_codec.type == codec) {
+ preferred_has_codec = true;
+ break;
+ }
}
+ supported[codec] = preferred_has_codec;
}
}
- // surely mjpeg is supported
- supported[SPICE_VIDEO_CODEC_TYPE_MJPEG] = true;
-
int num = 0;
for (codec = 1; codec < SPICE_N_ELEMENTS(codec2cap); ++codec) {
if (supported[codec]) {
@@ -387,6 +408,11 @@ stream_channel_get_supported_codecs(StreamChannel *channel, uint8_t *out_codecs)
}
}
+ if (num == 0) {
+ // surely mjpeg is supported
+ supported[SPICE_VIDEO_CODEC_TYPE_MJPEG] = true;
+ }
+
return num;
}
@@ -408,7 +434,7 @@ stream_channel_connect(RedChannel *red_channel, RedClient *red_client, RedStream
spice_return_if_fail(client != NULL);
// request new stream
- start->num_codecs = stream_channel_get_supported_codecs(channel, start->codecs);
+ start->num_codecs = stream_channel_get_preferred_codecs(channel, start->codecs);
// send in any case, even if list is not changed
// notify device about changes
request_new_stream(channel, start);
@@ -607,7 +633,7 @@ stream_channel_reset(StreamChannel *channel)
// try to request a new stream, this should start a new stream
// if the guest is connected to the device and a client is already connected
- start->num_codecs = stream_channel_get_supported_codecs(channel, start->codecs);
+ start->num_codecs = stream_channel_get_preferred_codecs(channel, start->codecs);
// send in any case, even if list is not changed
// notify device about changes
request_new_stream(channel, start);
--
2.21.0
More information about the Spice-devel
mailing list