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>
* @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.
* @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.
#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 {
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
}
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
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");
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");
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)
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");
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:
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)
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;
+}
+
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)
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;