webrtc_private: Add structure for data recovery types and update it 16/267516/7
authorSangchul Lee <sc11.lee@samsung.com>
Mon, 6 Dec 2021 11:07:29 +0000 (20:07 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Mon, 13 Dec 2021 06:03:07 +0000 (15:03 +0900)
It is updated from remote offer description. And it'll be used to
determine to enable the recovery mechanism for answerer.

[Version] 0.3.19
[Issue Type] Improvement

Change-Id: I35716c66381cfae8931f17b07817d0c93f52395b
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc_private.c

index 9cc3d4da1036dd6e601d60f8eb78feaf800ee8ce..038d5613f93b9856e1ddf639666d35d24d4de646 100644 (file)
@@ -239,6 +239,7 @@ do { \
 #define WEBRTC_DISPLAY_TYPE_ECORE_WL    2
 #define PAYLOAD_ID_BITS                 32 /* 96 ~ 127 */
 #define TRACK_ID_THRESHOLD_OF_LOOPBACK  100
+#define MAX_MLINE_NUM                   16
 
 /* NOTE : GstAutoplugSelectResult is defined in gstplay-enum.h but not exposed
  We are defining our own and will be removed when it actually exposed */
@@ -395,6 +396,11 @@ typedef struct _webrtc_gst_s {
        GHashTable *sink_slots;
 } webrtc_gst_s;
 
+typedef struct _webrtc_data_recovery_type_s {
+       bool red;
+       bool ulpfec;
+} webrtc_data_recovery_type_s;
+
 typedef struct _webrtc_negotiation_states_s {
        webrtc_peer_connection_state_e peer_connection_state;
        webrtc_signaling_state_e signaling_state;
@@ -419,6 +425,8 @@ typedef struct _webrtc_s {
        gchar *desc_offer;
        gchar *desc_answer;
 
+       webrtc_data_recovery_type_s data_recovery_types[MAX_MLINE_NUM];
+
        webrtc_state_e state;
        webrtc_state_e pend_state;
 
index 229a3658b5da0ceeafcc7d4c5399d954f4c9a7ce..2d9e59bc4719c557773ae5e6035cb9241a1701f5 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.3.18
+Version:    0.3.19
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 31db65c888a90ccd031e73ef4bf082c4ffc06d27..b14ef2ef9d05f24cd39c6ce6a8aff8d4a5f6a5f9 100644 (file)
@@ -205,6 +205,62 @@ static gchar *__make_ice_candidate_message(guint mlineindex, gchar *candidate)
        return text;
 }
 
+static GstSDPMessage* __webrtcbin_get_description(GstElement *webrtcbin, bool is_remote)
+{
+       GstWebRTCSessionDescription *desc;
+       const char *desc_type = is_remote ? "remote-description" : "local-description";
+
+       RET_VAL_IF(webrtcbin == NULL, NULL, "webrtcbin is NULL");
+
+       g_object_get(webrtcbin, desc_type, &desc, NULL);
+       RET_VAL_IF(desc == NULL, NULL, "%s is NULL", desc_type);
+
+       LOG_DEBUG("%s: type[%d], sdp[%p]", desc_type, desc->type, (void*)desc->sdp);
+
+       return desc->sdp;
+}
+
+static void __update_data_recovery_type_from_remote_offer_description(webrtc_s *webrtc)
+{
+       guint i, j;
+       guint attr_length;
+       GstSDPMessage *msg;
+       const GstSDPMedia *media;
+       const GstSDPAttribute *attr;
+
+       RET_IF(webrtc == NULL, "webrtc is NULL");
+
+       msg = __webrtcbin_get_description(webrtc->gst.webrtcbin, true);
+       RET_IF(msg == NULL, "msg is NULL");
+
+       for (i = 0; i < gst_sdp_message_medias_len(msg); i++) {
+               if (i == MAX_MLINE_NUM) {
+                       LOG_ERROR("reach to max mline num[%u]", i);
+                       break;
+               }
+               media = gst_sdp_message_get_media(msg, i);
+               LOG_DEBUG("mline[%u] media[%s, protocol:%s]", i, media->media, media->proto);
+               memset(&webrtc->data_recovery_types[i], 0, sizeof(webrtc_data_recovery_type_s));
+
+               attr_length = gst_sdp_media_attributes_len(media);
+               for (j = 0; j < attr_length; j++) {
+                       attr = gst_sdp_media_get_attribute(media, j);
+                       if (!strcmp(attr->key, "rtpmap")) {
+                               if (g_strrstr(attr->value, "red/")) {
+                                       webrtc->data_recovery_types[i].red = true;
+                                       LOG_INFO(" RED is set [key:%s, value:%s]", attr->key, attr->value);
+                                       continue;
+                               }
+                               if (g_strrstr(attr->value, "ulpfec/")) {
+                                       webrtc->data_recovery_types[i].ulpfec = true;
+                                       LOG_INFO(" ULPFEC is set [key:%s, value:%s]", attr->key, attr->value);
+                                       continue;
+                               }
+                       }
+               }
+       }
+}
+
 static bool __meet_gst_state(webrtc_state_e state, GstState gst_state)
 {
        if (state == WEBRTC_STATE_IDLE && gst_state == GST_STATE_READY)
@@ -912,6 +968,9 @@ static void __webrtcbin_signaling_state_cb(GstElement *webrtcbin, GParamSpec * p
        LOG_DEBUG("webrtc[%p] [SignalingState] is changed to [%s]", webrtc, __signaling_state_info[state].str);
        webrtc->negotiation_states.signaling_state = __signaling_state_info[state].state;
 
+       if (state == GST_WEBRTC_SIGNALING_STATE_HAVE_REMOTE_OFFER)
+               __update_data_recovery_type_from_remote_offer_description(webrtc);
+
        __post_signaling_state_change_cb_in_idle(webrtc, state);
 }
 
@@ -1191,8 +1250,9 @@ static void __webrtcbin_on_new_transceiver_cb(GstElement *webrtcbin, GstWebRTCRT
        RET_IF(transceiver == NULL, "transceiver is NULL");
        RET_IF(webrtc == NULL, "webrtc is NULL");
 
-       LOG_INFO("webrtc[%p] new transceiver[%p, mline:%u, mid:%s, direction:%d] user_data[%p]",
-               webrtc, transceiver, transceiver->mline, transceiver->mid, transceiver->direction, user_data);
+       LOG_INFO("webrtc[%p] new transceiver[%p, mline:%u, mid:%s, direction:%d, kind:%d] user_data[%p]",
+               webrtc, transceiver, transceiver->mline, transceiver->mid, transceiver->direction, transceiver->kind, user_data);
+       PRINT_CAPS(transceiver->codec_preferences, "codec preferences");
 
        if (g_hash_table_size(webrtc->gst.source_slots) == 0) {
                /* In this case, it might be an answerer without setting any media source.