From: Sangchul Lee Date: Mon, 14 Sep 2020 07:52:18 +0000 (+0900) Subject: Add new state for negotiation stage X-Git-Tag: submit/tizen/20210729.023123~220 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e562e46c3120fd0c46d184c9c97a56b0016e8ba0;p=platform%2Fcore%2Fapi%2Fwebrtc.git Add new state for negotiation stage WEBRTC_STATE_NEGOTIATING is added. [Version] 0.1.22 [Issue Type] API Change-Id: Ibedaadb1f82e5482174da6d85f46e7f42073cd8a Signed-off-by: Sangchul Lee --- diff --git a/include/webrtc.h b/include/webrtc.h index 1af37c05..4f5bbc77 100644 --- a/include/webrtc.h +++ b/include/webrtc.h @@ -65,8 +65,9 @@ typedef enum */ typedef enum { - WEBRTC_STATE_IDLE, /**< Created but not started */ - WEBRTC_STATE_PLAYING, /**< Started */ + WEBRTC_STATE_IDLE, /**< Created but not started */ + WEBRTC_STATE_NEGOTIATING, /**< Started but negotiation stage */ + WEBRTC_STATE_PLAYING, /**< Started all streams */ } webrtc_state_e; /** @@ -213,7 +214,7 @@ int webrtc_create(webrtc_h *webrtc); * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE. - * @post @a webrtc state will be #WEBRTC_STATE_PLAYING. + * @post @a webrtc state will be #WEBRTC_STATE_NEGOTIATING. * @see webrtc_create() * @see webrtc_stop() */ @@ -229,7 +230,7 @@ int webrtc_start(webrtc_h webrtc); * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state - * @pre @a webrtc state will be #WEBRTC_STATE_PLAYING. + * @pre @a webrtc state must be set to #WEBRTC_STATE_NEGOTIATING or #WEBRTC_STATE_PLAYING. * @post @a webrtc state will be #WEBRTC_STATE_IDLE. * @see webrtc_create() * @see webrtc_start() @@ -388,7 +389,7 @@ int webrtc_unset_ice_candidate_cb(webrtc_h webrtc); * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state - * @pre @a webrtc state must be set to #WEBRTC_STATE_PLAYING. + * @pre @a webrtc state must be set to #WEBRTC_STATE_NEGOTIATING. * @see webrtc_negotiation_needed_cb() * @see webrtc_set_local_description() */ @@ -406,7 +407,7 @@ int webrtc_create_offer(webrtc_h webrtc, char **offer); * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state - * @pre @a webrtc state must be set to #WEBRTC_STATE_PLAYING. + * @pre @a webrtc state must be set to #WEBRTC_STATE_NEGOTIATING. * @see webrtc_set_local_description() */ int webrtc_create_answer(webrtc_h webrtc, char **answer); @@ -424,7 +425,7 @@ int webrtc_create_answer(webrtc_h webrtc, char **answer); * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state - * @pre @a webrtc state must be set to #WEBRTC_STATE_PLAYING. + * @pre @a webrtc state must be set to #WEBRTC_STATE_NEGOTIATING. * @see webrtc_create_offer() * @see webrtc_create_answer() */ @@ -443,7 +444,7 @@ int webrtc_set_local_description(webrtc_h webrtc, const char *description); * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state - * @pre @a webrtc state must be set to #WEBRTC_STATE_PLAYING. + * @pre @a webrtc state must be set to #WEBRTC_STATE_NEGOTIATING. */ int webrtc_set_remote_description(webrtc_h webrtc, const char *description); @@ -460,7 +461,7 @@ int webrtc_set_remote_description(webrtc_h webrtc, const char *description); * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state - * @pre @a webrtc state must be set to #WEBRTC_STATE_PLAYING. + * @pre @a webrtc state must be set to #WEBRTC_STATE_NEGOTIATING. */ int webrtc_add_ice_candidate(webrtc_h webrtc, const char *candidate); diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 1d5a517f..e0a53370 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.21 +Version: 0.1.22 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc.c b/src/webrtc.c index 29490e9c..3d4f54d7 100644 --- a/src/webrtc.c +++ b/src/webrtc.c @@ -172,7 +172,7 @@ int webrtc_start(webrtc_h webrtc) RET_VAL_WITH_UNLOCK_IF(_webrtc->gst.webrtcbin == NULL, WEBRTC_ERROR_INVALID_OPERATION, &_webrtc->mutex, "webrtcbin is NULL"); _gst_pipeline_set_state(webrtc, GST_STATE_PLAYING); - _webrtc->pend_state = WEBRTC_STATE_PLAYING; + _webrtc->pend_state = WEBRTC_STATE_NEGOTIATING; g_mutex_unlock(&_webrtc->mutex); @@ -189,7 +189,7 @@ int webrtc_stop(webrtc_h webrtc) g_mutex_lock(&_webrtc->mutex); - RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be PLAYING"); + RET_VAL_WITH_UNLOCK_IF(_webrtc->state == WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should not be IDLE"); _gst_pipeline_set_state(webrtc, GST_STATE_READY); _webrtc->pend_state = WEBRTC_STATE_IDLE; @@ -379,7 +379,7 @@ int webrtc_create_offer(webrtc_h webrtc, char **offer) g_mutex_lock(&_webrtc->mutex); - RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be PLAYING"); + RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_NEGOTIATING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be NEGOTIATING"); LOG_INFO("offer[%p]", offer); @@ -400,7 +400,7 @@ int webrtc_create_answer(webrtc_h webrtc, char **answer) g_mutex_lock(&_webrtc->mutex); - RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be PLAYING"); + RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_NEGOTIATING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be NEGOTIATING"); /* FIXME: remote description should be set before this API */ LOG_INFO("answer[%p]", answer); @@ -422,7 +422,7 @@ int webrtc_set_local_description(webrtc_h webrtc, const char *description) g_mutex_lock(&_webrtc->mutex); - RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be PLAYING"); + RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_NEGOTIATING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be NEGOTIATING"); LOG_INFO("description[ %s ]", description); @@ -443,7 +443,7 @@ int webrtc_set_remote_description(webrtc_h webrtc, const char *description) g_mutex_lock(&_webrtc->mutex); - RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be PLAYING"); + RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_NEGOTIATING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be NEGOTIATING"); LOG_INFO("description[ %s ]", description); @@ -464,7 +464,7 @@ int webrtc_add_ice_candidate(webrtc_h webrtc, const char *candidate) g_mutex_lock(&_webrtc->mutex); - RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be PLAYING"); + RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_NEGOTIATING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be NEGOTIATING"); LOG_INFO("candidate[ %s ]", candidate); diff --git a/src/webrtc_private.c b/src/webrtc_private.c index 47930ea6..8e16b463 100644 --- a/src/webrtc_private.c +++ b/src/webrtc_private.c @@ -92,6 +92,12 @@ do { \ } \ } while (0) +static const char* __state_str[] = { + "IDLE", + "NEGOTIATING", + "PLAYING", +}; + /* Use g_free() to release the return value. */ static gchar* __get_string_from_json_object(JsonObject *object) { @@ -175,12 +181,25 @@ static gboolean __meet_gst_state(webrtc_state_e state, GstState gst_state) if (state == WEBRTC_STATE_IDLE && gst_state == GST_STATE_READY) return TRUE; - if (state == WEBRTC_STATE_PLAYING && gst_state == GST_STATE_PLAYING) + if (state == WEBRTC_STATE_NEGOTIATING && gst_state == GST_STATE_PLAYING) return TRUE; return FALSE; } +static void __invoke_state_changed_cb(webrtc_s *webrtc, webrtc_state_e old, webrtc_state_e new) +{ + RET_IF(webrtc == NULL, "webrtc is NULL"); + + LOG_INFO("state is changed [%s] -> [%s]", __state_str[old], __state_str[new]); + + if (webrtc->state_changed_cb.callback) { + LOG_DEBUG(">>> callback[%p], user_data[%p]", webrtc->state_changed_cb.callback, webrtc->state_changed_cb.user_data); + ((webrtc_state_changed_cb)(webrtc->state_changed_cb.callback))((webrtc_h)webrtc, old, new, webrtc->state_changed_cb.user_data); + LOG_DEBUG("<<< end of the callback"); + } +} + static gboolean __bus_watch_cb(GstBus *bus, GstMessage *message, gpointer user_data) { webrtc_s *webrtc = (webrtc_s *)user_data; @@ -236,23 +255,16 @@ static gboolean __bus_watch_cb(GstBus *bus, GstMessage *message, gpointer user_d g_mutex_lock(&webrtc->mutex); if (webrtc->pend_state == webrtc->state) { - LOG_DEBUG("pend_state(%d) is same with current state(%d)", webrtc->pend_state, webrtc->state); + LOG_DEBUG("pend_state[%s] is same with current state", __state_str[webrtc->pend_state]); g_mutex_unlock(&webrtc->mutex); break; } if (__meet_gst_state(webrtc->pend_state, gst_state_new)) { webrtc_state_e old_state = webrtc->state; - - LOG_INFO("webrtc state is changed [%d] -> [%d]", webrtc->state, webrtc->pend_state); webrtc->state = webrtc->pend_state; - if (webrtc->state_changed_cb.callback) { - LOG_DEBUG(">>> invoke state_changed_cb[%p], user_data[%p]", - webrtc->state_changed_cb.callback, webrtc->state_changed_cb.user_data); - ((webrtc_state_changed_cb)(webrtc->state_changed_cb.callback))((webrtc_h)webrtc, old_state, webrtc->state, webrtc->state_changed_cb.user_data); - LOG_DEBUG("<<< end of the callback"); - } + __invoke_state_changed_cb(webrtc, old_state, webrtc->state); } g_mutex_unlock(&webrtc->mutex); @@ -536,19 +548,30 @@ static void __webrtcbin_peer_connection_state_cb(GstElement *webrtcbin, GParamSp switch (peer_connection_state) { case GST_WEBRTC_PEER_CONNECTION_STATE_NEW: new_state = "NEW"; + if (webrtc->state == WEBRTC_STATE_NEGOTIATING) { + webrtc_state_e old_state = webrtc->state; + webrtc->state = webrtc->pend_state = WEBRTC_STATE_PLAYING; + __invoke_state_changed_cb(webrtc, old_state, webrtc->state); + } break; + case GST_WEBRTC_PEER_CONNECTION_STATE_CONNECTING: new_state = "CONNECTING"; break; + case GST_WEBRTC_PEER_CONNECTION_STATE_CONNECTED: new_state = "CONNECTED"; break; + + /* FIXME: error forwarding in case of disconnection/failed via error callback */ case GST_WEBRTC_PEER_CONNECTION_STATE_DISCONNECTED: new_state = "DISCONNECTED"; break; + case GST_WEBRTC_PEER_CONNECTION_STATE_FAILED: new_state = "FAILED"; break; + case GST_WEBRTC_PEER_CONNECTION_STATE_CLOSED: new_state = "CLOSED"; break; @@ -572,18 +595,23 @@ static void __webrtcbin_signaling_state_cb(GstElement *webrtcbin, GParamSpec * p case GST_WEBRTC_SIGNALING_STATE_STABLE: new_state = "STABLE"; break; + case GST_WEBRTC_SIGNALING_STATE_CLOSED: new_state = "CLOSED"; break; + case GST_WEBRTC_SIGNALING_STATE_HAVE_LOCAL_OFFER: new_state = "HAVE_LOCAL_OFFER"; break; + case GST_WEBRTC_SIGNALING_STATE_HAVE_REMOTE_OFFER: new_state = "HAVE_REMOTE_OFFER"; break; + case GST_WEBRTC_SIGNALING_STATE_HAVE_LOCAL_PRANSWER: new_state = "HAVE_LOCAL_PRANSWER"; break; + case GST_WEBRTC_SIGNALING_STATE_HAVE_REMOTE_PRANSWER: new_state = "HAVE_REMOTE_PRANSWER"; break; @@ -607,9 +635,11 @@ static void __webrtcbin_ice_gathering_state_cb(GstElement *webrtcbin, GParamSpec 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; @@ -633,21 +663,27 @@ static void __webrtcbin_ice_connection_state_cb(GstElement *webrtcbin, GParamSpe case GST_WEBRTC_ICE_CONNECTION_STATE_NEW: new_state = "NEW"; break; + case GST_WEBRTC_ICE_CONNECTION_STATE_CHECKING: new_state = "CHECKING"; break; + case GST_WEBRTC_ICE_CONNECTION_STATE_CONNECTED: new_state = "CONNECTED"; break; + case GST_WEBRTC_ICE_CONNECTION_STATE_COMPLETED: new_state = "COMPLETED"; break; + case GST_WEBRTC_ICE_CONNECTION_STATE_FAILED: new_state = "FAILED"; break; + case GST_WEBRTC_ICE_CONNECTION_STATE_DISCONNECTED: new_state = "DISCONNECTED"; break; + case GST_WEBRTC_ICE_CONNECTION_STATE_CLOSED: new_state = "CLOSED"; break;