Functions are added as below.
- webrtc_create_offer_async()
- webrtc_create_answer_async()
[Version] 0.2.91
[Issue Type] API
Change-Id: I5641f98fcd272ddd52f5173c048a9db3a94a9222
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
*/
typedef void (*webrtc_state_changed_cb)(webrtc_h webrtc, webrtc_state_e previous, webrtc_state_e current, void *user_data);
+/**
+ * @brief Called when the session description is created.
+ * @since_tizen 6.5
+ * @remarks The @a webrtc is the same object for which the callback was set.\n
+ * The @a webrtc should not be released.\n
+ * @a description is a JSON string.\n
+ * It will be {"sdp":{"type":"offer or answer","sdp":"..."}}.
+ * @param[in] webrtc WebRTC handle
+ * @param[in] description The session description
+ * @param[in] user_data The user data passed from the callback registration function
+ * @post @a description must be set as a local description by calling webrtc_set_local_description()
+ * @post @a description must be sent to the remote peer via the signaling channel.
+ * @see webrtc_create_offer_async()
+ * @see webrtc_create_answer_async()
+ * @see webrtc_set_local_description()
+ */
+typedef void (*webrtc_session_description_created_cb)(webrtc_h webrtc, const char *description, void *user_data);
+
/**
* @brief Called when the WebRTC peer connection state is changed.
* @since_tizen 6.5
* @see webrtc_state_changed_cb()
* @see webrtc_get_state()
* @see webrtc_create_offer()
+ * @see webrtc_create_offer_async()
*/
int webrtc_set_state_changed_cb(webrtc_h webrtc, webrtc_state_changed_cb callback, void *user_data);
*/
int webrtc_create_answer(webrtc_h webrtc, bundle *options, char **answer);
+/**
+ * @brief Creates SDP offer asynchronously to start a new WebRTC connection to a remote peer.
+ * @since_tizen 6.5
+ * @remarks The registered callback will be invoked in the main thread.\n
+ * The @a options currently has no effect.
+ * @param[in] webrtc WebRTC handle
+ * @param[in] options Configuration options for the offer (optional, this can be NULL)
+ * @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
+ * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state
+ * @pre @a webrtc state must be set to #WEBRTC_STATE_NEGOTIATING.
+ * @post webrtc_session_description_created_cb() will be invoked.
+ * @see webrtc_state_changed_cb()
+ * @see webrtc_negotiation_needed_cb()
+ * @see webrtc_set_local_description()
+ * @see webrtc_session_description_created_cb()
+ */
+int webrtc_create_offer_async(webrtc_h webrtc, bundle *options, webrtc_session_description_created_cb callback, void *user_data);
+
+/**
+ * @brief Creates SDP answer asynchronously to an offer received from a remote peer during the negotiation of a WebRTC connection.
+ * @since_tizen 6.5
+ * @remarks The registered callback will be invoked in the main thread.\n
+ * The @a options currently has no effect.
+ * @param[in] webrtc WebRTC handle
+ * @param[in] options Configuration options for the answer (optional, this can be NULL)
+ * @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
+ * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state
+ * @pre @a webrtc state must be set to #WEBRTC_STATE_NEGOTIATING.
+ * @pre The remote SDP offer must be set by calling webrtc_set_remote_description().
+ * @pre The signaling state must be set to #WEBRTC_SIGNALING_STATE_HAVE_REMOTE_OFFER.
+ * @post webrtc_session_description_created_cb() will be invoked.
+ * @see webrtc_set_remote_description()
+ * @see webrtc_set_local_description()
+ * @see webrtc_get_signaling_state()
+ * @see webrtc_set_signaling_state_change_cb()
+ * @see webrtc_session_description_created_cb()
+ */
+int webrtc_create_answer_async(webrtc_h webrtc, bundle *options, webrtc_session_description_created_cb callback, void *user_data);
+
/**
* @brief Sets the session description for a local peer associated with a WebRTC connection.
* @since_tizen 6.5
* @retval #WEBRTC_ERROR_INVALID_STATE Invalid state
* @pre @a webrtc state must be set to #WEBRTC_STATE_NEGOTIATING.
* @see webrtc_create_offer()
+ * @see webrtc_create_offer_async()
* @see webrtc_create_answer()
+ * @see webrtc_create_answer_async()
* @see webrtc_set_signaling_state_change_cb()
* @see webrtc_get_signaling_state()
*/
void _release_tbm_bo(webrtc_tbm_s *tbm, void *bo);
int _webrtcbin_create_session_description(webrtc_s *webrtc, bool is_offer, char **desc);
+int _webrtcbin_create_session_description_async(webrtc_s *webrtc, bool is_offer, webrtc_session_description_created_cb callback, void *user_data);
int _webrtcbin_set_session_description(webrtc_s *webrtc, const char *description, bool is_remote);
int _webrtcbin_add_ice_candidate(webrtc_s *webrtc, const char *candidate);
void _webrtcbin_on_data_channel_cb(GstElement *webrtcbin, GObject *data_channel, gpointer user_data);
Name: capi-media-webrtc
Summary: A WebRTC library in Tizen Native API
-Version: 0.2.90
+Version: 0.2.91
Release: 0
Group: Multimedia/API
License: Apache-2.0
return _webrtcbin_create_session_description(webrtc, false, answer);
}
+int webrtc_create_offer_async(webrtc_h webrtc, bundle *options, webrtc_session_description_created_cb callback, void *user_data)
+{
+ g_autoptr(GMutexLocker) locker = NULL;
+ 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");
+
+ locker = g_mutex_locker_new(&_webrtc->mutex);
+
+ RET_VAL_IF(_webrtc->state != WEBRTC_STATE_NEGOTIATING, WEBRTC_ERROR_INVALID_STATE, "the state should be NEGOTIATING");
+
+ return _webrtcbin_create_session_description_async(webrtc, true, callback, user_data);
+}
+
+int webrtc_create_answer_async(webrtc_h webrtc, bundle *options, webrtc_session_description_created_cb callback, void *user_data)
+{
+ g_autoptr(GMutexLocker) locker = NULL;
+ 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");
+
+ locker = g_mutex_locker_new(&_webrtc->mutex);
+
+ RET_VAL_IF(_webrtc->state != WEBRTC_STATE_NEGOTIATING, WEBRTC_ERROR_INVALID_STATE, "the state should be NEGOTIATING");
+ RET_VAL_IF(!_webrtcbin_have_remote_offer(_webrtc), WEBRTC_ERROR_INVALID_STATE, "remote offer should be set");
+
+ return _webrtcbin_create_session_description_async(webrtc, false, callback, user_data);
+}
+
int webrtc_set_local_description(webrtc_h webrtc, const char *description)
{
g_autoptr(GMutexLocker) locker = NULL;
} new;
} idle_userdata_s;
+typedef struct _description_created_userdata {
+ webrtc_s *webrtc;
+ webrtc_session_description_created_cb callback;
+ void *user_data;
+} description_created_userdata;
+
static gboolean __idle_cb(gpointer user_data)
{
idle_userdata_s *data = (idle_userdata_s*)user_data;
static void __offer_created_cb(GstPromise *promise, gpointer user_data)
{
- webrtc_s *webrtc = (webrtc_s *)user_data;
+ description_created_userdata *data = (description_created_userdata *)user_data;
+ webrtc_s *webrtc;
- RET_IF(promise == NULL, "promise is NULL");
- RET_IF(webrtc == NULL, "webrtc is NULL");
+ RET_IF(data == NULL, "data is NULL");
+
+ if (!(webrtc = data->webrtc)) {
+ LOG_ERROR("webrtc is NULL");
+ g_free(data);
+ return;
+ }
LOG_DEBUG_ENTER();
__update_session_description(promise, true, webrtc);
+ if (data->callback) {
+ LOG_DEBUG(">>> callback[%p], user_data[%p]", data->callback, data->user_data);
+ ((webrtc_session_description_created_cb)(data->callback))((webrtc_h)webrtc, webrtc->desc_offer, data->user_data);
+ LOG_DEBUG("<<< end of the callback");
+ g_mutex_unlock(&webrtc->desc_mutex);
- g_cond_signal(&webrtc->desc_cond);
+ } else {
+ g_cond_signal(&webrtc->desc_cond);
+ }
LOG_DEBUG_LEAVE();
+
+ g_free(data);
}
static void __answer_created_cb(GstPromise *promise, gpointer user_data)
{
- webrtc_s *webrtc = (webrtc_s *)user_data;
+ description_created_userdata *data = (description_created_userdata *)user_data;
+ webrtc_s *webrtc;
- RET_IF(promise == NULL, "promise is NULL");
- RET_IF(webrtc == NULL, "webrtc is NULL");
+ RET_IF(data == NULL, "data is NULL");
+
+ if (!(webrtc = data->webrtc)) {
+ LOG_ERROR("webrtc is NULL");
+ g_free(data);
+ return;
+ }
LOG_DEBUG_ENTER();
__update_session_description(promise, false, webrtc);
- g_cond_signal(&webrtc->desc_cond);
+ if (data->callback) {
+ LOG_DEBUG(">>> callback[%p], user_data[%p]", data->callback, data->user_data);
+ ((webrtc_session_description_created_cb)(data->callback))((webrtc_h)webrtc, webrtc->desc_answer, data->user_data);
+ LOG_DEBUG("<<< end of the callback");
+ g_mutex_unlock(&webrtc->desc_mutex);
+
+ } else {
+ g_cond_signal(&webrtc->desc_cond);
+ }
LOG_DEBUG_LEAVE();
+
+ g_free(data);
}
int _webrtcbin_create_session_description(webrtc_s *webrtc, bool is_offer, char **desc)
{
GstPromise *promise;
+ description_created_userdata *data;
gint64 end_time;
RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
g_mutex_lock(&webrtc->desc_mutex);
- promise = gst_promise_new_with_change_func(is_offer ? __offer_created_cb : __answer_created_cb, webrtc, NULL);
+ data = g_new0(description_created_userdata, 1);
+ data->webrtc = webrtc;
+
+ promise = gst_promise_new_with_change_func(is_offer ? __offer_created_cb : __answer_created_cb, data, NULL);
g_signal_emit_by_name(G_OBJECT(webrtc->gst.webrtcbin), is_offer ? "create-offer" : "create-answer", NULL, promise);
end_time = g_get_monotonic_time() + 30 * G_TIME_SPAN_SECOND;
return WEBRTC_ERROR_NONE;
}
+int _webrtcbin_create_session_description_async(webrtc_s *webrtc, bool is_offer, webrtc_session_description_created_cb callback, void *user_data)
+{
+ GstPromise *promise;
+ description_created_userdata *data;
+
+ RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(callback == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "callback is NULL");
+ RET_VAL_IF(webrtc->gst.webrtcbin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "webrtcbin is NULL");
+
+ g_mutex_lock(&webrtc->desc_mutex);
+
+ data = g_new0(description_created_userdata, 1);
+ data->webrtc = webrtc;
+ data->callback = callback;
+ data->user_data = user_data;
+
+ promise = gst_promise_new_with_change_func(is_offer ? __offer_created_cb : __answer_created_cb, data, NULL);
+ g_signal_emit_by_name(G_OBJECT(webrtc->gst.webrtcbin), is_offer ? "create-offer" : "create-answer", NULL, promise);
+
+ return WEBRTC_ERROR_NONE;
+}
+
/* Use g_free() to release the sdp and type parameter. */
static int __get_sdp_from_description(const char *description, gchar **sdp, gchar **type)
{