Add new state for negotiation stage 34/244034/8
authorSangchul Lee <sc11.lee@samsung.com>
Mon, 14 Sep 2020 07:52:18 +0000 (16:52 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 24 Sep 2020 07:11:22 +0000 (07:11 +0000)
WEBRTC_STATE_NEGOTIATING is added.

[Version] 0.1.22
[Issue Type] API

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

index 1af37c058b9147d47316236c99b3e89e1a95da6e..4f5bbc772e4ce203ec58c9d8df6618cb0e790700 100644 (file)
@@ -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);
 
index 1d5a517fe9fe8c2f6ba7ae486a75cae9b7e7e520..e0a53370effaf045597c792fd9f9dc88901eb966 100644 (file)
@@ -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
index 29490e9c71c82d98422735c3c460f15dd9d9b64c..3d4f54d7583883b39c40c5ef72ed59783509e7b0 100644 (file)
@@ -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);
 
index 47930ea6373c090dc038144850b87e146fa8cf1b..8e16b46313711807f808d516045a88770c775ad9 100644 (file)
@@ -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;