From: Sangchul Lee Date: Fri, 12 Aug 2022 09:02:03 +0000 (+0900) Subject: Make webrtc_foreach_stats() synchronous function X-Git-Tag: submit/tizen/20220819.010835~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=85e8134d17211d376fdd695f5190a98a1f7bd5bd;p=platform%2Fcore%2Fapi%2Fwebrtc.git Make webrtc_foreach_stats() synchronous function It ensures that webrtc_foreach_stats() returns after invoking all callbacks. It takes approximately under 30ms. [Version] 0.3.202 [Issue Type] API Change-Id: I5502ee3e948bad506279e34ba949bf99c5ed934c Signed-off-by: Sangchul Lee --- diff --git a/include/webrtc.h b/include/webrtc.h index 3cc748c4..8332409d 100644 --- a/include/webrtc.h +++ b/include/webrtc.h @@ -2783,7 +2783,7 @@ int webrtc_data_channel_unset_buffered_amount_low_cb(webrtc_data_channel_h chann */ /** - * @brief Retrieves all the statistics properties, asynchronously. + * @brief Retrieves all the statistics properties. * @since_tizen 7.0 * @remarks The registered callback will be invoked in an internal thread of the webrtc. * @param[in] webrtc WebRTC handle diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 43b0a778..9a89bd34 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -476,6 +476,8 @@ typedef struct _webrtc_s { GMutex event_src_mutex; GMutex desc_mutex; GCond desc_cond; + GMutex stats_mutex; + GCond stats_cond; webrtc_gst_s gst; unsigned int payload_types; @@ -767,7 +769,7 @@ int _data_channel_send_string(webrtc_data_channel_s *channel, const char *string int _data_channel_send_bytes(webrtc_data_channel_s *channel, const char *data, unsigned int size); /* stats */ -void _webrtcbin_get_stats(webrtc_s *webrtc, int type_mask, void *callback, void *user_data); +void _webrtcbin_foreach_stats(webrtc_s *webrtc, int type_mask, void *callback, void *user_data); void _set_stats_timer(webrtc_s *webrtc); void _unset_stats_timer(webrtc_s *webrtc); void _init_stats_all_fields_list(void); diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 758ca9cd..cf76a566 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.3.201 +Version: 0.3.202 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc.c b/src/webrtc.c index 061cabf2..c92e2e3c 100644 --- a/src/webrtc.c +++ b/src/webrtc.c @@ -95,6 +95,8 @@ int webrtc_create(webrtc_h *webrtc) g_mutex_init(&_webrtc->event_src_mutex); g_mutex_init(&_webrtc->desc_mutex); g_cond_init(&_webrtc->desc_cond); + g_mutex_init(&_webrtc->stats_mutex); + g_cond_init(&_webrtc->stats_cond); _load_ini(_webrtc); if (_is_resource_required(&_webrtc->ini)) { @@ -159,6 +161,8 @@ int webrtc_destroy(webrtc_h webrtc) _gst_destroy_pipeline(_webrtc); _unload_ini(_webrtc); + g_cond_clear(&_webrtc->stats_cond); + g_mutex_clear(&_webrtc->stats_mutex); g_cond_clear(&_webrtc->desc_cond); g_mutex_clear(&_webrtc->desc_mutex); g_mutex_clear(&_webrtc->event_src_mutex); @@ -2014,7 +2018,7 @@ int webrtc_foreach_stats(webrtc_h webrtc, int type_mask, webrtc_stats_cb callbac RET_VAL_IF(_webrtc->state != WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, "the state should be PLAYING"); - _webrtcbin_get_stats(_webrtc, type_mask, callback, user_data); + _webrtcbin_foreach_stats(_webrtc, type_mask, callback, user_data); LOG_INFO("webrtc[%p] type_mask[0x%x] callback[%p] user_data[%p]", webrtc, type_mask, callback, user_data); diff --git a/src/webrtc_stats.c b/src/webrtc_stats.c index ef50d7b4..d8009100 100644 --- a/src/webrtc_stats.c +++ b/src/webrtc_stats.c @@ -18,6 +18,7 @@ #include "webrtc_private.h" //LCOV_EXCL_START +#define FOREACH_STATS_TIMEOUT_SEC 1 #define WEBRTC_STATS_TYPE_GST_ALL 0xFFFF /* All statistics types of webrtcbin for debugging */ #define WEBRTC_STATS_PROP_NOT_EXPORTED 0x0 /* Statistics property that should not be exported */ @@ -316,10 +317,12 @@ static gboolean __invoke_stats_cb(int type, const gchar *field_name, webrtc_stat return TRUE; } + LOG_DEBUG(">>> type[0x%04x], callback[%p], user_data[%p]", type, stats_cb->callback, stats_cb->user_data); if (!((webrtc_stats_cb)stats_cb->callback)(type, &prop_info, stats_cb->user_data)) { LOG_DEBUG("stats foreach callback[%p] returns false, stop it", stats_cb->callback); return FALSE; } + LOG_DEBUG("<<< end of the callback"); return TRUE; } @@ -717,6 +720,7 @@ static gboolean __webrtcbin_stats_cb(GQuark field_id, const GValue *value, gpoin static void __webrtcbin_get_stats_cb(GstPromise *promise, gpointer user_data) { const GstStructure *stats; + promise_userdata_s *data = (promise_userdata_s *)user_data; RET_IF(gst_promise_wait(promise) != GST_PROMISE_RESULT_REPLIED, "failed to gst_promise_wait()"); RET_IF(user_data == NULL, "user_data is NULL"); @@ -725,16 +729,23 @@ static void __webrtcbin_get_stats_cb(GstPromise *promise, gpointer user_data) RET_IF(stats == NULL, "failed to gst_promise_get_reply()"); gst_structure_foreach(stats, __webrtcbin_stats_cb, user_data); + + g_mutex_lock(&data->webrtc->stats_mutex); + g_cond_signal(&data->webrtc->stats_cond); + g_mutex_unlock(&data->webrtc->stats_mutex); } -void _webrtcbin_get_stats(webrtc_s *webrtc, int type_mask, void *callback, void *user_data) +void _webrtcbin_foreach_stats(webrtc_s *webrtc, int type_mask, void *callback, void *user_data) { GstPromise *promise; promise_userdata_s *userdata; + gint64 end_time = g_get_monotonic_time() + FOREACH_STATS_TIMEOUT_SEC * G_TIME_SPAN_SECOND; RET_IF(webrtc == NULL, "webrtc is NULL"); RET_IF(webrtc->gst.webrtcbin == NULL, "webrtcbin is NULL"); + g_mutex_lock(&webrtc->stats_mutex); + userdata = g_new0(promise_userdata_s, 1); userdata->webrtc = webrtc; userdata->type_mask = type_mask; @@ -749,6 +760,10 @@ void _webrtcbin_get_stats(webrtc_s *webrtc, int type_mask, void *callback, void LOG_DEBUG("emitting 'get-stats' on %p", webrtc->gst.webrtcbin); gst_promise_unref(promise); + + if (!g_cond_wait_until(&webrtc->stats_cond, &webrtc->stats_mutex, end_time)) + LOG_ERROR("failed to get stats within %d sec. of timeout", FOREACH_STATS_TIMEOUT_SEC); + g_mutex_unlock(&webrtc->stats_mutex); } static gboolean __get_stats_periodically(gpointer user_data) @@ -756,7 +771,7 @@ static gboolean __get_stats_periodically(gpointer user_data) webrtc_s *webrtc = (webrtc_s *)user_data; if (webrtc->state == WEBRTC_STATE_PLAYING) - _webrtcbin_get_stats(webrtc, WEBRTC_STATS_TYPE_GST_ALL, NULL, NULL); + _webrtcbin_foreach_stats(webrtc, WEBRTC_STATS_TYPE_GST_ALL, NULL, NULL); return G_SOURCE_CONTINUE; }