[Spice-devel,v16,20/23] streaming: Dynamically adjust the GStreamer encoder bitrate if possible

Submitted by Francois Gouget on June 7, 2016, 2 p.m.

Details

Message ID ab95aa58b875e0f8a32d3e19c558024945e25c98.1465306176.git.fgouget@free.fr
State New
Headers show
Series "Add GStreamer support for video streaming" ( rev: 22 21 20 19 18 ) in Spice

Not browsing as part of any series.

Commit Message

Francois Gouget June 7, 2016, 2 p.m.
This is faster and lets the encoder leverage past bitrate shaping
history to attain the target faster.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
---
 server/gstreamer-encoder.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/server/gstreamer-encoder.c b/server/gstreamer-encoder.c
index b4facc9..b94656b 100644
--- a/server/gstreamer-encoder.c
+++ b/server/gstreamer-encoder.c
@@ -99,6 +99,9 @@  typedef struct SpiceGstEncoder {
     GstElement *gstenc;
     GParamSpec *gstenc_bitrate_param;
 
+    /* True if the encoder's bitrate can be modified while playing. */
+    gboolean gstenc_bitrate_is_dynamic;
+
     /* Pipeline parameters to modify before the next frame. */
 #   define SPICE_GST_VIDEO_PIPELINE_STATE    0x1
 #   define SPICE_GST_VIDEO_PIPELINE_BITRATE  0x2
@@ -473,9 +476,16 @@  static void add_frame(SpiceGstEncoder *encoder, uint32_t frame_mm_time,
 
 /* ---------- Encoder bit rate control ---------- */
 
+static void set_gstenc_bitrate(SpiceGstEncoder *encoder);
+
 static void set_video_bit_rate(SpiceGstEncoder *encoder, uint64_t bit_rate)
 {
-    if (abs(bit_rate - encoder->video_bit_rate) > encoder->video_bit_rate * SPICE_GST_VIDEO_BITRATE_MARGIN) {
+    if (encoder->video_bit_rate != bit_rate &&
+        encoder->gstenc_bitrate_is_dynamic) {
+        encoder->video_bit_rate = bit_rate;
+        set_gstenc_bitrate(encoder);
+
+    } else  if (abs(bit_rate - encoder->video_bit_rate) > encoder->video_bit_rate * SPICE_GST_VIDEO_BITRATE_MARGIN) {
         encoder->video_bit_rate = bit_rate;
         set_pipeline_changes(encoder, SPICE_GST_VIDEO_PIPELINE_BITRATE);
     }
@@ -945,7 +955,9 @@  static gboolean create_pipeline(SpiceGstEncoder *encoder)
     if (encoder->gstenc_bitrate_param == NULL) {
         encoder->gstenc_bitrate_param = g_object_class_find_property(class, "target-bitrate");
     }
-    if (!encoder->gstenc_bitrate_param) {
+    if (encoder->gstenc_bitrate_param) {
+        encoder->gstenc_bitrate_is_dynamic = (encoder->gstenc_bitrate_param->flags & GST_PARAM_MUTABLE_PLAYING);
+    } else {
         spice_warning("GStreamer error: could not find the %s bitrate parameter", gstenc_name);
     }