videoconvert, videoscaleconvert: fix element description
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-base / gst / videoconvertscale / gstvideoconvertscale.c
index df168ca..b6c4f44 100644 (file)
@@ -378,7 +378,7 @@ gst_video_convert_scale_class_init (GstVideoConvertScaleClass * klass)
   gst_element_class_set_static_metadata (element_class,
       "Video colorspace converter and scaler",
       "Filter/Converter/Video/Scaler/Colorspace",
-      "Resizes video and allow color conversion",
+      "Resizes video and converts from one colorspace to another",
       "Wim Taymans <wim.taymans@gmail.com>");
 
   gst_element_class_add_pad_template (element_class,
@@ -404,6 +404,10 @@ gst_video_convert_scale_class_init (GstVideoConvertScaleClass * klass)
   filter_class->set_info = GST_DEBUG_FUNCPTR (gst_video_convert_scale_set_info);
   filter_class->transform_frame =
       GST_DEBUG_FUNCPTR (gst_video_convert_scale_transform_frame);
+
+  klass->any_memory = FALSE;
+  klass->converts = TRUE;
+  klass->scales = TRUE;
 }
 
 static void
@@ -569,8 +573,10 @@ 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)
 {
+  GstVideoConvertScaleClass *klass = GST_VIDEO_CONVERT_SCALE_GET_CLASS (self);
   GstCaps *ret;
   GstStructure *structure;
   GstCapsFeatures *features;
@@ -596,15 +602,20 @@ 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 (klass->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 (klass->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));
@@ -617,13 +628,15 @@ static GstCaps *
 gst_video_convert_scale_transform_caps (GstBaseTransform * trans,
     GstPadDirection direction, GstCaps * caps, GstCaps * filter)
 {
+  GstVideoConvertScale *self = GST_VIDEO_CONVERT_SCALE (trans);
+  gint i;
   GstCaps *ret;
 
   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;
 
@@ -633,6 +646,28 @@ gst_video_convert_scale_transform_caps (GstBaseTransform * trans,
     ret = intersection;
   }
 
+  if (GST_VIDEO_CONVERT_SCALE_GET_CLASS (trans)->any_memory)
+    return ret;
+
+  for (i = 0; i < gst_caps_get_size (ret); i++) {
+    gint j;
+    GstCapsFeatures *f = gst_caps_get_features (ret, i);
+
+    if (!f || gst_caps_features_is_any (f) ||
+        gst_caps_features_is_equal (f, GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))
+      continue;
+
+    for (j = 0; j < gst_caps_features_get_size (f); j++) {
+      const gchar *feature = gst_caps_features_get_nth (f, j);
+
+      if (g_str_has_prefix (feature, "memory:")) {
+        GST_DEBUG_OBJECT (trans, "Can not work with memory `%s`", feature);
+        gst_caps_remove_structure (ret, i);
+        break;
+      }
+    }
+  }
+
   GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret);
 
   return ret;
@@ -689,7 +724,7 @@ gst_video_convert_scale_transform_meta (GstBaseTransform * trans,
         { &videofilter->in_info, &videofilter->out_info };
 
     if (info->transform_func)
-      return info->transform_func (outbuf, meta, inbuf, _scale_quark, &trans);
+      info->transform_func (outbuf, meta, inbuf, _scale_quark, &trans);
     return FALSE;
   }
 
@@ -757,12 +792,11 @@ gst_video_convert_scale_set_info (GstVideoFilter * filter, GstCaps * in,
    * we're converting between equivalent transfer functions, do passthrough */
   tmp_info = *in_info;
   tmp_info.colorimetry.transfer = out_info->colorimetry.transfer;
-  if (gst_video_info_is_equal (&tmp_info, out_info)) {
-    if (gst_video_transfer_function_is_equivalent (in_info->
-            colorimetry.transfer, in_info->finfo->bits,
-            out_info->colorimetry.transfer, out_info->finfo->bits)) {
-      gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), TRUE);
-    }
+  if (gst_video_info_is_equal (&tmp_info, out_info) &&
+      gst_video_transfer_function_is_equivalent (in_info->colorimetry.transfer,
+          in_info->finfo->bits, out_info->colorimetry.transfer,
+          out_info->finfo->bits)) {
+    gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), TRUE);
   } else {
     GstStructure *options;
     GST_CAT_DEBUG_OBJECT (CAT_PERFORMANCE, filter, "setup videoscaling");
@@ -1127,17 +1161,34 @@ transfer_colorimetry_from_input (GstBaseTransform * trans, GstCaps * in_caps,
     GstVideoInfo in_info, out_info;
     const GValue *in_colorimetry =
         gst_structure_get_value (in_caps_s, "colorimetry");
+    GstCaps *tmp_caps = NULL;
+    GstStructure *tmp_caps_s;
 
     if (!gst_video_info_from_caps (&in_info, in_caps)) {
       GST_WARNING_OBJECT (trans,
           "Failed to convert sink pad caps to video info");
       return;
     }
-    if (!gst_video_info_from_caps (&out_info, out_caps)) {
+
+    /* We are before fixate_size(), the width and height of
+       the output caps may be absent or not fixed. */
+    tmp_caps = gst_caps_copy (out_caps);
+    tmp_caps = gst_caps_fixate (tmp_caps);
+    tmp_caps_s = gst_caps_get_structure (tmp_caps, 0);
+    if (!gst_structure_has_field (tmp_caps_s, "width"))
+      gst_structure_set_value (tmp_caps_s, "width",
+          gst_structure_get_value (in_caps_s, "width"));
+    if (!gst_structure_has_field (tmp_caps_s, "height"))
+      gst_structure_set_value (tmp_caps_s, "height",
+          gst_structure_get_value (in_caps_s, "height"));
+
+    if (!gst_video_info_from_caps (&out_info, tmp_caps)) {
+      gst_clear_caps (&tmp_caps);
       GST_WARNING_OBJECT (trans,
           "Failed to convert src pad caps to video info");
       return;
     }
+    gst_clear_caps (&tmp_caps);
 
     if (!have_colorimetry && in_colorimetry != NULL) {
       if ((GST_VIDEO_INFO_IS_YUV (&out_info)
@@ -1195,6 +1246,7 @@ gst_video_convert_scale_get_fixed_format (GstBaseTransform * trans,
     result = gst_caps_copy (othercaps);
   }
 
+  result = gst_caps_make_writable (result);
   gst_video_convert_scale_fixate_format (trans, caps, result);
 
   /* fixate remaining fields */