summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivia Nikolaidou <vivia@ahiru.eu>2020-06-18 22:56:57 +0300
committerVivia Nikolaidou <vivia@ahiru.eu>2020-06-24 11:15:48 +0300
commit7c7ac7a0dc044d6837b9fc38af8b319970c2b90e (patch)
tree9d4c3a98a03653ed65fb151c953c784fa02ea518
parent581d76b41a7acb0c2c657ba7e6aeab8d358c4f9a (diff)
downloadgstreamer-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.c34
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");