videoscale: fix broken format filter
authorWim Taymans <wim.taymans@collabora.co.uk>
Thu, 8 Mar 2012 09:22:49 +0000 (10:22 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Thu, 8 Mar 2012 09:22:49 +0000 (10:22 +0100)
Simply intersect the format with the supported formats to make the code deal
with lists of formats.

gst/videoscale/gstvideoscale.c

index bebe52f..26e21af 100644 (file)
@@ -395,99 +395,38 @@ gst_video_scale_get_property (GObject * object, guint prop_id, GValue * value,
   }
 }
 
-#define NEAREST  (1 << GST_VIDEO_SCALE_NEAREST)
-#define BILINEAR (1 << GST_VIDEO_SCALE_BILINEAR)
-#define FOURTAP  (1 << GST_VIDEO_SCALE_4TAP)
-#define LANCZOS  (1 << GST_VIDEO_SCALE_LANCZOS)
-
-/* or we could just do lookups via table[format] if we could be bothered..  */
-static const struct
-{
-  GstVideoFormat format;
-  guint8 methods;
-} formats_methods_table[] = {
-  {
-  GST_VIDEO_FORMAT_RGBx, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_xRGB, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_BGRx, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_xBGR, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_RGBA, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_ARGB, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_BGRA, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_ABGR, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_AYUV, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_ARGB64, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_AYUV64, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_RGB, NEAREST | BILINEAR | FOURTAP}, {
-  GST_VIDEO_FORMAT_BGR, NEAREST | BILINEAR | FOURTAP}, {
-  GST_VIDEO_FORMAT_v308, NEAREST | BILINEAR | FOURTAP}, {
-  GST_VIDEO_FORMAT_YUY2, NEAREST | BILINEAR | FOURTAP}, {
-  GST_VIDEO_FORMAT_YVYU, NEAREST | BILINEAR | FOURTAP}, {
-  GST_VIDEO_FORMAT_UYVY, NEAREST | BILINEAR | FOURTAP}, {
-  GST_VIDEO_FORMAT_Y800, NEAREST | BILINEAR | FOURTAP}, {
-  GST_VIDEO_FORMAT_GRAY8, NEAREST | BILINEAR | FOURTAP}, {
-  GST_VIDEO_FORMAT_GRAY16_LE, NEAREST | BILINEAR | FOURTAP}, {
-  GST_VIDEO_FORMAT_GRAY16_BE, NEAREST | BILINEAR | FOURTAP}, {
-  GST_VIDEO_FORMAT_Y16, NEAREST | BILINEAR | FOURTAP}, {
-  GST_VIDEO_FORMAT_I420, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_YV12, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_Y444, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_Y42B, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_Y41B, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
-  GST_VIDEO_FORMAT_NV12, NEAREST | BILINEAR}, {
-  GST_VIDEO_FORMAT_RGB16, NEAREST | BILINEAR | FOURTAP}, {
-  GST_VIDEO_FORMAT_RGB15, NEAREST | BILINEAR | FOURTAP}
-};
-
-static gboolean
-gst_video_scale_format_supported_for_method (GstVideoFormat format,
-    GstVideoScaleMethod method)
-{
-  int i;
-
-  for (i = 0; i < G_N_ELEMENTS (formats_methods_table); ++i) {
-    if (formats_methods_table[i].format == format)
-      return ((formats_methods_table[i].methods & (1 << method)) != 0);
-  }
-  return FALSE;
-}
-
-static gboolean
-gst_video_scale_transform_supported (GstVideoScale * videoscale,
-    GstVideoScaleMethod method, GstStructure * structure)
+static GstCaps *
+get_formats_filter (GstVideoScaleMethod method)
 {
-  const GValue *val;
-  GstVideoInfo info;
-  gboolean supported = TRUE;
-  GstStructure *s;
-  GstCaps *c;
-
-  /* we support these methods for all formats */
-  if (method == GST_VIDEO_SCALE_NEAREST || method == GST_VIDEO_SCALE_BILINEAR)
-    return TRUE;
-
-  /* we need fixed caps if we want to use gst_video_parse_caps() */
-  s = gst_structure_new (gst_structure_get_name (structure),
-      "width", G_TYPE_INT, 1, "height", G_TYPE_INT, 1, NULL);
-
-  if ((val = gst_structure_get_value (structure, "format"))) {
-    gst_structure_set_value (s, "format", val);
-  }
-  c = gst_caps_new_full (s, NULL);
-
-  gst_video_info_init (&info);
-  if (!gst_video_info_from_caps (&info, c)) {
-    GST_ERROR_OBJECT (videoscale, "couldn't parse %" GST_PTR_FORMAT, c);
-    supported = FALSE;
-  } else if (!gst_video_scale_format_supported_for_method (info.finfo->format,
-          method)) {
-    supported = FALSE;
+  switch (method) {
+    case GST_VIDEO_SCALE_NEAREST:
+    case GST_VIDEO_SCALE_BILINEAR:
+      return NULL;
+    case GST_VIDEO_SCALE_4TAP:
+    {
+      static GstStaticCaps fourtap_filter =
+          GST_STATIC_CAPS ("video/x-raw,"
+          "format = (string) { RGBx, xRGB, BGRx, xBGR, RGBA, "
+          "ARGB, BGRA, ABGR, AYUV, ARGB64, AYUV64, "
+          "RGB, BGR, v308, YUY2, YVYU, UYVY, Y800, "
+          "GRAY8, GRAY16_LE, GRAY16_BE, Y16, I420, YV12, "
+          "Y444, Y42B, Y41B, RGB16, RGB15 }");
+      return gst_static_caps_get (&fourtap_filter);
+    }
+    case GST_VIDEO_SCALE_LANCZOS:
+    {
+      static GstStaticCaps lanczos_filter =
+          GST_STATIC_CAPS ("video/x-raw,"
+          "format = (string) { RGBx, xRGB, BGRx, xBGR, RGBA, "
+          "ARGB, BGRA, ABGR, AYUV, ARGB64, AYUV64, "
+          "I420, YV12, Y444, Y42B, Y41B }");
+      return gst_static_caps_get (&lanczos_filter);
+    }
+    default:
+      g_assert_not_reached ();
+      break;
   }
-  GST_LOG_OBJECT (videoscale, "method %d %ssupported for format %d",
-      method, (supported) ? "" : "not ", info.finfo->format);
-  gst_caps_unref (c);
-
-  return supported;
+  return NULL;
 }
 
 static GstCaps *
@@ -496,7 +435,7 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
 {
   GstVideoScale *videoscale = GST_VIDEO_SCALE (trans);
   GstVideoScaleMethod method;
-  GstCaps *ret;
+  GstCaps *ret, *mfilter;
   GstStructure *structure;
   gint i, n;
 
@@ -508,6 +447,14 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
   method = videoscale->method;
   GST_OBJECT_UNLOCK (videoscale);
 
+  /* filter the supported formats */
+  if ((mfilter = get_formats_filter (method))) {
+    caps = gst_caps_intersect_full (caps, mfilter, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (mfilter);
+  } else {
+    gst_caps_ref (caps);
+  }
+
   ret = gst_caps_new_empty ();
   n = gst_caps_get_size (caps);
   for (i = 0; i < n; i++) {
@@ -518,9 +465,7 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
     if (i > 0 && gst_caps_is_subset_structure (ret, structure))
       continue;
 
-    if (!gst_video_scale_transform_supported (videoscale, method, structure))
-      goto format_not_supported;
-
+    /* make copy */
     structure = gst_structure_copy (structure);
     gst_structure_set (structure,
         "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
@@ -543,19 +488,10 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
     ret = intersection;
   }
 
-done:
-
+  gst_caps_unref (caps);
   GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret);
 
   return ret;
-
-format_not_supported:
-  {
-    gst_structure_free (structure);
-    gst_caps_unref (ret);
-    ret = gst_caps_new_empty ();
-    goto done;
-  }
 }
 
 static gboolean