From: Sangchul Lee Date: Mon, 6 Dec 2021 11:07:29 +0000 (+0900) Subject: webrtc_private: Add structure for data recovery types and update it X-Git-Tag: submit/tizen/20211216.092652~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b0e5c2af519695c0093711577243a344ee1daa58;p=platform%2Fcore%2Fapi%2Fwebrtc.git webrtc_private: Add structure for data recovery types and update it 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 --- diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 9cc3d4da..038d5613 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -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; diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 229a3658..2d9e59bc 100644 --- a/packaging/capi-media-webrtc.spec +++ b/packaging/capi-media-webrtc.spec @@ -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 diff --git a/src/webrtc_private.c b/src/webrtc_private.c index 31db65c8..b14ef2ef 100644 --- a/src/webrtc_private.c +++ b/src/webrtc_private.c @@ -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.