From 7c6093357b5904c2e5dc7f3c9140748c85575349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 5 Jun 2012 09:30:00 +0200 Subject: [PATCH] videoparsers: Fix GstBaseParse::get_sink_caps() implementations They should take the filter caps into account and always return the template caps appended to the actual caps. Otherwise the parsers stop to accept unparsed streams where upstream does not know about width, height, etc. Fixes bug #677401. --- gst/videoparsers/gstdiracparse.c | 28 +++++++++++++++++++-------- gst/videoparsers/gsth263parse.c | 28 +++++++++++++++++++-------- gst/videoparsers/gsth264parse.c | 17 +++++++++------- gst/videoparsers/gstmpeg4videoparse.c | 19 ++++++++++-------- gst/videoparsers/gstmpegvideoparse.c | 27 ++++++++++++++++++-------- 5 files changed, 80 insertions(+), 39 deletions(-) diff --git a/gst/videoparsers/gstdiracparse.c b/gst/videoparsers/gstdiracparse.c index 13b874fcd5..0d7518bdee 100644 --- a/gst/videoparsers/gstdiracparse.c +++ b/gst/videoparsers/gstdiracparse.c @@ -351,10 +351,12 @@ gst_dirac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) static GstCaps * gst_dirac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter) { - GstCaps *peercaps; + GstCaps *peercaps, *templ; GstCaps *res; + templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse)); peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse)); + if (peercaps) { guint i, n; @@ -366,15 +368,25 @@ gst_dirac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter) gst_structure_remove_field (s, "parsed"); } - res = - gst_caps_intersect_full (peercaps, - gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse)), - GST_CAPS_INTERSECT_FIRST); + res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (peercaps); + + /* Append the template caps because we still want to accept + * caps without any fields in the case upstream does not + * know anything. + */ + gst_caps_append (res, templ); } else { - res = - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD - (parse))); + res = templ; + } + + if (filter) { + GstCaps *intersection; + + intersection = + gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (res); + res = intersection; } return res; diff --git a/gst/videoparsers/gsth263parse.c b/gst/videoparsers/gsth263parse.c index 4d75da87e6..1d1324a302 100644 --- a/gst/videoparsers/gsth263parse.c +++ b/gst/videoparsers/gsth263parse.c @@ -352,10 +352,12 @@ more: static GstCaps * gst_h263_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter) { - GstCaps *peercaps; + GstCaps *peercaps, *templ; GstCaps *res; + templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse)); peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse)); + if (peercaps) { guint i, n; @@ -367,15 +369,25 @@ gst_h263_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter) gst_structure_remove_field (s, "parsed"); } - res = - gst_caps_intersect_full (peercaps, - gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse)), - GST_CAPS_INTERSECT_FIRST); + res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (peercaps); + + /* Append the template caps because we still want to accept + * caps without any fields in the case upstream does not + * know anything. + */ + gst_caps_append (res, templ); } else { - res = - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD - (parse))); + res = templ; + } + + if (filter) { + GstCaps *intersection; + + intersection = + gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (res); + res = intersection; } return res; diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c index 38086a5e26..b14ea9c8b0 100644 --- a/gst/videoparsers/gsth264parse.c +++ b/gst/videoparsers/gsth264parse.c @@ -1821,11 +1821,10 @@ refuse_caps: static GstCaps * gst_h264_parse_get_caps (GstBaseParse * parse, GstCaps * filter) { - GstCaps *peercaps, *template_caps; + GstCaps *peercaps, *templ; GstCaps *res; - template_caps = - gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse)); + templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse)); peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse)); if (peercaps) { guint i, n; @@ -1839,12 +1838,16 @@ gst_h264_parse_get_caps (GstBaseParse * parse, GstCaps * filter) gst_structure_remove_field (s, "parsed"); } - res = gst_caps_intersect_full (peercaps, template_caps, - GST_CAPS_INTERSECT_FIRST); + res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (peercaps); - gst_caps_unref (template_caps); + + /* Append the template caps because we still want to accept + * caps without any fields in the case upstream does not + * know anything. + */ + gst_caps_append (res, templ); } else { - res = template_caps; + res = templ; } if (filter) { diff --git a/gst/videoparsers/gstmpeg4videoparse.c b/gst/videoparsers/gstmpeg4videoparse.c index 9b7344f069..29caec7f52 100644 --- a/gst/videoparsers/gstmpeg4videoparse.c +++ b/gst/videoparsers/gstmpeg4videoparse.c @@ -767,10 +767,12 @@ gst_mpeg4vparse_set_caps (GstBaseParse * parse, GstCaps * caps) static GstCaps * gst_mpeg4vparse_get_caps (GstBaseParse * parse, GstCaps * filter) { - GstCaps *peercaps; + GstCaps *peercaps, *templ; GstCaps *res; + templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse)); peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse)); + if (peercaps) { guint i, n; @@ -783,15 +785,16 @@ gst_mpeg4vparse_get_caps (GstBaseParse * parse, GstCaps * filter) gst_structure_remove_field (s, "parsed"); } - res = - gst_caps_intersect_full (peercaps, - gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)), - GST_CAPS_INTERSECT_FIRST); + res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (peercaps); + + /* Append the template caps because we still want to accept + * caps without any fields in the case upstream does not + * know anything. + */ + gst_caps_append (res, templ); } else { - res = - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD - (parse))); + res = templ; } if (filter) { diff --git a/gst/videoparsers/gstmpegvideoparse.c b/gst/videoparsers/gstmpegvideoparse.c index 77f19ca952..7892229bf6 100644 --- a/gst/videoparsers/gstmpegvideoparse.c +++ b/gst/videoparsers/gstmpegvideoparse.c @@ -824,9 +824,10 @@ gst_mpegv_parse_set_caps (GstBaseParse * parse, GstCaps * caps) static GstCaps * gst_mpegv_parse_get_caps (GstBaseParse * parse, GstCaps * filter) { - GstCaps *peercaps; + GstCaps *peercaps, *templ; GstCaps *res; + templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse)); peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse)); if (peercaps) { guint i, n; @@ -839,15 +840,25 @@ gst_mpegv_parse_get_caps (GstBaseParse * parse, GstCaps * filter) gst_structure_remove_field (s, "parsed"); } - res = - gst_caps_intersect_full (peercaps, - gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse)), - GST_CAPS_INTERSECT_FIRST); + res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (peercaps); + + /* Append the template caps because we still want to accept + * caps without any fields in the case upstream does not + * know anything. + */ + gst_caps_append (res, templ); } else { - res = - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD - (parse))); + res = templ; + } + + if (filter) { + GstCaps *intersection; + + intersection = + gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (res); + res = intersection; } return res;