From: Sangchul Lee Date: Fri, 28 Aug 2020 08:52:02 +0000 (+0900) Subject: Add infrastructure for adding/removing media source X-Git-Tag: submit/tizen/20210729.023123~238 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bb0adedc624fdd9e92a657ed8d2aa8fec52e8631;p=platform%2Fcore%2Fapi%2Fwebrtc.git Add infrastructure for adding/removing media source g_hash_table is used to manage source elements. [Version] 0.1.4 [Issue Type] Implementation Change-Id: Ifcf131c61cb48ec284d36f5765afefab9def1901 Signed-off-by: Sangchul Lee --- diff --git a/include/webrtc.h b/include/webrtc.h index 62c46009..2b5717e9 100644 --- a/include/webrtc.h +++ b/include/webrtc.h @@ -172,7 +172,7 @@ int webrtc_get_state(webrtc_h webrtc, webrtc_state_e *state); * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE. * @see webrtc_remove_media_source() */ -int webrtc_add_media_source(webrtc_h webrtc, webrtc_media_source_type_e type, int *source_id); +int webrtc_add_media_source(webrtc_h webrtc, webrtc_media_source_type_e type, unsigned int *source_id); /** * @brief Removes the media source. @@ -189,7 +189,7 @@ int webrtc_add_media_source(webrtc_h webrtc, webrtc_media_source_type_e type, in * @pre Add media source to @a webrtc by calling webrtc_add_media_source(). * @see webrtc_add_media_source() */ -int webrtc_remove_media_source(webrtc_h webrtc, int source_id); +int webrtc_remove_media_source(webrtc_h webrtc, unsigned int source_id); /** * @brief Sets a STUN server URL. diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 7c1a5e85..bff07c94 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -98,25 +98,23 @@ do { \ #define SAFE_FREE(src) { if (src) { free(src); src = NULL; } } #define SAFE_STR(str) (str) ? str : "null" -#define SOURCES_MAX 8 - typedef struct _webrtc_ini_s { gboolean generate_dot; gchar **gst_args; } webrtc_ini_s; -typedef struct _webrtc_gst_src_s { - unsigned int source_id; +typedef struct _webrtc_gst_slot_s { + webrtc_media_source_type_e type; + unsigned int id; GstElement *bin; -} webrtc_gst_src_s; +} webrtc_gst_slot_s; typedef struct _webrtc_gst_s { GstElement *pipeline; GstElement *webrtcbin; GstBus *bus; guint bus_watcher; - webrtc_gst_src_s *audiosrc[SOURCES_MAX]; - webrtc_gst_src_s *videosrc[SOURCES_MAX]; + GHashTable *source_slots; } webrtc_gst_s; typedef struct _webrtc_s { @@ -135,6 +133,8 @@ int _gst_init(webrtc_s *webrtc); int _gst_build_pipeline(webrtc_s *webrtc); void _gst_destroy_pipeline(webrtc_s *webrtc); int _gst_pipeline_set_state(webrtc_s *webrtc, GstState state); +int _add_media_source(webrtc_s *webrtc, webrtc_media_source_type_e type, unsigned int *source_id); +int _remove_media_source(webrtc_s *webrtc, unsigned int source_id); #ifdef __cplusplus } diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 9405a89b..58dc368b 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.3 +Version: 0.1.4 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc.c b/src/webrtc.c index 700dfb8e..76a79032 100644 --- a/src/webrtc.c +++ b/src/webrtc.c @@ -135,8 +135,9 @@ int webrtc_get_state(webrtc_h webrtc, webrtc_state_e *state) return WEBRTC_ERROR_NONE; } -int webrtc_add_media_source(webrtc_h webrtc, webrtc_media_source_type_e type, int *source_id) +int webrtc_add_media_source(webrtc_h webrtc, webrtc_media_source_type_e type, unsigned int *source_id) { + int ret = WEBRTC_ERROR_NONE; webrtc_s *_webrtc = (webrtc_s*)webrtc; RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); @@ -146,17 +147,18 @@ int webrtc_add_media_source(webrtc_h webrtc, webrtc_media_source_type_e type, in RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be IDLE"); - /* Implementation */ + ret = _add_media_source(webrtc, type, source_id); g_mutex_unlock(&_webrtc->mutex); LOG_INFO("source_id[%d]", *source_id); - return WEBRTC_ERROR_NONE; + return ret; } -int webrtc_remove_media_source(webrtc_h webrtc, int source_id) +int webrtc_remove_media_source(webrtc_h webrtc, unsigned int source_id) { + int ret = WEBRTC_ERROR_NONE; webrtc_s *_webrtc = (webrtc_s*)webrtc; RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); @@ -165,13 +167,13 @@ int webrtc_remove_media_source(webrtc_h webrtc, int source_id) RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be IDLE"); - /* Implementation */ + ret = _remove_media_source(webrtc, source_id); g_mutex_unlock(&_webrtc->mutex); LOG_INFO("source_id[%d]", source_id); - return WEBRTC_ERROR_NONE; + return ret; } int webrtc_set_stun_server(webrtc_h webrtc, const char *stun_server) diff --git a/src/webrtc_private.c b/src/webrtc_private.c index c584bb43..8fe9bdf8 100644 --- a/src/webrtc_private.c +++ b/src/webrtc_private.c @@ -117,6 +117,20 @@ static GstElement *__element_create(const char *factory_name, const char *name) return element; } +static void __value_destroy_cb(gpointer data) +{ + webrtc_gst_slot_s *source = (webrtc_gst_slot_s *)data; + RET_IF(data == NULL, "data is NULL"); + + LOG_DEBUG("[%s, type:%u, id:%u] is removed", GST_ELEMENT_NAME(source->bin), source->type, source->id); + + /* FIXME: do unlink */ + + gst_bin_remove(GST_BIN(gst_element_get_parent(source->bin)), source->bin); + + g_free(source); +} + int _ini_load(webrtc_s *webrtc) { RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); @@ -204,6 +218,8 @@ int _gst_build_pipeline(webrtc_s *webrtc) goto error; } + webrtc->gst.source_slots = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, __value_destroy_cb); + return WEBRTC_ERROR_NONE; error: @@ -232,6 +248,10 @@ void _gst_destroy_pipeline(webrtc_s *webrtc) gst_object_unref(webrtc->gst.pipeline); webrtc->gst.pipeline = NULL; } + if (webrtc->gst.source_slots) { + g_hash_table_unref(webrtc->gst.source_slots); + webrtc->gst.source_slots = NULL; + } } int _gst_pipeline_set_state(webrtc_s *webrtc, GstState state) @@ -250,3 +270,63 @@ int _gst_pipeline_set_state(webrtc_s *webrtc, GstState state) return WEBRTC_ERROR_NONE; } +int _add_media_source(webrtc_s *webrtc, webrtc_media_source_type_e type, unsigned int *source_id) +{ + static unsigned int id = 0; + webrtc_gst_slot_s *source = NULL; + gchar *bin_name = NULL; + + RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(webrtc->gst.source_slots == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source_slots is NULL"); + RET_VAL_IF(source_id == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is NULL"); + + /* key/value will be freed by function set via g_hash_table_new_full() */ + bin_name = g_strdup_printf("media_source_%u", ++id); /* key */ + source = g_new0(webrtc_gst_slot_s, 1); /* value */ + + source->type = type; + source->id = id; + source->bin = gst_bin_new(bin_name); + + /* FIXME: add proper elements to the bin according to the type */ + + if (!gst_bin_add(GST_BIN(webrtc->gst.pipeline), source->bin)) { + LOG_ERROR("failed to gst_bin_add(), [%s] -> [%s] pipeline", GST_ELEMENT_NAME(source->bin), GST_ELEMENT_NAME(webrtc->gst.pipeline)); + g_free(bin_name); + g_free(source); + return WEBRTC_ERROR_INVALID_OPERATION; + } + + if (!g_hash_table_insert(webrtc->gst.source_slots, bin_name, (gpointer)source)) { + LOG_ERROR("should not be reached here, bin_name[%s] already exist, source id[%u] will be removed", bin_name, source->id); + g_hash_table_remove(webrtc->gst.source_slots, bin_name); + return WEBRTC_ERROR_INVALID_OPERATION; + } + + *source_id = id; + + LOG_INFO("type[%d] source_id[%u] source[%p]", type, *source_id, source); + + return WEBRTC_ERROR_NONE; +} + +int _remove_media_source(webrtc_s *webrtc, unsigned int source_id) +{ + gchar *bin_name = NULL; + + RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(webrtc->gst.source_slots == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source_slots is NULL"); + + bin_name = g_strdup_printf("media_source_%u", source_id); + + if (!g_hash_table_remove(webrtc->gst.source_slots, (gpointer)bin_name)) { + LOG_ERROR("failed to find media source by id[%u]", source_id); + g_free(bin_name); + return WEBRTC_ERROR_INVALID_PARAMETER; + } + + g_free(bin_name); + + return WEBRTC_ERROR_NONE; +} + diff --git a/test/webrtc_test.c b/test/webrtc_test.c index 0e1d6c30..847a7d9a 100644 --- a/test/webrtc_test.c +++ b/test/webrtc_test.c @@ -254,7 +254,7 @@ static void _webrtc_get_state() static void _webrtc_add_media_source(int type) { int ret = WEBRTC_ERROR_NONE; - int source_id = 0; + unsigned int source_id = 0; ret = webrtc_add_media_source(g_webrtc, (webrtc_media_source_type_e)type, &source_id); if (ret != WEBRTC_ERROR_NONE) @@ -263,7 +263,7 @@ static void _webrtc_add_media_source(int type) g_print("webrtc_add_media_source() success, source_id[%d]\n", source_id); } -static void _webrtc_remove_media_source(int source_id) +static void _webrtc_remove_media_source(unsigned int source_id) { int ret = WEBRTC_ERROR_NONE;