videoconvertscale: Add properties to disable scaling/converting in videoconvert/video...
authorThibault Saunier <tsaunier@igalia.com>
Thu, 14 Apr 2022 13:48:14 +0000 (09:48 -0400)
committerThibault Saunier <tsaunier@igalia.com>
Wed, 20 Apr 2022 21:09:20 +0000 (17:09 -0400)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/898>

subprojects/gst-devtools/validate/launcher/testsuites/check.py
subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json
subprojects/gst-plugins-base/gst/videoconvertscale/gstvideoconvert.c
subprojects/gst-plugins-base/gst/videoconvertscale/gstvideoconvertscale.c
subprojects/gst-plugins-base/gst/videoconvertscale/gstvideoconvertscale.h
subprojects/gst-plugins-base/gst/videoconvertscale/gstvideoscale.c
subprojects/gst-plugins-base/tests/validate/convertscale/convert_disable_scale.validatetest [new file with mode: 0644]
subprojects/gst-plugins-base/tests/validate/convertscale/convert_disable_scale/flow-expectations/log-converter-src-expected [new file with mode: 0644]
subprojects/gst-plugins-base/tests/validate/convertscale/scale_disable_convert.validatetest [new file with mode: 0644]
subprojects/gst-plugins-base/tests/validate/convertscale/scale_disable_convert/flow-expectations/log-scaler-src-expected [new file with mode: 0644]
subprojects/gst-plugins-base/tests/validate/meson.build

index e4c884d..551e697 100644 (file)
@@ -112,7 +112,9 @@ VALGRIND_BLACKLIST = [
     (r'check.gst-editing-services.pythontests', 'Need to figure out how to introduce python suppressions'),
     (r'check.gst-editing-services.check_keyframes_in_compositor_two_sources', 'Valgrind exit with an exitcode 20 but shows no issue: https://gitlab.freedesktop.org/thiblahute/gst-editing-services/-/jobs/4079972'),
     (r'check.gst-plugins-good.elements_splitmuxsrc.test_splitmuxsrc_sparse_streams', 'https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/739'),
-    (r'check.gst-plugins-good.elements_udpsrc.test_udpsrc_empty_packet', 'https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/740')
+    (r'check.gst-plugins-good.elements_udpsrc.test_udpsrc_empty_packet', 'https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/740'),
+    (r'check.gst-plugins-base.validate.convertscale.scale_disable_convert', 'Use of uninitialised value of size 8 in digest_to_string that needs investigating'),
+    (r'check.gst-plugins-base.validate.convertscale.convert_disable_scale', 'Use of uninitialised value of size 8 in digest_to_string that needs investigating'),
 ]
 
 
index 6827f94..a466734 100644 (file)
                         "presence": "always"
                     }
                 },
+                "properties": {
+                    "disable-scaling": {
+                        "blurb": "Disables frame scaling",
+                        "conditionally-available": false,
+                        "construct": true,
+                        "construct-only": false,
+                        "controllable": false,
+                        "default": "false",
+                        "mutable": "ready",
+                        "readable": true,
+                        "type": "gboolean",
+                        "writable": true
+                    }
+                },
                 "rank": "marginal"
             },
             "videoconvertscale": {
                     }
                 },
                 "properties": {
+                    "disable-conversion": {
+                        "blurb": "Disables colorspace conversions",
+                        "conditionally-available": false,
+                        "construct": true,
+                        "construct-only": false,
+                        "controllable": false,
+                        "default": "false",
+                        "mutable": "ready",
+                        "readable": true,
+                        "type": "gboolean",
+                        "writable": true
+                    },
                     "gamma-decode": {
                         "blurb": "Decode gamma before scaling",
                         "conditionally-available": false,
index ff8b4f1..5aae71d 100644 (file)
@@ -46,10 +46,65 @@ G_DEFINE_TYPE (GstVideoConvert, gst_video_convert,
 GST_ELEMENT_REGISTER_DEFINE (videoconvert, "videoconvert",
     GST_RANK_MARGINAL, gst_video_convert_get_type ());
 
+enum
+{
+  PROP_0,
+  PROP_DISABLE_SCALING,
+};
+
+#define DEFAULT_PROP_DISABLE_SCALING FALSE
+
+static void
+gst_video_convert_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  switch (prop_id) {
+    case PROP_DISABLE_SCALING:
+      g_value_set_boolean (value,
+          !gst_video_convert_scale_get_scales (GST_VIDEO_CONVERT_SCALE
+              (object)));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_video_convert_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  switch (prop_id) {
+    case PROP_DISABLE_SCALING:
+      gst_video_convert_scale_set_scales (GST_VIDEO_CONVERT_SCALE (object),
+          !g_value_get_boolean (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
 static void
 gst_video_convert_class_init (GstVideoConvertClass * klass)
 {
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+
+  gobject_class->set_property = gst_video_convert_set_property;
+  gobject_class->get_property = gst_video_convert_get_property;
+
   ((GstVideoConvertScaleClass *) klass)->any_memory = TRUE;
+
+  /**
+   * videoconvert::disable-scaling:
+   *
+   * Since: 1.22
+   */
+  g_object_class_install_property (gobject_class, PROP_DISABLE_SCALING,
+      g_param_spec_boolean ("disable-scaling", "Disable Scaling",
+          "Disables frame scaling", DEFAULT_PROP_DISABLE_SCALING,
+          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
 }
 
 static void
index a5d9b52..c418125 100644 (file)
@@ -107,6 +107,9 @@ typedef struct
 
   gint borders_h;
   gint borders_w;
+
+  gboolean scales;
+  gboolean converts;
 } GstVideoConvertScalePrivate;
 
 #define gst_video_convert_scale_parent_class parent_class
@@ -115,7 +118,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (GstVideoConvertScale, gst_video_convert_scale,
 GST_ELEMENT_REGISTER_DEFINE (videoconvertscale, "videoconvertscale",
     GST_RANK_SECONDARY, GST_TYPE_VIDEO_CONVERT_SCALE);
 
-#define PRIV(self) gst_video_convert_scale_get_instance_private(((GstVideoConvertScale*) self))
+#define PRIV(self) ((GstVideoConvertScalePrivate*)gst_video_convert_scale_get_instance_private(((GstVideoConvertScale*) self)))
 
 #define GST_CAT_DEFAULT video_convertscale_debug
 GST_DEBUG_CATEGORY_STATIC (video_convertscale_debug);
@@ -426,6 +429,8 @@ gst_video_convert_scale_init (GstVideoConvertScale * self)
   priv->matrix_mode = DEFAULT_PROP_MATRIX_MODE;
   priv->gamma_mode = DEFAULT_PROP_GAMMA_MODE;
   priv->primaries_mode = DEFAULT_PROP_PRIMARIES_MODE;
+  priv->scales = TRUE;
+  priv->converts = TRUE;
 }
 
 static void
@@ -569,12 +574,14 @@ gst_video_convert_scale_get_property (GObject * object, guint prop_id,
 }
 
 static GstCaps *
-gst_video_convert_caps_remove_format_and_rangify_size_info (GstCaps * caps)
+gst_video_convert_caps_remove_format_and_rangify_size_info (GstVideoConvertScale
+    * self, GstCaps * caps)
 {
   GstCaps *ret;
   GstStructure *structure;
   GstCapsFeatures *features;
   gint i, n;
+  GstVideoConvertScalePrivate *priv = PRIV (self);
 
   ret = gst_caps_new_empty ();
 
@@ -596,15 +603,21 @@ gst_video_convert_caps_remove_format_and_rangify_size_info (GstCaps * caps)
             || gst_caps_features_is_equal (features, features_format_interlaced)
             || gst_caps_features_is_equal (features,
                 features_format_interlaced_sysmem))) {
-      gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
-          "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
-      /* if pixel aspect ratio, make a range of it */
-      if (gst_structure_has_field (structure, "pixel-aspect-ratio")) {
-        gst_structure_set (structure, "pixel-aspect-ratio",
-            GST_TYPE_FRACTION_RANGE, 1, G_MAXINT, G_MAXINT, 1, NULL);
+
+      if (priv->scales) {
+        gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
+            "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
+        /* if pixel aspect ratio, make a range of it */
+        if (gst_structure_has_field (structure, "pixel-aspect-ratio")) {
+          gst_structure_set (structure, "pixel-aspect-ratio",
+              GST_TYPE_FRACTION_RANGE, 1, G_MAXINT, G_MAXINT, 1, NULL);
+        }
+      }
+
+      if (priv->converts) {
+        gst_structure_remove_fields (structure, "format", "colorimetry",
+            "chroma-site", NULL);
       }
-      gst_structure_remove_fields (structure, "format", "colorimetry",
-          "chroma-site", NULL);
     }
     gst_caps_append_structure_full (ret, structure,
         gst_caps_features_copy (features));
@@ -619,12 +632,13 @@ gst_video_convert_scale_transform_caps (GstBaseTransform * trans,
 {
   gint i;
   GstCaps *ret;
+  GstVideoConvertScale *self = GST_VIDEO_CONVERT_SCALE (trans);
 
   GST_DEBUG_OBJECT (trans,
       "Transforming caps %" GST_PTR_FORMAT " in direction %s", caps,
       (direction == GST_PAD_SINK) ? "sink" : "src");
 
-  ret = gst_video_convert_caps_remove_format_and_rangify_size_info (caps);
+  ret = gst_video_convert_caps_remove_format_and_rangify_size_info (self, caps);
   if (filter) {
     GstCaps *intersection;
 
@@ -1769,3 +1783,39 @@ gst_video_convert_scale_src_event (GstBaseTransform * trans, GstEvent * event)
 
   return ret;
 }
+
+void
+gst_video_convert_scale_set_scales (GstVideoConvertScale * self,
+    gboolean scales)
+{
+  GstVideoConvertScalePrivate *priv = PRIV (self);
+
+  if (!scales)
+    g_assert (priv->converts);
+
+  priv->scales = scales;
+}
+
+void
+gst_video_convert_scale_set_converts (GstVideoConvertScale * self,
+    gboolean converts)
+{
+  GstVideoConvertScalePrivate *priv = PRIV (self);
+
+  if (!converts)
+    g_assert (priv->scales);
+
+  priv->converts = converts;
+}
+
+gboolean
+gst_video_convert_scale_get_scales (GstVideoConvertScale * self)
+{
+  return PRIV (self)->scales;
+}
+
+gboolean
+gst_video_convert_scale_get_converts (GstVideoConvertScale * self)
+{
+  return PRIV (self)->converts;
+}
index 64be8b1..4cac22b 100644 (file)
@@ -69,6 +69,11 @@ typedef enum {
   GST_VIDEO_SCALE_MITCHELL
 } GstVideoScaleMethod;
 
+void gst_video_convert_scale_set_scales (GstVideoConvertScale *self, gboolean scales);
+void gst_video_convert_scale_set_converts (GstVideoConvertScale *self, gboolean converts);
+gboolean gst_video_convert_scale_get_scales (GstVideoConvertScale *self);
+gboolean gst_video_convert_scale_get_converts (GstVideoConvertScale *self);
+
 GST_ELEMENT_REGISTER_DECLARE (videoconvertscale);
 
 G_END_DECLS
index e8e41f1..94f25d9 100644 (file)
@@ -51,6 +51,7 @@
 #endif
 
 #define DEFAULT_PROP_GAMMA_DECODE FALSE
+#define DEFAULT_PROP_DISABLE_CONVERSION FALSE
 
 #include "gstvideoscale.h"
 
@@ -61,7 +62,8 @@ GST_ELEMENT_REGISTER_DEFINE (videoscale, "videoscale",
 enum
 {
   PROP_0,
-  PROP_GAMMA_DECODE
+  PROP_GAMMA_DECODE,
+  PROP_DISABLE_CONVERSION,
 };
 
 static void
@@ -78,6 +80,11 @@ gst_video_scale_get_property (GObject * object, guint prop_id,
 
       break;
     }
+    case PROP_DISABLE_CONVERSION:
+      g_value_set_boolean (value,
+          !gst_video_convert_scale_get_converts (GST_VIDEO_CONVERT_SCALE
+              (object)));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -98,6 +105,10 @@ gst_video_scale_set_property (GObject * object, guint prop_id,
 
       break;
     }
+    case PROP_DISABLE_CONVERSION:
+      gst_video_convert_scale_set_converts (GST_VIDEO_CONVERT_SCALE (object),
+          !g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -118,6 +129,17 @@ gst_video_scale_class_init (GstVideoScaleClass * klass)
       g_param_spec_boolean ("gamma-decode", "Gamma Decode",
           "Decode gamma before scaling", DEFAULT_PROP_GAMMA_DECODE,
           G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * videoscale::disable-conversion:
+   *
+   * Since: 1.22
+   */
+  g_object_class_install_property (gobject_class, PROP_DISABLE_CONVERSION,
+      g_param_spec_boolean ("disable-conversion", "Disable Conversion",
+          "Disables colorspace conversions", DEFAULT_PROP_DISABLE_CONVERSION,
+          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_READY));
 }
 
 static void
diff --git a/subprojects/gst-plugins-base/tests/validate/convertscale/convert_disable_scale.validatetest b/subprojects/gst-plugins-base/tests/validate/convertscale/convert_disable_scale.validatetest
new file mode 100644 (file)
index 0000000..8570000
--- /dev/null
@@ -0,0 +1,37 @@
+meta,
+    handles-states=true,
+    ignore-eos=true,
+    allow-errors=true,
+    args = {
+        "videotestsrc num-buffers=1 ! video/x-raw,format=ARGB,width=20,height=20 ! videoconvert name=converter ! video/x-raw,format=I420,width=100,height=100 ! fakevideosink",
+    },
+    configs = {
+       "$(validateflow), pad=converter:src, buffers-checksum=as-id, ignored-event-types={ tag }",
+    },
+    expected-issues = {
+        [
+            expected-issue,
+                level=critical,
+                issue-id=runtime::not-negotiated,
+                details="\
+.*Caps negotiation failed starting from pad 'capsfilter1:sink' as the QUERY_CAPS returned EMPTY caps for the following possible reasons:.*\\n\
+.*-> Field 'width' downstream value from structure 0 '.*100' can't intersect with filter value from structure number 0 '.*20'.*\\n\
+.*-> Field 'height' downstream value from structure 0 '.*100' can't intersect with filter value from structure number 0 '.*20'.*\
+",
+        ],
+        [
+            expected-issue,
+                level=critical,
+                issue-id=scenario::execution-error,
+                details="Error message happened while executing action",
+        ],
+    }
+
+
+play
+set-state,  state=ready, on-message=eos
+
+set-properties, converter::disable-scaling=true
+play
+
+stop, on-message=error
diff --git a/subprojects/gst-plugins-base/tests/validate/convertscale/convert_disable_scale/flow-expectations/log-converter-src-expected b/subprojects/gst-plugins-base/tests/validate/convertscale/convert_disable_scale/flow-expectations/log-converter-src-expected
new file mode 100644 (file)
index 0000000..0db91d1
--- /dev/null
@@ -0,0 +1,7 @@
+event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
+event caps: video/x-raw, format=(string)I420, framerate=(fraction)30/1, height=(int)100, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)100;
+event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
+buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.033333333, flags=discont, meta=GstVideoMeta
+event eos: (no structure)
+event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)2;
+event eos: (no structure)
diff --git a/subprojects/gst-plugins-base/tests/validate/convertscale/scale_disable_convert.validatetest b/subprojects/gst-plugins-base/tests/validate/convertscale/scale_disable_convert.validatetest
new file mode 100644 (file)
index 0000000..3088b62
--- /dev/null
@@ -0,0 +1,36 @@
+meta,
+    handles-states=true,
+    ignore-eos=true,
+    allow-errors=true,
+    args = {
+        "videotestsrc num-buffers=1 ! video/x-raw,format=ARGB,width=20,height=20 ! videoscale name=scaler ! video/x-raw,format=I420,width=100,height=100 ! fakevideosink",
+    },
+    configs = {
+       "$(validateflow), pad=scaler:src, buffers-checksum=as-id, ignored-event-types={ tag }",
+    },
+    expected-issues = {
+        [
+            expected-issue,
+                level=critical,
+                issue-id=runtime::not-negotiated,
+                details="\
+.*Caps negotiation failed starting from pad 'capsfilter.*:sink' as the QUERY_CAPS returned EMPTY caps for the following possible reasons:.*\\n\
+    -> Field 'format' downstream value from structure 0 '\\(gchararray\\)I420' can't intersect with filter value from structure number 0 '\\(gchararray\\)ARGB'\
+",
+        ],
+        [
+            expected-issue,
+                level=critical,
+                issue-id=scenario::execution-error,
+                details="Error message happened while executing action",
+        ],
+    }
+
+
+play
+set-state,  state=ready, on-message=eos
+
+set-properties, scaler::disable-conversion=true
+play
+
+stop, on-message=error
diff --git a/subprojects/gst-plugins-base/tests/validate/convertscale/scale_disable_convert/flow-expectations/log-scaler-src-expected b/subprojects/gst-plugins-base/tests/validate/convertscale/scale_disable_convert/flow-expectations/log-scaler-src-expected
new file mode 100644 (file)
index 0000000..0db91d1
--- /dev/null
@@ -0,0 +1,7 @@
+event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
+event caps: video/x-raw, format=(string)I420, framerate=(fraction)30/1, height=(int)100, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)100;
+event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
+buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.033333333, flags=discont, meta=GstVideoMeta
+event eos: (no structure)
+event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)2;
+event eos: (no structure)
index 82d22a4..326ac8a 100644 (file)
@@ -20,6 +20,8 @@ tests = [
     'compositor/renogotiate_failing_unsupported_src_format',
     'giosrc/read-growing-file',
     'encodebin/set-encoder-properties',
+    'convertscale/convert_disable_scale',
+    'convertscale/scale_disable_convert',
 ]
 
 env = environment()