mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 15:51:11 +00:00
videoscale: fix negotiation after addition of new formats and methods
Now that we no longer support all methods for all formats, we need to cater for that in the transform function: we can't transform formats not supported by the currently-selected mehod. make check, folks. It's da bomb.
This commit is contained in:
parent
92ebd6bd2a
commit
63d1316c0f
2 changed files with 128 additions and 1 deletions
|
@ -424,10 +424,118 @@ 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)
|
||||
{
|
||||
const GValue *val;
|
||||
GstVideoFormat fmt;
|
||||
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);
|
||||
} else {
|
||||
if ((val = gst_structure_get_value (structure, "endianness")))
|
||||
gst_structure_set_value (s, "endianness", val);
|
||||
if ((val = gst_structure_get_value (structure, "red_mask")))
|
||||
gst_structure_set_value (s, "red_mask", val);
|
||||
if ((val = gst_structure_get_value (structure, "blue_mask")))
|
||||
gst_structure_set_value (s, "blue_mask", val);
|
||||
if ((val = gst_structure_get_value (structure, "green_mask")))
|
||||
gst_structure_set_value (s, "green_mask", val);
|
||||
if ((val = gst_structure_get_value (structure, "alpha_mask")))
|
||||
gst_structure_set_value (s, "alpha_mask", val);
|
||||
if ((val = gst_structure_get_value (structure, "depth")))
|
||||
gst_structure_set_value (s, "depth", val);
|
||||
if ((val = gst_structure_get_value (structure, "bpp")))
|
||||
gst_structure_set_value (s, "bpp", val);
|
||||
}
|
||||
c = gst_caps_new_full (s, NULL);
|
||||
if (!gst_video_format_parse_caps (c, &fmt, NULL, NULL)) {
|
||||
GST_ERROR_OBJECT (videoscale, "couldn't parse %" GST_PTR_FORMAT, c);
|
||||
} else if (!gst_video_scale_format_supported_for_method (fmt, method)) {
|
||||
supported = FALSE;
|
||||
}
|
||||
GST_LOG_OBJECT (videoscale, "method %d %ssupported for format %d",
|
||||
method, (supported) ? "" : "not ", fmt);
|
||||
gst_caps_unref (c);
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_video_scale_transform_caps (GstBaseTransform * trans,
|
||||
GstPadDirection direction, GstCaps * caps)
|
||||
{
|
||||
GstVideoScale *videoscale = GST_VIDEO_SCALE (trans);
|
||||
GstVideoScaleMethod method;
|
||||
GstCaps *ret;
|
||||
GstStructure *structure;
|
||||
|
||||
|
@ -441,6 +549,13 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
|
|||
ret = gst_caps_copy (caps);
|
||||
structure = gst_structure_copy (gst_caps_get_structure (ret, 0));
|
||||
|
||||
GST_OBJECT_LOCK (videoscale);
|
||||
method = videoscale->method;
|
||||
GST_OBJECT_UNLOCK (videoscale);
|
||||
|
||||
if (!gst_video_scale_transform_supported (videoscale, method, structure))
|
||||
goto format_not_supported;
|
||||
|
||||
gst_structure_set (structure,
|
||||
"width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
|
||||
"height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
|
||||
|
@ -452,9 +567,19 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
|
|||
}
|
||||
gst_caps_append_structure (ret, structure);
|
||||
|
||||
done:
|
||||
|
||||
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
|
||||
|
|
|
@ -221,7 +221,7 @@ test_passthrough (int method)
|
|||
|
||||
/* skip formats that ffmpegcolorspace can't handle */
|
||||
if (caps_are_64bpp (caps))
|
||||
continue;
|
||||
goto skip;
|
||||
|
||||
GST_DEBUG ("Running test for caps '%" GST_PTR_FORMAT "'"
|
||||
" from %dx%u to %dx%d with method %d", caps, src_width, src_height,
|
||||
|
@ -251,6 +251,8 @@ test_passthrough (int method)
|
|||
g_list_free (sink_buffers);
|
||||
sink_buffers = NULL;
|
||||
|
||||
skip:
|
||||
|
||||
gst_caps_unref (caps);
|
||||
p++;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue