*/
int webrtc_get_rtp_packet_drop_probability(webrtc_h webrtc, bool sender, float *probability);
+/**
+ * @internal
+ * @brief Starts the WebRTC synchronously.
+ * @since_tizen 8.0
+ * @remarks The main difference with webrtc_start() is that this returns after changing state to #WEBRTC_STATE_NEGOTIATING.\n
+ * webrtc_state_changed_cb() will not be invoked.
+ * @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
+ * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state
+ * @retval #WEBRTC_ERROR_RESOURCE_FAILED Resource failed
+ * @pre webrtc_ice_candidate_cb() must be set by calling webrtc_set_ice_candidate_cb().
+ * @pre webrtc_media_packet_source_set_format() must be called if @a webrtc has a media packet source.
+ * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE.
+ * @post @a webrtc state is #WEBRTC_STATE_NEGOTIATING.
+ * @see webrtc_create()
+ * @see webrtc_stop()
+ */
+int webrtc_start_sync(webrtc_h webrtc);
+
/**
* @internal
* @brief Creates a signaling server for private network.
guint stats_timer_src;
GMutex mutex;
+ GMutex state_mutex;
+ GCond state_cond;
GMutex event_src_mutex;
GMutex desc_mutex;
GCond desc_cond;
webrtc_state_e state;
webrtc_state_e pend_state;
bool is_destroying;
+ bool is_start_sync;
GList *signals;
Name: capi-media-webrtc
Summary: A WebRTC library in Tizen Native API
-Version: 0.4.45
+Version: 0.4.46
Release: 0
Group: Multimedia/API
License: Apache-2.0
g_mutex_init(&_webrtc->mutex);
locker = g_mutex_locker_new(&_webrtc->mutex);
+ g_mutex_init(&_webrtc->state_mutex);
+ g_cond_init(&_webrtc->state_cond);
g_mutex_init(&_webrtc->event_src_mutex);
g_mutex_init(&_webrtc->desc_mutex);
g_cond_init(&_webrtc->desc_cond);
LOG_INFO("webrtc[%p] is destroyed", webrtc);
g_mutex_clear(&_webrtc->destroy_mutex);
+ g_cond_clear(&_webrtc->state_cond);
+ g_mutex_clear(&_webrtc->state_mutex);
g_clear_pointer(&locker, g_mutex_locker_free);
g_mutex_clear(&_webrtc->mutex);
RET_VAL_IF(!_check_if_codec_is_set_to_null_sources(_webrtc), WEBRTC_ERROR_INVALID_OPERATION, "transceiver codec is should be set");
#ifndef TIZEN_TV
- ret = _acquire_resource_if_needed(_webrtc);
- if (ret != WEBRTC_ERROR_NONE) {
- LOG_ERROR("failed to acquire resource, webrtc[%p]", _webrtc);
+ if ((ret = _acquire_resource_if_needed(_webrtc)) != WEBRTC_ERROR_NONE)
return ret;
- }
#endif
ret = _complete_sources(_webrtc);
RET_VAL_IF(ret != WEBRTC_ERROR_NONE, ret, "failed to complete sources");
LOG_INFO("webrtc[%p] is started", webrtc);
-
return WEBRTC_ERROR_NONE;
}
return _get_packet_drop_probability(webrtc, sender, probability);
}
+
+int webrtc_start_sync(webrtc_h webrtc)
+{
+ int ret = WEBRTC_ERROR_NONE;
+ g_autoptr(GMutexLocker) locker = NULL;
+ webrtc_s *_webrtc = (webrtc_s *)webrtc;
+ gint64 end_time;
+
+ RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+
+ locker = g_mutex_locker_new(&_webrtc->mutex);
+
+ RET_VAL_IF(_webrtc->ice_candidate_cb.callback == NULL, WEBRTC_ERROR_INVALID_OPERATION, "the ice candidate callback should be set");
+ RET_VAL_IF(_webrtc->state != WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_STATE, "the state should be IDLE");
+ RET_VAL_IF(_webrtc->gst.webrtcbin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "webrtcbin is NULL");
+ RET_VAL_IF(!_check_if_format_is_set_to_packet_sources(_webrtc), WEBRTC_ERROR_INVALID_OPERATION, "the media format should be set");
+ RET_VAL_IF(!_check_if_path_is_set_to_file_sources(_webrtc), WEBRTC_ERROR_INVALID_OPERATION, "the media path should be set");
+ RET_VAL_IF(!_check_if_codec_is_set_to_null_sources(_webrtc), WEBRTC_ERROR_INVALID_OPERATION, "transceiver codec is should be set");
+
+#ifndef TIZEN_TV
+ if ((ret = _acquire_resource_if_needed(_webrtc)) != WEBRTC_ERROR_NONE)
+ return ret;
+#endif
+ ret = _complete_sources(_webrtc);
+ RET_VAL_IF(ret != WEBRTC_ERROR_NONE, ret, "failed to complete sources");
+
+ g_mutex_lock(&_webrtc->state_mutex);
+
+ _webrtc->is_start_sync = true;
+ _webrtc->pend_state = WEBRTC_STATE_NEGOTIATING;
+
+ if ((ret = _gst_pipeline_set_state(_webrtc, GST_STATE_PLAYING)) != WEBRTC_ERROR_NONE) {
+ _webrtc->pend_state = WEBRTC_STATE_IDLE;
+ goto out;
+ }
+
+ end_time = g_get_monotonic_time() + 10 * G_TIME_SPAN_SECOND;
+ LOG_DEBUG("wait...");
+ if (!g_cond_wait_until(&_webrtc->state_cond, &_webrtc->state_mutex, end_time)) {
+ LOG_ERROR("timeout of g_cond_wait_until()");
+ _webrtc->pend_state = WEBRTC_STATE_IDLE;
+ ret = WEBRTC_ERROR_INVALID_OPERATION;
+ goto out;
+ }
+
+ LOG_INFO("webrtc[%p] is started", webrtc);
+
+out:
+ _webrtc->is_start_sync = false;
+ g_mutex_unlock(&_webrtc->state_mutex);
+ return ret;
+}
//LCOV_EXCL_STOP
RET_IF(webrtc == NULL, "webrtc is NULL");
- _post_state_cb_in_idle(webrtc, WEBRTC_STATE_NEGOTIATING);
+ if (webrtc->is_start_sync) {
+ webrtc->state = WEBRTC_STATE_NEGOTIATING;
+ g_mutex_lock(&webrtc->state_mutex);
+ g_cond_signal(&webrtc->state_cond);
+ g_mutex_unlock(&webrtc->state_mutex);
+ } else {
+ _post_state_cb_in_idle(webrtc, WEBRTC_STATE_NEGOTIATING);
+ }
if (webrtc->negotiation_needed_cb.callback == NULL) {
LOG_DEBUG("negotiation_needed_cb is NULL, skip it");