[RFC,v2,1/2] stream-channel: Use the preferred codec list instead of supported

Submitted by Kevin Pouget on Aug. 2, 2019, 1:10 p.m.

Details

Message ID 20190802131043.28274-1-kpouget@redhat.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in Spice

Not browsing as part of any series.

Commit Message

Kevin Pouget Aug. 2, 2019, 1:10 p.m.
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@redhat.com>
---
 server/stream-channel.c | 42 +++++++++++++++++++++++++++++++++--------
 1 file changed, 34 insertions(+), 8 deletions(-)

--
2.21.0

Patch hide | download patch | download mbox

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);