diff --git a/ChangeLog b/ChangeLog index 2d32acc3ae..e9a45393d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2007-12-22 Tim-Philipp Müller + + * 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 * gst-libs/gst/video/video.c: diff --git a/gst/videoscale/gstvideoscale.c b/gst/videoscale/gstvideoscale.c index cbe5236a25..c75cdde031 100644 --- a/gst/videoscale/gstvideoscale.c +++ b/gst/videoscale/gstvideoscale.c @@ -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: diff --git a/tests/check/pipelines/simple-launch-lines.c b/tests/check/pipelines/simple-launch-lines.c index 971be95443..3f0bdc178e 100644 --- a/tests/check/pipelines/simple-launch-lines.c +++ b/tests/check/pipelines/simple-launch-lines.c @@ -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