From: Victor Toso <me@xxxxxxxxxxxxxx> SPICE_MSGC_DISPLAY_PREFERRED_VIDEO_CODEC_TYPE can be used to set the preferred order of video codecs to be used based in client's preference. A new function is introduced in reds.c to update its video codec: reds_set_video_codecs_from_client_preferred_msg() - it only update the rank values of existing video codecs. It is important to note that this message will not _immediately_ change a ongoing streaming; It might change the video codec on newly created streams. Signed-off-by: Victor Toso <victortoso@xxxxxxxxxx> --- server/dcc.c | 13 +++++++++++++ server/red-worker.c | 1 + server/reds.c | 35 +++++++++++++++++++++++++++++++++++ server/reds.h | 3 +++ 4 files changed, 52 insertions(+) diff --git a/server/dcc.c b/server/dcc.c index 5c05c3b..c86f8db 100644 --- a/server/dcc.c +++ b/server/dcc.c @@ -1097,6 +1097,16 @@ static int dcc_handle_preferred_compression(DisplayChannelClient *dcc, return TRUE; } +static int dcc_handle_preferred_video_codec_type(DisplayChannelClient *dcc, + SpiceMsgcDisplayPreferredVideoCodecType *msg) +{ + RedsState *reds; + + reds = red_channel_get_server(red_channel_client_get_channel(&dcc->parent)); + reds_set_video_codecs_from_client_preferred_msg(reds, msg->codec_ranks, msg->num_of_codecs); + return TRUE; +} + static int dcc_handle_gl_draw_done(DisplayChannelClient *dcc) { DisplayChannel *display = DCC_TO_DC(dcc); @@ -1127,6 +1137,9 @@ int dcc_handle_message(RedChannelClient *rcc, uint32_t size, uint16_t type, void (SpiceMsgcDisplayPreferredCompression *)msg); case SPICE_MSGC_DISPLAY_GL_DRAW_DONE: return dcc_handle_gl_draw_done(dcc); + case SPICE_MSGC_DISPLAY_PREFERRED_VIDEO_CODEC_TYPE: + return dcc_handle_preferred_video_codec_type(dcc, + (SpiceMsgcDisplayPreferredVideoCodecType *)msg); default: return red_channel_client_handle_message(rcc, size, type, msg); } diff --git a/server/red-worker.c b/server/red-worker.c index 40e58f2..8e8be5b 100644 --- a/server/red-worker.c +++ b/server/red-worker.c @@ -1384,6 +1384,7 @@ RedWorker* red_worker_new(QXLInstance *qxl, red_channel_register_client_cbs(channel, client_display_cbs, dispatcher); red_channel_set_cap(channel, SPICE_DISPLAY_CAP_MONITORS_CONFIG); red_channel_set_cap(channel, SPICE_DISPLAY_CAP_PREF_COMPRESSION); + red_channel_set_cap(channel, SPICE_DISPLAY_CAP_PREF_VIDEO_CODEC_TYPE); red_channel_set_cap(channel, SPICE_DISPLAY_CAP_STREAM_REPORT); reds_register_channel(reds, channel); diff --git a/server/reds.c b/server/reds.c index 6dbc010..28acddd 100644 --- a/server/reds.c +++ b/server/reds.c @@ -3649,6 +3649,41 @@ static void reds_set_video_codecs(RedsState *reds, GArray *video_codecs) reds->config->video_codecs = video_codecs; } +void reds_set_video_codecs_from_client_preferred_msg(RedsState *reds, + SpiceVideoCodecPreferredRank *codec_ranks, guint32 codec_ranks_len) +{ + gint i; + GArray *video_codecs; + + /* Dup the current array */ + video_codecs = g_array_new(FALSE, FALSE, sizeof(RedVideoCodec)); + for (i = 0; i < reds->config->video_codecs->len; i++) { + RedVideoCodec codec = g_array_index(reds->config->video_codecs, RedVideoCodec, i); + + /* Only one type of codec should be set as preferred - reset to sofware decoder */ + if (codec.rank == SPICE_VIDEO_CODEC_RANK_PREFERRED) + codec.rank = SPICE_VIDEO_CODEC_RANK_SOFTWARE_DECODER; + + g_array_append_val(video_codecs, codec); + } + + /* Update the rank based in the information given by client */ + for (i = 0; i < codec_ranks_len; i++) { + gint j; + + for (j = 0; j < video_codecs->len; j++) { + RedVideoCodec *codec = &g_array_index(video_codecs, RedVideoCodec, j); + + if (codec_ranks[i].type != codec->type) + continue; + + codec->rank = codec_ranks[i].rank; + } + } + reds_set_video_codecs(reds, video_codecs); + reds_on_vc_change(reds); +} + static void reds_set_video_codecs_from_string(RedsState *reds, const char *codecs) { char *encoder_name, *codec_name, *codec_rank; diff --git a/server/reds.h b/server/reds.h index cd62fc1..e3afe42 100644 --- a/server/reds.h +++ b/server/reds.h @@ -94,6 +94,9 @@ void reds_on_main_channel_migrate(RedsState *reds, MainChannelClient *mcc); void reds_set_client_mm_time_latency(RedsState *reds, RedClient *client, uint32_t latency); uint32_t reds_get_streaming_video(const RedsState *reds); GArray* reds_get_video_codecs(const RedsState *reds); +void reds_set_video_codecs_from_client_preferred_msg(RedsState *reds, + SpiceVideoCodecPreferredRank *codec_ranks, + guint32 codec_ranks_len); spice_wan_compression_t reds_get_jpeg_state(const RedsState *reds); spice_wan_compression_t reds_get_zlib_glz_state(const RedsState *reds); SpiceCoreInterfaceInternal* reds_get_core_interface(RedsState *reds); -- 2.9.3 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel