diff options
author | Vivia Nikolaidou <vivia@ahiru.eu> | 2020-06-18 22:56:57 +0300 |
---|---|---|
committer | Vivia Nikolaidou <vivia@ahiru.eu> | 2020-06-24 11:15:48 +0300 |
commit | 7c7ac7a0dc044d6837b9fc38af8b319970c2b90e (patch) | |
tree | 9d4c3a98a03653ed65fb151c953c784fa02ea518 | |
parent | 581d76b41a7acb0c2c657ba7e6aeab8d358c4f9a (diff) | |
download | gstreamer-plugins-bad-7c7ac7a0dc044d6837b9fc38af8b319970c2b90e.tar.gz |
interlace: Don't fail negotiation if capsfilters decide framerate
Try to negotiate if the framerates on either sides of the interlace are
decided using capsfilters and the framerates are correct. Otherwise the
following pipelines would fail to negotiate:
gst-launch-1.0 videotestsrc !
video/x-raw,framerate=24/1,interlace-mode=progressive ! interlace
field-pattern=2 ! video/x-raw,framerate =30/1 ! fakesink
gst-launch-1.0 videotestsrc !
video/x-raw,framerate=60/1,interlace-mode=progressive ! interlace
field-pattern=0 ! video/x-raw,framerate=30/1 ! fakesink
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1349>
-rw-r--r-- | gst/interlace/gstinterlace.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/gst/interlace/gstinterlace.c b/gst/interlace/gstinterlace.c index f3656505d..f84b2eb4a 100644 --- a/gst/interlace/gstinterlace.c +++ b/gst/interlace/gstinterlace.c @@ -213,6 +213,9 @@ static gboolean gst_interlace_src_query (GstPad * pad, GstObject * parent, static GstStateChangeReturn gst_interlace_change_state (GstElement * element, GstStateChange transition); +static GstCaps *gst_interlace_caps_double_framerate (GstCaps * caps, + gboolean half, gboolean skip_progressive); + #define gst_interlace_parent_class parent_class G_DEFINE_TYPE (GstInterlace, gst_interlace, GST_TYPE_ELEMENT); @@ -434,6 +437,20 @@ gst_interlace_setcaps (GstInterlace * interlace, GstCaps * caps) s = gst_caps_get_structure (othercaps, i); gst_structure_remove_field (s, "field-order"); } + } else if (interlace->pattern == GST_INTERLACE_PATTERN_1_1 && + GST_VIDEO_INFO_INTERLACE_MODE (&info) == + GST_VIDEO_INTERLACE_MODE_PROGRESSIVE) { + /* interlaced will do passthrough, mixed will fail later in the + * negotiation */ + othercaps = gst_interlace_caps_double_framerate (othercaps, TRUE, FALSE); + } else if (interlace->pattern > GST_INTERLACE_PATTERN_2_2) { + GST_FIXME_OBJECT (interlace, + "Add calculations for telecine framerate conversions"); + for (i = 0; i < gst_caps_get_size (othercaps); ++i) { + GstStructure *s = gst_caps_get_structure (othercaps, i); + + gst_structure_remove_field (s, "framerate"); + } } src_peer_caps = gst_pad_peer_query_caps (interlace->srcpad, othercaps); gst_caps_unref (othercaps); @@ -457,6 +474,8 @@ gst_interlace_setcaps (GstInterlace * interlace, GstCaps * caps) interlace->src_fps_n = info.fps_n * pdformat->ratio_n; interlace->src_fps_d = info.fps_d * pdformat->ratio_d; + GST_DEBUG_OBJECT (interlace, "new framerate %d/%d", interlace->src_fps_n, + interlace->src_fps_d); if (alternate) { GST_DEBUG_OBJECT (interlace, @@ -666,18 +685,26 @@ gst_interlace_fraction_double (gint * n_out, gint * d_out, gboolean half) } static GstCaps * -gst_interlace_caps_double_framerate (GstCaps * caps, gboolean half) +gst_interlace_caps_double_framerate (GstCaps * caps, gboolean half, + gboolean skip_progressive) { guint len; for (len = gst_caps_get_size (caps); len > 0; len--) { GstStructure *s = gst_caps_get_structure (caps, len - 1); const GValue *val; + const gchar *interlace_mode; val = gst_structure_get_value (s, "framerate"); if (!val) continue; + interlace_mode = gst_structure_get_string (s, "interlace-mode"); + /* Do not double the framerate for interlaced - we will either passthrough + * or fail to negotiate */ + if (skip_progressive && (g_strcmp0 (interlace_mode, "progressive") != 0)) + continue; + if (G_VALUE_TYPE (val) == GST_TYPE_FRACTION) { gint n, d; @@ -789,7 +816,7 @@ gst_interlace_getcaps (GstPad * pad, GstInterlace * interlace, GstCaps * filter) if (interlace->pattern == GST_INTERLACE_PATTERN_1_1) { clean_filter = gst_interlace_caps_double_framerate (clean_filter, - (pad == interlace->sinkpad)); + (pad == interlace->sinkpad), TRUE); } else if (interlace->pattern != GST_INTERLACE_PATTERN_2_2) { GST_FIXME_OBJECT (interlace, "Add calculations for telecine framerate conversions"); @@ -887,7 +914,8 @@ gst_interlace_getcaps (GstPad * pad, GstInterlace * interlace, GstCaps * filter) if (interlace->pattern == GST_INTERLACE_PATTERN_1_1) { icaps = - gst_interlace_caps_double_framerate (icaps, (pad == interlace->srcpad)); + gst_interlace_caps_double_framerate (icaps, (pad == interlace->srcpad), + FALSE); } else if (interlace->pattern != GST_INTERLACE_PATTERN_2_2) { GST_FIXME_OBJECT (interlace, "Add calculations for telecine framerate conversions"); |