From: Sangchul Lee Date: Thu, 22 Apr 2021 11:18:52 +0000 (+0900) Subject: Add API set for the ICE gathering state X-Git-Tag: submit/tizen/20210729.023123~78 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=16aedfc9ae8997b69178729ab710589bc6bfcb90;p=platform%2Fcore%2Fapi%2Fwebrtc.git Add API set for the ICE gathering state These correspond to the 'iceGatheringState' and 'onicegatheringstatechange' property of the RTCPeerConnection respectively. Enums are added as below. - WEBRTC_ICE_GATHERING_STATE_NEW - WEBRTC_ICE_GATHERING_STATE_GATHERING - WEBRTC_ICE_GATHERING_STATE_COMPLETE Functions are added as below. - webrtc_set[unset]_ice_gathering_state_change_cb() - webrtc_get_ice_gathering_state() [Version] 0.1.163 [Issue Type] API Change-Id: I3076aede623598d191b3792ec9cb2dcf849b325d Signed-off-by: Sangchul Lee --- diff --git a/include/webrtc.h b/include/webrtc.h index dc962eb5..1e5b1811 100644 --- a/include/webrtc.h +++ b/include/webrtc.h @@ -119,6 +119,16 @@ typedef enum { WEBRTC_SIGNALING_STATE_CLOSED, /**< Closed */ } webrtc_signaling_state_e; +/** + * @brief Enumeration for WebRTC ICE gathering state. + * @since_tizen 6.5 + */ +typedef enum { + WEBRTC_ICE_GATHERING_STATE_NEW, /**< New */ + WEBRTC_ICE_GATHERING_STATE_GATHERING, /**< Gathering */ + WEBRTC_ICE_GATHERING_STATE_COMPLETE, /**< Complete */ +} webrtc_ice_gathering_state_e; + /** * @brief Enumeration for WebRTC media source type. * @since_tizen 6.5 @@ -236,6 +246,18 @@ typedef void (*webrtc_peer_connection_state_change_cb)(webrtc_h webrtc, webrtc_p */ typedef void (*webrtc_signaling_state_change_cb)(webrtc_h webrtc, webrtc_signaling_state_e state, void *user_data); +/** + * @brief Called when the WebRTC ICE gathering state is changed. + * @since_tizen 6.5 + * @remarks The @a webrtc is the same object for which the callback was set.\nThe @a webrtc should not be released. + * @param[in] webrtc WebRTC handle + * @param[in] state The ICE gathering state + * @param[in] user_data The user data passed from the callback registration function + * @see webrtc_set_ice_gathering_state_change_cb() + * @see webrtc_unset_ice_gathering_state_change_cb() + */ +typedef void (*webrtc_ice_gathering_state_change_cb)(webrtc_h webrtc, webrtc_ice_gathering_state_e state, void *user_data); + /** * @brief Called when the buffer state of media packet source is changed. * @since_tizen 6.5 @@ -901,6 +923,52 @@ int webrtc_unset_signaling_state_change_cb(webrtc_h webrtc); */ int webrtc_get_signaling_state(webrtc_h webrtc, webrtc_signaling_state_e *state); +/** + * @brief Sets a callback function to be invoked when the WebRTC ICE gathering state is changed. + * @since_tizen 6.5 + * @param[in] webrtc WebRTC handle + * @param[in] callback Callback function pointer + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #WEBRTC_ERROR_NONE Successful + * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter + * @post webrtc_ice_gathering_state_change_cb() will be invoked. + * @see webrtc_unset_ice_gathering_state_change_cb() + * @see webrtc_ice_gathering_state_change_cb() + * @see webrtc_get_ice_gathering_state() + */ +int webrtc_set_ice_gathering_state_change_cb(webrtc_h webrtc, webrtc_ice_gathering_state_change_cb callback, void *user_data); + +/** + * @brief Unsets the ICE gathering state change callback function. + * @since_tizen 6.5 + * @param[in] webrtc WebRTC handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #WEBRTC_ERROR_NONE Successful + * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation + * @see webrtc_set_ice_gathering_state_change_cb() + * @see webrtc_get_ice_gathering_state() + */ +int webrtc_unset_ice_gathering_state_change_cb(webrtc_h webrtc); + +/** + * @brief Gets the ICE gathering state. + * @since_tizen 6.5 + * @remarks The default value is #WEBRTC_ICE_GATHERING_STATE_NEW. + * @param[in] webrtc WebRTC handle + * @param[out] state The ICE gathering state + * @return @c 0 on success, + * otherwise a negative error value + * @retval #WEBRTC_ERROR_NONE Successful + * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter + * @see webrtc_set_ice_gathering_state_change_cb() + * @see webrtc_unset_ice_gathering_state_change_cb() + */ +int webrtc_get_ice_gathering_state(webrtc_h webrtc, webrtc_ice_gathering_state_e *state); + /** * @brief Sets a negotiation needed callback function to be invoked when a change has occurred which requires session negotiation. * @since_tizen 6.5 @@ -937,6 +1005,7 @@ int webrtc_unset_negotiation_needed_cb(webrtc_h webrtc); /** * @brief Sets an ICE candidate callback function to be invoked when the WebRTC needs to send the ICE candidate message to the remote peer. * @since_tizen 6.5 + * @remarks If all the ICE candidates have been gathered, ICE gathering state will be changed to #WEBRTC_ICE_GATHERING_STATE_COMPLETE. * @param[in] webrtc WebRTC handle * @param[in] callback Callback function pointer * @param[in] user_data The user data to be passed to the callback function @@ -949,6 +1018,8 @@ int webrtc_unset_negotiation_needed_cb(webrtc_h webrtc); * @post webrtc_ice_candidate_cb() will be invoked. * @see webrtc_unset_ice_candidate_cb() * @see webrtc_ice_candidate_cb() + * @see webrtc_set_ice_gathering_state_change_cb() + * @see webrtc_get_ice_gathering_state() */ int webrtc_set_ice_candidate_cb(webrtc_h webrtc, webrtc_ice_candidate_cb callback, void *user_data); diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 3ca7165a..a56d95f7 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -357,6 +357,7 @@ typedef struct _webrtc_s { webrtc_callbacks_s state_changed_cb; webrtc_callbacks_s peer_connection_state_change_cb; webrtc_callbacks_s signaling_state_change_cb; + webrtc_callbacks_s ice_gathering_state_change_cb; webrtc_callbacks_s negotiation_needed_cb; webrtc_callbacks_s ice_candidate_cb; webrtc_callbacks_s track_added_cb; @@ -367,8 +368,8 @@ typedef struct _webrtc_s { struct { webrtc_peer_connection_state_e peer_connection_state; webrtc_signaling_state_e signaling_state; + webrtc_ice_gathering_state_e ice_gathering_state; const gchar *ice_connection_state; - const gchar *ice_gathering_state; } internal_states; #ifdef TIZEN_FEATURE_RES_MGR webrtc_resource_s resource; diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index e3d7a03a..97e08213 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.1.162 +Version: 0.1.163 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc.c b/src/webrtc.c index f00b5c22..102756c4 100644 --- a/src/webrtc.c +++ b/src/webrtc.c @@ -719,6 +719,69 @@ int webrtc_get_signaling_state(webrtc_h webrtc, webrtc_signaling_state_e *state) return WEBRTC_ERROR_NONE; } +int webrtc_set_ice_gathering_state_change_cb(webrtc_h webrtc, webrtc_ice_gathering_state_change_cb callback, void *user_data) +{ + webrtc_s *_webrtc = (webrtc_s*)webrtc; + + RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(callback == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "callback is NULL"); + + g_mutex_lock(&_webrtc->mutex); + + RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be IDLE"); + + LOG_WARNING_IF_CALLBACK_EXISTS(_webrtc->ice_gathering_state_change_cb); + + _webrtc->ice_gathering_state_change_cb.callback = callback; + _webrtc->ice_gathering_state_change_cb.user_data = user_data; + + LOG_INFO("callback[%p] user_data[%p]", callback, user_data); + + g_mutex_unlock(&_webrtc->mutex); + + return WEBRTC_ERROR_NONE; +} + +int webrtc_unset_ice_gathering_state_change_cb(webrtc_h webrtc) +{ + webrtc_s *_webrtc = (webrtc_s*)webrtc; + + RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + + g_mutex_lock(&_webrtc->mutex); + + RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be IDLE"); + RET_VAL_WITH_UNLOCK_IF(_webrtc->ice_gathering_state_change_cb.callback == NULL, WEBRTC_ERROR_INVALID_OPERATION, &_webrtc->mutex, "callback was not set"); + + LOG_INFO("callback[%p] user_data[%p] is reset to NULL", + _webrtc->ice_gathering_state_change_cb.callback, _webrtc->ice_gathering_state_change_cb.user_data); + + _webrtc->ice_gathering_state_change_cb.callback = NULL; + _webrtc->ice_gathering_state_change_cb.user_data = NULL; + + g_mutex_unlock(&_webrtc->mutex); + + return WEBRTC_ERROR_NONE; +} + +int webrtc_get_ice_gathering_state(webrtc_h webrtc, webrtc_ice_gathering_state_e *state) +{ + webrtc_s *_webrtc = (webrtc_s*)webrtc; + + RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(state == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "state is NULL"); + + g_mutex_lock(&_webrtc->mutex); + + *state = _webrtc->internal_states.ice_gathering_state; + + LOG_INFO("state[%d]", *state); + + g_mutex_unlock(&_webrtc->mutex); + + return WEBRTC_ERROR_NONE; +} + int webrtc_set_negotiation_needed_cb(webrtc_h webrtc, webrtc_negotiation_needed_cb callback, void *user_data) { webrtc_s *_webrtc = (webrtc_s*)webrtc; diff --git a/src/webrtc_private.c b/src/webrtc_private.c index 88c23f68..2439a695 100644 --- a/src/webrtc_private.c +++ b/src/webrtc_private.c @@ -41,6 +41,11 @@ typedef struct { webrtc_signaling_state_e state; } signaling_state_info_s; +typedef struct { + const char *str; + webrtc_ice_gathering_state_e state; +} ice_gathering_state_info_s; + static direction_info_s __direction_info[] = { [WEBRTC_TRANSCEIVER_DIRECTION_SENDONLY] = { "SENDONLY", GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY }, [WEBRTC_TRANSCEIVER_DIRECTION_RECVONLY] = { "RECVONLY", GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY }, @@ -65,6 +70,12 @@ static signaling_state_info_s __signaling_state_info[] = { [GST_WEBRTC_SIGNALING_STATE_CLOSED] = { "CLOSED", WEBRTC_SIGNALING_STATE_CLOSED }, }; +static ice_gathering_state_info_s __ice_gathering_state_info[] = { + [GST_WEBRTC_ICE_GATHERING_STATE_NEW] = { "NEW", WEBRTC_ICE_GATHERING_STATE_NEW }, + [GST_WEBRTC_ICE_GATHERING_STATE_GATHERING] = { "GATHERING", WEBRTC_ICE_GATHERING_STATE_GATHERING }, + [GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE] = { "COMPLETE", WEBRTC_ICE_GATHERING_STATE_COMPLETE }, +}; + static const char *__get_error_string(webrtc_error_e error) { switch (error) { @@ -264,6 +275,23 @@ static void __invoke_signaling_state_change_cb(webrtc_s *webrtc, GstWebRTCPeerCo GENERATE_DOT(webrtc, "SIGNALING_STATE_%s", __signaling_state_info[state].str); } +static void __invoke_ice_gathering_state_change_cb(webrtc_s *webrtc, GstWebRTCICEGatheringState state) +{ + webrtc_callbacks_s *cb; + + RET_IF(webrtc == NULL, "webrtc is NULL"); + + cb = &webrtc->ice_gathering_state_change_cb; + + if (cb->callback) { + LOG_DEBUG(">>> callback[%p], user_data[%p]", cb->callback, cb->user_data); + ((webrtc_ice_gathering_state_change_cb)(cb->callback))((webrtc_h)webrtc, __ice_gathering_state_info[state].state, cb->user_data); + LOG_DEBUG("<<< end of the callback"); + } + + GENERATE_DOT(webrtc, "ICE_GATHERING_STATE_%s", __ice_gathering_state_info[state].str); +} + static gboolean __bus_watch_cb(GstBus *bus, GstMessage *message, gpointer user_data) { webrtc_s *webrtc = (webrtc_s *)user_data; @@ -709,31 +737,17 @@ static void __webrtcbin_signaling_state_cb(GstElement *webrtcbin, GParamSpec * p static void __webrtcbin_ice_gathering_state_cb(GstElement *webrtcbin, GParamSpec * pspec, gpointer user_data) { webrtc_s *webrtc = (webrtc_s *)user_data; - GstWebRTCICEGatheringState ice_gathering_state; - const gchar *new_state = "UNKNOWN"; + GstWebRTCICEGatheringState state; RET_IF(webrtcbin == NULL, "webrtcbin is NULL"); RET_IF(webrtc == NULL, "webrtc is NULL"); - g_object_get(webrtcbin, "ice-gathering-state", &ice_gathering_state, NULL); - - switch (ice_gathering_state) { - case GST_WEBRTC_ICE_GATHERING_STATE_NEW: - new_state = "NEW"; - break; - - case GST_WEBRTC_ICE_GATHERING_STATE_GATHERING: - new_state = "GATHERING"; - break; - - case GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE: - new_state = "COMPLETE"; - break; - } + g_object_get(webrtcbin, "ice-gathering-state", &state, NULL); - LOG_DEBUG("[IceGatheringState] is changed to [%s]", new_state); + LOG_DEBUG("[IceGatheringState] is changed to [%s]", __ice_gathering_state_info[state].str); + webrtc->internal_states.ice_gathering_state = __ice_gathering_state_info[state].state; - webrtc->internal_states.ice_gathering_state = new_state; + __invoke_ice_gathering_state_change_cb(webrtc, state); } static void __webrtcbin_ice_connection_state_cb(GstElement *webrtcbin, GParamSpec * pspec, gpointer user_data)