webrtc: Save the media kind in the transceiver
authorOlivier CrĂȘte <olivier.crete@collabora.com>
Wed, 8 Jul 2020 23:13:33 +0000 (19:13 -0400)
committerSangchul Lee <sc11.lee@samsung.com>
Fri, 13 Aug 2021 09:16:08 +0000 (09:16 +0000)
Change-Id: If05ff32397a82abfab8394dbaa0209261631cea7
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1707>
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
ext/webrtc/gstwebrtcbin.c
gst-libs/gst/webrtc/rtptransceiver.h
gst-libs/gst/webrtc/webrtc_fwd.h

index da5fc17..acf409b 100644 (file)
@@ -2794,6 +2794,47 @@ _media_add_rtx (GstSDPMedia * media, WebRTCTransceiver * trans,
   }
 }
 
+static GstWebRTCKind
+_kind_from_caps (const GstCaps * caps)
+{
+  GstStructure *s;
+  const gchar *media;
+
+  if (gst_caps_get_size (caps) == 0)
+    return GST_WEBRTC_KIND_UNKNOWN;
+
+  s = gst_caps_get_structure (caps, 0);
+
+  media = gst_structure_get_string (s, "media");
+  if (media == NULL)
+    return GST_WEBRTC_KIND_UNKNOWN;
+
+  if (!g_strcmp0 (media, "audio"))
+    return GST_WEBRTC_KIND_AUDIO;
+
+  if (!g_strcmp0 (media, "video"))
+    return GST_WEBRTC_KIND_VIDEO;
+
+  return GST_WEBRTC_KIND_UNKNOWN;
+}
+
+static gboolean
+_update_transceiver_kind_from_caps (GstWebRTCRTPTransceiver * trans,
+    const GstCaps * caps)
+{
+  GstWebRTCKind kind = _kind_from_caps (caps);
+
+  if (trans->kind == kind)
+    return TRUE;
+
+  if (trans->kind == GST_WEBRTC_KIND_UNKNOWN) {
+    trans->kind = kind;
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
 static void
 _get_rtx_target_pt_and_ssrc_from_caps (GstCaps * answer_caps, gint * target_pt,
     guint * target_ssrc)
@@ -3104,6 +3145,10 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options,
       } else {
         trans = WEBRTC_TRANSCEIVER (rtp_trans);
       }
+      if (!_update_transceiver_kind_from_caps (rtp_trans, answer_caps))
+        GST_WARNING_OBJECT (webrtc,
+            "Trying to change transceiver %d kind from %d to %d",
+            rtp_trans->mline, rtp_trans->kind, _kind_from_caps (answer_caps));
 
       if (!trans->do_nack) {
         answer_caps = gst_caps_make_writable (answer_caps);
@@ -3726,6 +3771,20 @@ _update_transceiver_from_sdp_media (GstWebRTCBin * webrtc,
 
   rtp_trans->mline = media_idx;
 
+  if (!g_strcmp0 (gst_sdp_media_get_media (media), "audio")) {
+    if (rtp_trans->kind == GST_WEBRTC_KIND_VIDEO)
+      GST_FIXME_OBJECT (webrtc,
+          "Updating video transceiver to audio, which isn't fully supported.");
+    rtp_trans->kind = GST_WEBRTC_KIND_AUDIO;
+  }
+
+  if (!g_strcmp0 (gst_sdp_media_get_media (media), "video")) {
+    if (rtp_trans->kind == GST_WEBRTC_KIND_AUDIO)
+      GST_FIXME_OBJECT (webrtc,
+          "Updating audio transceiver to video, which isn't fully supported.");
+    rtp_trans->kind = GST_WEBRTC_KIND_VIDEO;
+  }
+
   for (i = 0; i < gst_sdp_media_attributes_len (media); i++) {
     const GstSDPAttribute *attr = gst_sdp_media_get_attribute (media, i);
 
@@ -4983,8 +5042,10 @@ gst_webrtc_bin_add_transceiver (GstWebRTCBin * webrtc,
       "Created new unassociated transceiver %" GST_PTR_FORMAT, trans);
 
   rtp_trans = GST_WEBRTC_RTP_TRANSCEIVER (trans);
-  if (caps)
+  if (caps) {
     rtp_trans->codec_preferences = gst_caps_ref (caps);
+    _update_transceiver_kind_from_caps (rtp_trans, caps);
+  }
 
   return gst_object_ref (trans);
 }
@@ -5845,6 +5906,12 @@ gst_webrtc_bin_request_new_pad (GstElement * element, GstPadTemplate * templ,
     }
     pad->trans = gst_object_ref (trans);
 
+    if (caps && name && !_update_transceiver_kind_from_caps (trans, caps))
+      GST_WARNING_OBJECT (webrtc,
+          "Trying to create pad %s with caps %" GST_PTR_FORMAT
+          " but transceiver %d already exists with a different"
+          " media type", name, caps, serial);
+
     pad->block_id = gst_pad_add_probe (GST_PAD (pad), GST_PAD_PROBE_TYPE_BLOCK |
         GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST,
         (GstPadProbeCallback) sink_pad_block, NULL, NULL);
index 73391f0..a14dc4a 100644 (file)
@@ -61,6 +61,13 @@ GType gst_webrtc_rtp_transceiver_get_type(void);
  *
  * Since: 1.16
  */
+/**
+ * GstWebRTCRTPTransceiver.kind:
+ *
+ * Type of media
+ *
+ * Since: 1.20
+ */
 struct _GstWebRTCRTPTransceiver
 {
   GstObject                         parent;
@@ -75,6 +82,7 @@ struct _GstWebRTCRTPTransceiver
   GstWebRTCRTPTransceiverDirection  current_direction;
 
   GstCaps                          *codec_preferences;
+  GstWebRTCKind                     kind;
 
   gpointer                          _padding[GST_PADDING];
 };
index 5c727d2..4de3412 100644 (file)
@@ -373,4 +373,21 @@ typedef enum /*<underscore_name=gst_webrtc_ice_transport_policy>*/
   GST_WEBRTC_ICE_TRANSPORT_POLICY_RELAY,
 } GstWebRTCICETransportPolicy;
 
+/**
+ * GstWebRTCKind:
+ * @GST_WEBRTC_KIND_UNKNOWN: Kind has not yet been set
+ * @GST_WEBRTC_KIND_AUDIO: Kind is audio
+ * @GST_WEBRTC_KIND_VIDEO: Kind is audio
+ *
+ * https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-kind
+ *
+ * Since: 1.20
+ */
+typedef enum /*<underscore_name=gst_webrtc_kind>*/
+{
+  GST_WEBRTC_KIND_UNKNOWN,
+  GST_WEBRTC_KIND_AUDIO,
+  GST_WEBRTC_KIND_VIDEO,
+} GstWebRTCKind;
+
 #endif /* __GST_WEBRTC_FWD_H__ */