gst/videoscale/gstvideoscale.c: Don't claim to be able to handle/transform caps that can't really be handled by the c...

Original commit message from CVS:
* gst/videoscale/gstvideoscale.c: (gst_video_scale_set_property),
(gst_video_scale_get_property), (gst_video_scale_transform_caps),
(gst_video_scale_transform):
Don't claim to be able to handle/transform caps that can't really
be handled by the currently selected scaling method (here: RGB or
packed YUV with 4-tap method). Also add locking to method property.
* tests/check/pipelines/simple-launch-lines.c: (setup_pipeline),
(test_basetransform_based):
Some test pipelines for the above (not entirely valgrind clean yet
apparently).
This commit is contained in:
Tim-Philipp Müller 2007-12-22 12:06:47 +00:00
parent d605ca3ba2
commit bd01fd3a57
3 changed files with 92 additions and 10 deletions

View file

@ -1,3 +1,17 @@
2007-12-22 Tim-Philipp Müller <tim at centricular dot net>
* gst/videoscale/gstvideoscale.c: (gst_video_scale_set_property),
(gst_video_scale_get_property), (gst_video_scale_transform_caps),
(gst_video_scale_transform):
Don't claim to be able to handle/transform caps that can't really
be handled by the currently selected scaling method (here: RGB or
packed YUV with 4-tap method). Also add locking to method property.
* tests/check/pipelines/simple-launch-lines.c: (setup_pipeline),
(test_basetransform_based):
Some test pipelines for the above (not entirely valgrind clean yet
apparently).
2007-12-21 David Schleef <ds@schleef.org>
* gst-libs/gst/video/video.c:

View file

@ -307,11 +307,13 @@ static void
gst_video_scale_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstVideoScale *src = GST_VIDEO_SCALE (object);
GstVideoScale *vscale = GST_VIDEO_SCALE (object);
switch (prop_id) {
case PROP_METHOD:
src->method = g_value_get_enum (value);
GST_OBJECT_LOCK (vscale);
vscale->method = g_value_get_enum (value);
GST_OBJECT_UNLOCK (vscale);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -323,11 +325,13 @@ static void
gst_video_scale_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstVideoScale *src = GST_VIDEO_SCALE (object);
GstVideoScale *vscale = GST_VIDEO_SCALE (object);
switch (prop_id) {
case PROP_METHOD:
g_value_set_enum (value, src->method);
GST_OBJECT_LOCK (vscale);
g_value_set_enum (value, vscale->method);
GST_OBJECT_UNLOCK (vscale);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -343,14 +347,33 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
GstCaps *ret;
GstStructure *structure;
const GValue *par;
gint method;
/* this function is always called with a simple caps */
g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL);
videoscale = GST_VIDEO_SCALE (trans);
GST_OBJECT_LOCK (videoscale);
method = videoscale->method;
GST_OBJECT_UNLOCK (videoscale);
structure = gst_caps_get_structure (caps, 0);
/* check compatibility of format and method before we copy the input caps */
if (method == GST_VIDEO_SCALE_4TAP) {
guint32 fourcc;
if (!gst_structure_has_name (structure, "video/x-raw-yuv"))
goto method_not_implemented_for_format;
if (!gst_structure_get_fourcc (structure, "format", &fourcc))
goto method_not_implemented_for_format;
if (fourcc != GST_MAKE_FOURCC ('I', '4', '2', '0') &&
fourcc != GST_MAKE_FOURCC ('Y', 'V', '1', '2'))
goto method_not_implemented_for_format;
}
ret = gst_caps_copy (caps);
/* this function is always called with a simple caps */
g_return_val_if_fail (GST_CAPS_IS_SIMPLE (ret), NULL);
structure = gst_caps_get_structure (ret, 0);
gst_structure_set (structure,
@ -378,6 +401,13 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret);
return ret;
method_not_implemented_for_format:
{
GST_DEBUG_OBJECT (trans, "method %d not implemented for format %"
GST_PTR_FORMAT ", returning empty caps", method, caps);
return gst_caps_new_empty ();
}
}
static int
@ -709,9 +739,14 @@ gst_video_scale_transform (GstBaseTransform * trans, GstBuffer * in,
VSImage dest_v;
VSImage src_u;
VSImage src_v;
gint method;
videoscale = GST_VIDEO_SCALE (trans);
GST_OBJECT_LOCK (videoscale);
method = videoscale->method;
GST_OBJECT_UNLOCK (videoscale);
src = &videoscale->src;
dest = &videoscale->dest;
@ -719,7 +754,7 @@ gst_video_scale_transform (GstBaseTransform * trans, GstBuffer * in,
gst_video_scale_prepare_image (videoscale->format, out, dest, &dest_u,
&dest_v);
switch (videoscale->method) {
switch (method) {
case GST_VIDEO_SCALE_NEAREST:
switch (videoscale->format) {
case GST_VIDEO_SCALE_RGBx:
@ -815,6 +850,8 @@ gst_video_scale_transform (GstBaseTransform * trans, GstBuffer * in,
vs_image_scale_4tap_Y (&dest_v, &src_v, videoscale->tmp_buf);
break;
default:
/* FIXME: update gst_video_scale_transform_caps once RGB and/or
* other YUV formats work too */
goto unsupported;
}
break;
@ -832,7 +869,7 @@ unsupported:
{
GST_ELEMENT_ERROR (videoscale, STREAM, NOT_IMPLEMENTED, (NULL),
("Unsupported format %d for scaling method %d",
videoscale->format, videoscale->method));
videoscale->format, method));
return GST_FLOW_ERROR;
}
unknown_mode:

View file

@ -29,6 +29,7 @@ setup_pipeline (const gchar * pipe_descr)
{
GstElement *pipeline;
GST_LOG ("pipeline: %s", pipe_descr);
pipeline = gst_parse_launch (pipe_descr, NULL);
g_return_val_if_fail (GST_IS_PIPELINE (pipeline), NULL);
return pipeline;
@ -168,6 +169,36 @@ GST_START_TEST (test_basetransform_based)
run_pipeline (setup_pipeline (s), s,
GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
GST_MESSAGE_UNKNOWN);
/* Check that videoscale doesn't claim to be able to transform input in
* formats it can't handle for a given scaling method; ffmpegcolorspace
* should then make sure a format that can be handled is chosen (4-tap
* scaling is not implemented for RGB and packed yuv currently) */
s = "videotestsrc num-buffers=2 ! video/x-raw-rgb,width=64,height=64 ! "
"ffmpegcolorspace ! videoscale method=4-tap ! ffmpegcolorspace ! "
"video/x-raw-rgb,width=32,height=32,framerate=(fraction)30/1,"
"pixel-aspect-ratio=(fraction)1/1,bpp=(int)24,depth=(int)24,"
"red_mask=(int)16711680,green_mask=(int)65280,blue_mask=(int)255,"
"endianness=(int)4321 ! fakesink";
run_pipeline (setup_pipeline (s), s,
GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
GST_MESSAGE_UNKNOWN);
s = "videotestsrc num-buffers=2 ! video/x-raw-yuv,format=(fourcc)AYUV,"
"width=64,height=64 ! ffmpegcolorspace ! videoscale method=4-tap ! "
"ffmpegcolorspace ! video/x-raw-yuv,format=(fourcc)AYUV,width=32,"
"height=32 ! fakesink";
run_pipeline (setup_pipeline (s), s,
GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
GST_MESSAGE_UNKNOWN);
/* make sure nothing funny happens in passthrough mode (we don't check that
* passthrough mode is chosen though) */
s = "videotestsrc num-buffers=2 ! video/x-raw-yuv,format=(fourcc)I420,"
"width=64,height=64 ! ffmpegcolorspace ! videoscale method=4-tap ! "
"ffmpegcolorspace ! video/x-raw-yuv,format=(fourcc)I420,width=32,"
"height=32 ! fakesink";
run_pipeline (setup_pipeline (s), s,
GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
GST_MESSAGE_UNKNOWN);
}
GST_END_TEST