videoscale: fix broken format filter

Simply intersect the format with the supported formats to make the code deal
with lists of formats.
This commit is contained in:
Wim Taymans 2012-03-08 10:22:49 +01:00
parent 863252258c
commit 37541750d2

View 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
static GstCaps *
get_formats_filter (GstVideoScaleMethod method)
{
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);
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;
}
return FALSE;
}
static gboolean
gst_video_scale_transform_supported (GstVideoScale * videoscale,
GstVideoScaleMethod method, GstStructure * structure)
{
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;
}
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