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);
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);
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);
- ret = gst_caps_copy (caps);
+ GST_OBJECT_LOCK (videoscale);
+ method = videoscale->method;
+ GST_OBJECT_UNLOCK (videoscale);
- /* 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 (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);
structure = gst_caps_get_structure (ret, 0);
gst_structure_set (structure,
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
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;
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:
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;
{
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:
{
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;
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