gst/videoscale/gstvideoscale.c: Don't claim to be able to handle/transform caps that...
authorTim-Philipp Müller <tim@centricular.net>
Sat, 22 Dec 2007 12:06:47 +0000 (12:06 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Sat, 22 Dec 2007 12:06:47 +0000 (12:06 +0000)
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).

ChangeLog
gst/videoscale/gstvideoscale.c
tests/check/pipelines/simple-launch-lines.c

index 2d32acc3ae9fb9e73880e4599431ac4bf0eb07ce..e9a45393d9efd8f7ed07483b1a1fc34cf830d92b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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:
index cbe5236a25034ae2cb20241b59487ebd62441391..c75cdde031000d7147cf91b68b312519d32d61ce 100644 (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);
 
-  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,
@@ -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:
index 971be95443096615013dad3a15f3dbc4ac1e6ded..3f0bdc178eda319c9c9633c36a84b9853c51bf54 100644 (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