deinterlace: Handle image caps without asserting
authorThiago Santos <thiago.sousa.santos@collabora.co.uk>
Thu, 3 Feb 2011 19:10:49 +0000 (16:10 -0300)
committerThiago Santos <thiago.sousa.santos@collabora.co.uk>
Fri, 4 Feb 2011 12:38:35 +0000 (09:38 -0300)
Images might have framerate=0/1 in the caps, which caused an
assertion on deinterlace. I don't know of interlaced image formats
but deinterlace might be hardcoded on some generic pipelines and
it shouldn't assert.

The fix was to set field_duration to 0 if the input has a framerate
with a 0 numerator.

This patch also adds checks for this situation on the unit tests.

https://bugzilla.gnome.org/show_bug.cgi?id=641400

gst/deinterlace/gstdeinterlace.c
tests/check/elements/deinterlace.c

index 300f23e..2f7d2ea 100644 (file)
@@ -1433,12 +1433,16 @@ gst_deinterlace_setcaps (GstPad * pad, GstCaps * caps)
   self->frame_size =
       gst_video_format_get_size (self->format, self->width, self->height);
 
-  if (self->fields == GST_DEINTERLACE_ALL && otherpad == self->srcpad)
-    self->field_duration =
-        gst_util_uint64_scale (GST_SECOND, self->fps_d, self->fps_n);
-  else
-    self->field_duration =
-        gst_util_uint64_scale (GST_SECOND, self->fps_d, 2 * self->fps_n);
+  if (G_LIKELY (self->fps_n != 0)) {
+    if (self->fields == GST_DEINTERLACE_ALL && otherpad == self->srcpad)
+      self->field_duration =
+          gst_util_uint64_scale (GST_SECOND, self->fps_d, self->fps_n);
+    else
+      self->field_duration =
+          gst_util_uint64_scale (GST_SECOND, self->fps_d, 2 * self->fps_n);
+  } else {
+    self->field_duration = 0;
+  }
 
   if (pad == self->sinkpad) {
     gst_caps_replace (&self->sink_caps, caps);
index 6606a5f..b111c86 100644 (file)
@@ -53,6 +53,9 @@ GST_END_TEST;
 #define CAPS_VIDEO_COMMON \
     "width=(int)800, height=(int)600, framerate=(fraction)15/1"
 
+#define CAPS_IMAGE_COMMON \
+    "width=(int)3200, height=(int)3400, framerate=(fraction)0/1"
+
 #define CAPS_YUY2 \
     "video/x-raw-yuv, " \
     CAPS_VIDEO_COMMON ", " \
@@ -71,6 +74,24 @@ GST_END_TEST;
     CAPS_YVYU ", " \
     "interlaced=(boolean)true"
 
+#define CAPS_YUY2_IMAGE \
+    "video/x-raw-yuv, " \
+    CAPS_IMAGE_COMMON ", " \
+    "format=(fourcc)YUY2"
+
+#define CAPS_YUY2_INTERLACED_IMAGE \
+    CAPS_YUY2_IMAGE ", " \
+    "interlaced=(boolean)true"
+
+#define CAPS_YVYU_IMAGE \
+    "video/x-raw-yuv, " \
+    CAPS_IMAGE_COMMON ", " \
+    "format=(fourcc)YVYU"
+
+#define CAPS_YVYU_INTERLACED_IMAGE \
+    CAPS_YVYU_IMAGE ", " \
+    "interlaced=(boolean)true"
+
 static GstElement *deinterlace;
 static GstPad *srcpad;
 static GstPad *sinkpad;
@@ -295,10 +316,14 @@ GST_START_TEST (test_mode_auto_accept_caps)
   /* try to set non interlaced caps */
   deinterlace_set_string_caps_and_check (CAPS_YVYU, FALSE);
   deinterlace_set_string_caps_and_check (CAPS_YUY2, FALSE);
+  deinterlace_set_string_caps_and_check (CAPS_YVYU_IMAGE, FALSE);
+  deinterlace_set_string_caps_and_check (CAPS_YUY2_IMAGE, FALSE);
 
   /* now try to set interlaced caps */
   deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED, TRUE);
   deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED, TRUE);
+  deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED_IMAGE, TRUE);
+  deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED_IMAGE, TRUE);
 
   /* cleanup */
   gst_object_unref (sinkpad);
@@ -322,10 +347,14 @@ GST_START_TEST (test_mode_forced_accept_caps)
   /* try to set non interlaced caps */
   deinterlace_set_string_caps_and_check (CAPS_YVYU, TRUE);
   deinterlace_set_string_caps_and_check (CAPS_YUY2, TRUE);
+  deinterlace_set_string_caps_and_check (CAPS_YVYU_IMAGE, TRUE);
+  deinterlace_set_string_caps_and_check (CAPS_YUY2_IMAGE, TRUE);
 
   /* now try to set interlaced caps */
   deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED, TRUE);
   deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED, TRUE);
+  deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED_IMAGE, TRUE);
+  deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED_IMAGE, TRUE);
 
   /* cleanup */
   gst_object_unref (sinkpad);
@@ -349,10 +378,14 @@ GST_START_TEST (test_mode_disabled_accept_caps)
   /* try to set non interlaced caps */
   deinterlace_set_string_caps_and_check (CAPS_YVYU, FALSE);
   deinterlace_set_string_caps_and_check (CAPS_YUY2, FALSE);
+  deinterlace_set_string_caps_and_check (CAPS_YVYU_IMAGE, FALSE);
+  deinterlace_set_string_caps_and_check (CAPS_YUY2_IMAGE, FALSE);
 
   /* now try to set interlaced caps */
   deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED, FALSE);
   deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED, FALSE);
+  deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED_IMAGE, FALSE);
+  deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED_IMAGE, FALSE);
 
   /* cleanup */
   gst_object_unref (sinkpad);
@@ -371,6 +404,11 @@ GST_START_TEST (test_mode_disabled_passthrough)
   deinterlace_check_passthrough (2, CAPS_YVYU_INTERLACED);
   deinterlace_check_passthrough (2, CAPS_YUY2);
   deinterlace_check_passthrough (2, CAPS_YVYU);
+
+  deinterlace_check_passthrough (2, CAPS_YUY2_INTERLACED_IMAGE);
+  deinterlace_check_passthrough (2, CAPS_YVYU_INTERLACED_IMAGE);
+  deinterlace_check_passthrough (2, CAPS_YUY2_IMAGE);
+  deinterlace_check_passthrough (2, CAPS_YVYU_IMAGE);
 }
 
 GST_END_TEST;
@@ -380,6 +418,8 @@ GST_START_TEST (test_mode_auto_deinterlaced_passthrough)
   /* 0 is auto mode */
   deinterlace_check_passthrough (0, CAPS_YUY2);
   deinterlace_check_passthrough (0, CAPS_YVYU);
+  deinterlace_check_passthrough (0, CAPS_YUY2_IMAGE);
+  deinterlace_check_passthrough (0, CAPS_YVYU_IMAGE);
 }
 
 GST_END_TEST;