audioaggregator: Check all downstream allowed caps structures if they support the...
authorSebastian Dröge <sebastian@centricular.com>
Mon, 27 Jul 2020 15:49:48 +0000 (18:49 +0300)
committerSebastian Dröge <sebastian@centricular.com>
Mon, 27 Jul 2020 15:49:48 +0000 (18:49 +0300)
Otherwise it might happen that downstream prefers a different rate (i.e.
puts it into the first structure) and also supports other rates, but
audioaggregator would then fail negotiation.

Also this now correctly handles downstream returning a range of
supported rates.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/issues/795

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/768>

gst-libs/gst/audio/gstaudioaggregator.c

index 1d45170..546c9a0 100644 (file)
@@ -870,10 +870,10 @@ gst_audio_aggregator_sink_setcaps (GstAudioAggregatorPad * aaggpad,
   GstAudioAggregatorPad *first_configured_pad =
       gst_audio_aggregator_get_first_configured_pad (agg);
   GstCaps *downstream_caps = gst_pad_get_allowed_caps (agg->srcpad);
+  GstCaps *rate_caps;
   GstAudioInfo info;
   gboolean ret = TRUE;
-  gint downstream_rate;
-  GstStructure *s;
+  gboolean downstream_supports_rate;
 
   /* Returns NULL if there is no downstream peer */
   if (!downstream_caps)
@@ -888,14 +888,18 @@ gst_audio_aggregator_sink_setcaps (GstAudioAggregatorPad * aaggpad,
     GST_WARNING_OBJECT (agg, "Rejecting invalid caps: %" GST_PTR_FORMAT, caps);
     return FALSE;
   }
-  s = gst_caps_get_structure (downstream_caps, 0);
 
   /* TODO: handle different rates on sinkpads, a bit complex
    * because offsets will have to be updated, and audio resampling
    * has a latency to take into account
    */
-  if ((gst_structure_get_int (s, "rate", &downstream_rate)
-          && info.rate != downstream_rate) || (first_configured_pad
+  rate_caps =
+      gst_caps_new_simple ("audio/x-raw", "rate", G_TYPE_INT, info.rate, NULL);
+  downstream_supports_rate =
+      gst_caps_can_intersect (rate_caps, downstream_caps);
+  gst_caps_unref (rate_caps);
+
+  if (!downstream_supports_rate || (first_configured_pad
           && info.rate != first_configured_pad->info.rate)) {
     gst_pad_push_event (GST_PAD (aaggpad), gst_event_new_reconfigure ());
     ret = FALSE;