Add infrastructure for adding/removing media source 22/242622/6
authorSangchul Lee <sc11.lee@samsung.com>
Fri, 28 Aug 2020 08:52:02 +0000 (17:52 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Tue, 8 Sep 2020 05:22:45 +0000 (14:22 +0900)
g_hash_table is used to manage source elements.

[Version] 0.1.4
[Issue Type] Implementation

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

index 62c4600925a67ec574ddb7b9200a10f8fd06d030..2b5717e94314a9ec1f75a0b812b5d3e4c5c5155a 100644 (file)
@@ -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.
index 7c1a5e85116c2d18661dfed569d2858f3ce50db2..bff07c94ac953d9f44854b48b18bcc771b60e47c 100644 (file)
@@ -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
 }
index 9405a89b5032ae91b239c0b5036700233d9b1bd6..58dc368bced99349976e4b2206a339e4a6be8829 100644 (file)
@@ -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
index 700dfb8ed206ce6bfe23d156fe1607dbcd64f612..76a79032d05570c0df168b7d63534dfd28bd8da7 100644 (file)
@@ -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)
index c584bb43392b9657eee6e301ca62203710e9fdf1..8fe9bdf80a22f5be30ac2047330200f6663a20e9 100644 (file)
@@ -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;
+}
+
index 0e1d6c30a97d24676364f2ae31cfc6f1fd6159f8..847a7d9a12bf82d52ea71ac2643afbf053eca5ac 100644 (file)
@@ -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;