Otherwise it may get wrapped to a much lower value than intended. Signed-off-by: Francois Gouget <fgouget@xxxxxxxxxxxxxxx> --- server/gstreamer-encoder.c | 65 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/server/gstreamer-encoder.c b/server/gstreamer-encoder.c index 3c1e86e..bcf28e7 100644 --- a/server/gstreamer-encoder.c +++ b/server/gstreamer-encoder.c @@ -20,6 +20,8 @@ #include <config.h> #endif +#include <inttypes.h> + #include <gst/gst.h> #include <gst/app/gstappsrc.h> #include <gst/app/gstappsink.h> @@ -777,6 +779,65 @@ static gboolean create_pipeline(SpiceGstEncoder *encoder) return TRUE; } +/* A helper for configure_pipeline() */ +static void set_gstenc_bitrate(SpiceGstEncoder *encoder) +{ + GObjectClass *class = G_OBJECT_GET_CLASS(encoder->gstenc); + GParamSpec *param = g_object_class_find_property(class, "bitrate"); + if (param == NULL) { + param = g_object_class_find_property(class, "target-bitrate"); + } + if (param) { + uint64_t gst_bit_rate = encoder->video_bit_rate; + if (strstr(g_param_spec_get_blurb(param), "kbit")) { + gst_bit_rate = gst_bit_rate / 1024; + } + switch (param->value_type) { + case G_TYPE_ULONG: { + GParamSpecULong *range = G_PARAM_SPEC_ULONG(param); + gst_bit_rate = MAX(range->minimum, MIN(range->maximum, gst_bit_rate)); + break; + } + case G_TYPE_LONG: { + GParamSpecLong *range = G_PARAM_SPEC_LONG(param); + gst_bit_rate = MAX(range->minimum, MIN(range->maximum, gst_bit_rate)); + break; + } + case G_TYPE_UINT: { + GParamSpecUInt *range = G_PARAM_SPEC_UINT(param); + gst_bit_rate = MAX(range->minimum, MIN(range->maximum, gst_bit_rate)); + break; + } + case G_TYPE_INT: { + GParamSpecInt *range = G_PARAM_SPEC_INT(param); + gst_bit_rate = MAX(range->minimum, MIN(range->maximum, gst_bit_rate)); + break; + } + case G_TYPE_UINT64: { + GParamSpecUInt64 *range = G_PARAM_SPEC_UINT64(param); + gst_bit_rate = MAX(range->minimum, MIN(range->maximum, gst_bit_rate)); + break; + } + case G_TYPE_INT64: { + GParamSpecInt64 *range = G_PARAM_SPEC_INT64(param); + gst_bit_rate = MAX(range->minimum, MIN(range->maximum, gst_bit_rate)); + break; + } + default: + spice_debug("the %s property has an unsupported type %zu", + g_param_spec_get_name(param), param->value_type); + } + spice_debug("setting the GStreamer %s to %"PRIu64, + g_param_spec_get_name(param), gst_bit_rate); + g_object_set(G_OBJECT(encoder->gstenc), + g_param_spec_get_name(param), gst_bit_rate, + NULL); + } else { + spice_printerr("Could not find the bit rate property for %s", + get_gst_codec_name(encoder)); + } +} + /* A helper for spice_gst_encoder_encode_frame() */ static gboolean configure_pipeline(SpiceGstEncoder *encoder, const SpiceBitmap *bitmap) @@ -786,10 +847,10 @@ static gboolean configure_pipeline(SpiceGstEncoder *encoder, } /* Configure the encoder bitrate, frame latency, etc. */ + set_gstenc_bitrate(encoder); switch (encoder->base.codec_type) { case SPICE_VIDEO_CODEC_TYPE_MJPEG: g_object_set(G_OBJECT(encoder->gstenc), - "bitrate", encoder->video_bit_rate, "max-threads", 1, /* zero-frame latency */ NULL); @@ -807,7 +868,6 @@ static gboolean configure_pipeline(SpiceGstEncoder *encoder, g_object_set(G_OBJECT(encoder->gstenc), "resize-allowed", TRUE, /* for very low bit rates */ "min-quantizer", 10, /* seems virtually lossless */ - "target-bitrate", encoder->video_bit_rate, "end-usage", 1, /* CBR */ "lag-in-frames", 0, /* zero-frame latency */ "error-resilient", 1, /* for client frame drops */ @@ -818,7 +878,6 @@ static gboolean configure_pipeline(SpiceGstEncoder *encoder, } case SPICE_VIDEO_CODEC_TYPE_H264: g_object_set(G_OBJECT(encoder->gstenc), - "bitrate", encoder->video_bit_rate / 1024, "qp-min", 15, /* virtually lossless */ "byte-stream", TRUE, "aud", FALSE, -- 2.6.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel