From 1c6adcab895edcd2f276d3877b8621335f5e23c0 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Wed, 7 Sep 2022 10:39:21 -0400 Subject: [PATCH] uridecodebin: Ensure that pads caps are set before exposing them We are supposed to guarantee that pads that are exposed have the caps set, but for sources that have pad with "all raw caps" templates, we end up exposing pads that don't have caps set yet, which can break code (in GES for example). To avoid that we let uridecodebin plug a `decodebin` after such pads and let decodebin to handle that for us. In the end the only thing that decodebin does in those cases is to wait for pads to be ready and expose them, after that `uridecodebin` will expose those pads. Part-of: --- .../gst/playback/gsturidecodebin.c | 25 ++++++++----------- .../tests/validate/meson.build | 1 + .../expose_raw_pad_caps.validatetest | 15 +++++++++++ 3 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 subprojects/gst-plugins-base/tests/validate/uridecodebin/expose_raw_pad_caps.validatetest diff --git a/subprojects/gst-plugins-base/gst/playback/gsturidecodebin.c b/subprojects/gst-plugins-base/gst/playback/gsturidecodebin.c index b27c2fcd96..00fc502bf2 100644 --- a/subprojects/gst-plugins-base/gst/playback/gsturidecodebin.c +++ b/subprojects/gst-plugins-base/gst/playback/gsturidecodebin.c @@ -1478,23 +1478,23 @@ no_source: } /** - * has_all_raw_caps: + * has_raw_caps: * @pad: a #GstPad * @all_raw: pointer to hold the result * * check if the caps of the pad are all raw. The caps are all raw if * all of its structures contain audio/x-raw or video/x-raw. * - * Returns: %FALSE @pad has no caps. Else TRUE and @all_raw set t the result. + * Returns: %FALSE @pad caps are not set and raw */ static gboolean -has_all_raw_caps (GstPad * pad, GstCaps * rawcaps, gboolean * all_raw) +has_raw_caps (GstPad * pad, GstCaps * rawcaps) { GstCaps *caps, *intersection; gint capssize; gboolean res = FALSE; - caps = gst_pad_query_caps (pad, NULL); + caps = gst_pad_get_current_caps (pad); if (caps == NULL) return FALSE; @@ -1506,12 +1506,9 @@ has_all_raw_caps (GstPad * pad, GstCaps * rawcaps, gboolean * all_raw) goto done; intersection = gst_caps_intersect (caps, rawcaps); - *all_raw = !gst_caps_is_empty (intersection) - && (gst_caps_get_size (intersection) == capssize); + res = !gst_caps_is_empty (intersection); gst_caps_unref (intersection); - res = TRUE; - done: gst_caps_unref (caps); return res; @@ -1593,16 +1590,15 @@ analyse_source (GstURIDecodeBin * decoder, gboolean * is_raw, *have_out = TRUE; /* if FALSE, this pad has no caps and we continue with the next pad. */ - if (!has_all_raw_caps (pad, rawcaps, is_raw)) { + if (!has_raw_caps (pad, rawcaps)) { gst_object_unref (pad); g_value_reset (&item); break; - } - - /* caps on source pad are all raw, we can add the pad */ - if (*is_raw) { + } else { + /* caps on source pad are all raw, we can add the pad */ GstElement *outelem; + *is_raw = TRUE; if (use_queue) { GstPad *sinkpad; @@ -2169,7 +2165,6 @@ static void source_new_pad (GstElement * element, GstPad * pad, GstURIDecodeBin * bin) { GstElement *decoder; - gboolean is_raw; GstCaps *rawcaps; GstPad *sinkpad; @@ -2182,7 +2177,7 @@ source_new_pad (GstElement * element, GstPad * pad, GstURIDecodeBin * bin) rawcaps = DEFAULT_CAPS; /* if this is a pad with all raw caps, we can expose it */ - if (has_all_raw_caps (pad, rawcaps, &is_raw) && is_raw) { + if (has_raw_caps (pad, rawcaps)) { /* it's all raw, create output pads. */ GST_URI_DECODE_BIN_UNLOCK (bin); gst_caps_unref (rawcaps); diff --git a/subprojects/gst-plugins-base/tests/validate/meson.build b/subprojects/gst-plugins-base/tests/validate/meson.build index 82d22a4b0b..f055ffd2d8 100644 --- a/subprojects/gst-plugins-base/tests/validate/meson.build +++ b/subprojects/gst-plugins-base/tests/validate/meson.build @@ -20,6 +20,7 @@ tests = [ 'compositor/renogotiate_failing_unsupported_src_format', 'giosrc/read-growing-file', 'encodebin/set-encoder-properties', + 'uridecodebin/expose_raw_pad_caps', ] env = environment() diff --git a/subprojects/gst-plugins-base/tests/validate/uridecodebin/expose_raw_pad_caps.validatetest b/subprojects/gst-plugins-base/tests/validate/uridecodebin/expose_raw_pad_caps.validatetest new file mode 100644 index 0000000000..a8e367ce0c --- /dev/null +++ b/subprojects/gst-plugins-base/tests/validate/uridecodebin/expose_raw_pad_caps.validatetest @@ -0,0 +1,15 @@ +meta, + args = { + "uridecodebin uri=testbin://video,num-buffers=1 ! fakesink", + }, + handles-states=true, + ignore-eos=true + +wait, signal-name="pad-added", target-element-factory-name="uridecodebin", non-blocking=true, + check=[ + check-current-pad-caps, expected-caps=[video/x-raw], target-element-factory-name="uridecodebin", pad="src_0", comparison-mode="intersect", + ] + +pause + +stop