From cb527623a31bf9cc701630f90c8754f336dd874b Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Thu, 3 Feb 2011 16:10:49 -0300 Subject: [PATCH] deinterlace: Handle image caps without asserting 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 | 16 +++++++----- tests/check/elements/deinterlace.c | 40 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/gst/deinterlace/gstdeinterlace.c b/gst/deinterlace/gstdeinterlace.c index 300f23e7fd..2f7d2ea0e6 100644 --- a/gst/deinterlace/gstdeinterlace.c +++ b/gst/deinterlace/gstdeinterlace.c @@ -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); diff --git a/tests/check/elements/deinterlace.c b/tests/check/elements/deinterlace.c index 6606a5f7a1..b111c86f74 100644 --- a/tests/check/elements/deinterlace.c +++ b/tests/check/elements/deinterlace.c @@ -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;