mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
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>
This commit is contained in:
parent
581d76b41a
commit
7c7ac7a0dc
1 changed files with 31 additions and 3 deletions
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue