[Spice-devel] [PATCH] reds: Add ability to query the video-codecs currently enabled
Frediano Ziglio
fziglio at redhat.com
Fri Jul 5 10:12:22 UTC 2019
> spice_server_get_video_codecs: new public function to query the video
> encoders/codecs currently enabled in the spice server. It returns a
> string that can be fed to the setter counter
> (spice_server_set_video_codecs). The string returned by this function
> should be released with spice_server_free_video_codecs.
>
> spice_server_free_video_codecs: new public function to free the the
> video codec list returned by spice_server_get_video_codecs.
>
> video_codecs_to_string: new private function to transform an array of
> RedVideoCodec into a string.
>
> Signed-off-by: Kevin Pouget <kpouget at redhat.com>
Acked-by: Frediano Ziglio <fziglio at redhat.com>
> ---
>
> resending with Frediano's fixes applied
>
> ---
> server/dcc.c | 13 ++++---------
> server/reds.c | 38 ++++++++++++++++++++++++++++++++++++++
> server/reds.h | 2 ++
> server/spice-server.h | 16 ++++++++++++++++
> server/spice-server.syms | 6 ++++++
> server/video-encoder.h | 2 ++
> server/video-stream.c | 23 +++++++++++++++++++++++
> 7 files changed, 91 insertions(+), 9 deletions(-)
>
> diff --git a/server/dcc.c b/server/dcc.c
> index bd393e04..b364a8e1 100644
> --- a/server/dcc.c
> +++ b/server/dcc.c
> @@ -1120,9 +1120,8 @@ static gint
> sort_video_codecs_by_client_preference(gconstpointer a_pointer,
>
> static void dcc_update_preferred_video_codecs(DisplayChannelClient *dcc)
> {
> - guint i;
> GArray *video_codecs, *server_codecs;
> - GString *msg;
> + char *codecs_str;
>
> server_codecs = display_channel_get_video_codecs(DCC_TO_DC(dcc));
> spice_return_if_fail(server_codecs != NULL);
> @@ -1137,13 +1136,9 @@ static void
> dcc_update_preferred_video_codecs(DisplayChannelClient *dcc)
> g_clear_pointer(&dcc->priv->preferred_video_codecs, g_array_unref);
> dcc->priv->preferred_video_codecs = video_codecs;
>
> - msg = g_string_new("Preferred video-codecs:");
> - for (i = 0; i < video_codecs->len; i++) {
> - RedVideoCodec codec = g_array_index(video_codecs, RedVideoCodec, i);
> - g_string_append_printf(msg, " %d", codec.type);
> - }
> - spice_debug("%s", msg->str);
> - g_string_free(msg, TRUE);
> + codecs_str = video_codecs_to_string(video_codecs, " ");
> + spice_debug("Preferred video-codecs: %s", codecs_str);
> + g_free(codecs_str);
> }
>
> static void on_display_video_codecs_update(GObject *gobject, GParamSpec
> *pspec, gpointer user_data)
> diff --git a/server/reds.c b/server/reds.c
> index aabfe919..7783ab0b 100644
> --- a/server/reds.c
> +++ b/server/reds.c
> @@ -3708,6 +3708,16 @@ static gboolean get_name_index(const EnumNames
> names[], const char *name, uint32
> return FALSE;
> }
>
> +/* returns NULL if index is invalid. */
> +static const char *get_index_name(const EnumNames names[], uint32_t index)
> +{
> + while (names->name != NULL && names->id != index) {
> + names++;
> + }
> +
> + return names->name;
> +}
> +
> static const EnumNames renderer_names[] = {
> {RED_RENDERER_SW, "sw"},
> {RED_RENDERER_INVALID, NULL},
> @@ -3755,6 +3765,24 @@ static const int video_codec_caps[] = {
> SPICE_DISPLAY_CAP_CODEC_VP9,
> };
>
> +char *reds_get_video_codec_fullname(RedVideoCodec *codec)
> +{
> + int i;
> + const char *encoder_name = NULL;
> + const char *codec_name = get_index_name(video_codec_names, codec->type);
> +
> + spice_assert(codec_name);
> +
> + for (i = 0; i < G_N_ELEMENTS(video_encoder_procs); i++) {
> + if (video_encoder_procs[i] == codec->create) {
> + encoder_name = get_index_name(video_encoder_names, i);
> + break;
> + }
> + }
> + spice_assert(encoder_name);
> +
> + return g_strdup_printf("%s:%s", encoder_name, codec_name);
> +}
>
> /* Parses the given codec string and returns newly-allocated strings
> describing
> * the next encoder and codec in the list. These strings must be freed by
> the
> @@ -4223,6 +4251,16 @@ SPICE_GNUC_VISIBLE int
> spice_server_set_video_codecs(SpiceServer *reds, const ch
> return 0;
> }
>
> +SPICE_GNUC_VISIBLE const char *spice_server_get_video_codecs(SpiceServer
> *reds)
> +{
> + return video_codecs_to_string(reds_get_video_codecs(reds), ";");
> +}
> +
> +SPICE_GNUC_VISIBLE void spice_server_free_video_codecs(SpiceServer *reds,
> const char *video_codecs)
> +{
> + g_free((char *) video_codecs);
> +}
> +
> GArray* reds_get_video_codecs(const RedsState *reds)
> {
> return reds->config->video_codecs;
> diff --git a/server/reds.h b/server/reds.h
> index 8c5ee84d..e3355f81 100644
> --- a/server/reds.h
> +++ b/server/reds.h
> @@ -27,6 +27,7 @@
> #include "char-device.h"
> #include "spice.h"
> #include "red-channel.h"
> +#include "video-encoder.h"
> #include "main-dispatcher.h"
> #include "migration-protocol.h"
>
> @@ -54,6 +55,7 @@ void reds_send_device_display_info(RedsState *reds);
> void reds_handle_agent_mouse_event(RedsState *reds, const VDAgentMouseState
> *mouse_state); // used by inputs_channel
>
> GArray* reds_get_renderers(RedsState *reds);
> +char *reds_get_video_codec_fullname(RedVideoCodec *codec);
>
> enum {
> RED_RENDERER_INVALID,
> diff --git a/server/spice-server.h b/server/spice-server.h
> index 5f572f4f..c6c8646a 100644
> --- a/server/spice-server.h
> +++ b/server/spice-server.h
> @@ -136,6 +136,22 @@ enum {
> };
>
> int spice_server_set_video_codecs(SpiceServer *s, const char* video_codecs);
> +
> +/**
> + * Returns a newly allocated string describing video encoders/codecs
> + * currently allowed in @s Spice server. The string returned by
> + * this function must be released with spice_server_free_video_codecs.
> + *
> + * @s: the Spice server to query
> + * @return the string describing the video encoders/codecs currently enabled
> + */
> +const char *spice_server_get_video_codecs(SpiceServer *s);
> +
> +/**
> + * Releases the memory of the video-codec string returned by
> + * spice_server_get_video_codecs.
> + */
> +void spice_server_free_video_codecs(SpiceServer *s, const char
> *video_codecs);
> int spice_server_set_playback_compression(SpiceServer *s, int enable);
> int spice_server_set_agent_mouse(SpiceServer *s, int enable);
> int spice_server_set_agent_copypaste(SpiceServer *s, int enable);
> diff --git a/server/spice-server.syms b/server/spice-server.syms
> index ac4d9b14..e33526f3 100644
> --- a/server/spice-server.syms
> +++ b/server/spice-server.syms
> @@ -178,3 +178,9 @@ SPICE_SERVER_0.14.2 {
> global:
> spice_qxl_set_device_info;
> } SPICE_SERVER_0.13.2;
> +
> +SPICE_SERVER_0.14.3 {
> +global:
> + spice_server_get_video_codecs;
> + spice_server_free_video_codecs;
> +} SPICE_SERVER_0.14.2;
> diff --git a/server/video-encoder.h b/server/video-encoder.h
> index 71f4131a..90d21312 100644
> --- a/server/video-encoder.h
> +++ b/server/video-encoder.h
> @@ -213,4 +213,6 @@ typedef struct RedVideoCodec {
> uint32_t cap;
> } RedVideoCodec;
>
> +char *video_codecs_to_string(GArray *video_codecs, const char *sep);
> +
> #endif /* VIDEO_ENCODER_H_ */
> diff --git a/server/video-stream.c b/server/video-stream.c
> index 4ac25af8..6aa859a0 100644
> --- a/server/video-stream.c
> +++ b/server/video-stream.c
> @@ -970,3 +970,26 @@ void video_stream_trace_add_drawable(DisplayChannel
> *display,
> trace->height = src_area->bottom - src_area->top;
> trace->dest_area = item->red_drawable->bbox;
> }
> +
> +/*
> + * video_codecs: an array of RedVideoCodec
> + * sep: a string for separating the list elements
> + *
> + * returns a string of "enc:codec<sep>"* that must be released
> + * with g_free.
> + */
> +char *video_codecs_to_string(GArray *video_codecs, const char *sep)
> +{
> + int i;
> + GString *msg = g_string_new("");
> +
> + for (i = 0; i < video_codecs->len; i++) {
> + RedVideoCodec codec = g_array_index(video_codecs, RedVideoCodec, i);
> + char *codec_name = reds_get_video_codec_fullname(&codec);
> +
> + g_string_append_printf(msg, "%s%s", i ? sep : "", codec_name);
> + g_free(codec_name);
> + }
> +
> + return g_string_free(msg, FALSE);
> +}
More information about the Spice-devel
mailing list