webrtcbin: Try to match an existing transceiver on pad request
authorOlivier Crête <olivier.crete@collabora.com>
Sat, 27 Mar 2021 00:55:36 +0000 (20:55 -0400)
committerOlivier Crête <olivier.crete@collabora.com>
Mon, 12 Apr 2021 21:55:07 +0000 (17:55 -0400)
This should avoid creating extra transceivers that are duplicated.

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

ext/webrtc/gstwebrtcbin.c
tests/check/elements/webrtcbin.c

index d439657..b21faa4 100644 (file)
@@ -6373,6 +6373,52 @@ gst_webrtc_bin_request_new_pad (GstElement * element, GstPadTemplate * templ,
     }
   }
 
+  /* Let's try to find a free transceiver that matches */
+  if (!trans) {
+    GstWebRTCKind kind = GST_WEBRTC_KIND_UNKNOWN;
+    guint i;
+
+    if (caps)
+      kind = _kind_from_caps (caps);
+
+    for (i = 0; i < webrtc->priv->transceivers->len; i++) {
+      GstWebRTCRTPTransceiver *tmptrans =
+          g_ptr_array_index (webrtc->priv->transceivers, i);
+      GstWebRTCBinPad *pad2;
+
+      /* Ignore transceivers with a non-matching kind */
+      if (tmptrans->kind != GST_WEBRTC_KIND_UNKNOWN &&
+          kind != GST_WEBRTC_KIND_UNKNOWN && tmptrans->kind != kind)
+        continue;
+
+      /* Ignore stopped transmitters */
+      if (tmptrans->stopped)
+        continue;
+
+      /* Ignore transceivers that are only for receiving ... */
+      if (tmptrans->direction == GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY
+          || tmptrans->direction ==
+          GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_INACTIVE)
+        continue;
+
+      /* Ignore transceivers that already have a pad allocated */
+      pad2 = _find_pad_for_transceiver (webrtc, GST_PAD_SINK, tmptrans);
+      if (pad2) {
+        gst_object_unref (pad2);
+        continue;
+      }
+
+      /* Ignore transceivers with non-matching caps */
+      if (caps && tmptrans->codec_preferences &&
+          !gst_caps_can_intersect (caps, tmptrans->codec_preferences)) {
+        continue;
+      }
+
+      trans = tmptrans;
+      break;
+    }
+  }
+
   if (!trans) {
     trans = GST_WEBRTC_RTP_TRANSCEIVER (_create_webrtc_transceiver (webrtc,
             GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV, -1));
index e9d7359..376ad3a 100644 (file)
@@ -1702,6 +1702,7 @@ GST_START_TEST (test_recvonly_sendonly)
   t->harnesses = g_list_prepend (t->harnesses, h);
   g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers);
   fail_unless (transceivers != NULL);
+  fail_unless_equals_int (transceivers->len, 2);
   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 1);
   trans->direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY;