From c6b0aa5d70e50b2889e18182c8e0e6e1f6d031ef Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Wed, 10 Jun 2020 10:47:20 +0900 Subject: [PATCH] Add new parameter to set/get STUN server URL for WebRTC node MEDIA_STREAMER_PARAM_WEBRTC_STUN_SERVER is added. The default value is "stun://stun.l.google.com:19302" [Version] 0.1.57 [Issue Type] New feature Change-Id: I12365080f76f19dc4175c8616a998fb8fe5d3624 Signed-off-by: Sangchul Lee --- include/media_streamer.h | 8 ++++++ include/media_streamer_gst_webrtc.h | 6 ++-- include/media_streamer_util.h | 1 + packaging/capi-media-streamer.spec | 2 +- src/media_streamer_gst_webrtc.c | 55 +++++++++++++++++++++++++++++++------ src/media_streamer_node.c | 18 ++++++++++-- 6 files changed, 76 insertions(+), 14 deletions(-) diff --git a/include/media_streamer.h b/include/media_streamer.h index 4385790..93022fe 100644 --- a/include/media_streamer.h +++ b/include/media_streamer.h @@ -303,6 +303,14 @@ typedef enum { #define MEDIA_STREAMER_PARAM_WEBRTC_PEER_TYPE "webrtc-peer-type" /** + * @brief Definition for the STUN server URL for WebRTC node. + * @details Data type is string and default value is "stun://stun.l.google.com:19302". + * @since_tizen 6.0 + * @see media_streamer_node_get_params() + */ +#define MEDIA_STREAMER_PARAM_WEBRTC_STUN_SERVER "webrtc-stun-server" + +/** * @brief Definition for remote session description. * @details Value of the session description of the remote peer over its signaling channel * Data type is string. diff --git a/include/media_streamer_gst_webrtc.h b/include/media_streamer_gst_webrtc.h index 6f1fe74..4409d53 100644 --- a/include/media_streamer_gst_webrtc.h +++ b/include/media_streamer_gst_webrtc.h @@ -40,9 +40,11 @@ void ms_webrtcbin_on_negotiation_needed_cb(GstElement *webrtcbin, gpointer user_ void ms_webrtcbin_on_negotiation_process_answer(GstElement *webrtcbin, media_streamer_node_s *webrtc_node); -int ms_webrtcbin_set_remote_session_description(media_streamer_node_s *node, const char *sdp_msg); +int ms_webrtcbin_set_remote_session_description(media_streamer_node_s *webrtc_node, const char *sdp_msg); -int ms_webrtcbin_add_ice_candidate(media_streamer_node_s *node, const char *ice_msg); +int ms_webrtcbin_add_ice_candidate(media_streamer_node_s *webrtc_node, const char *ice_msg); + +int ms_webrtcbin_set_stun_server(media_streamer_node_s *webrtc_node, const char *stun_server_url); #ifdef __cplusplus diff --git a/include/media_streamer_util.h b/include/media_streamer_util.h index bbfe35d..08c2a01 100644 --- a/include/media_streamer_util.h +++ b/include/media_streamer_util.h @@ -196,6 +196,7 @@ typedef struct _media_streamer_wl_info_s { #define WEBRTC_PEER_ANSWER "answer" #define WEBRTC_PEER_OFFER "offer" #define DEFAULT_WEBRTC_PEER WEBRTC_PEER_ANSWER +#define DEFAULT_WEBRTC_STUN_SERVER "stun://stun.l.google.com:19302" #define MEDIA_STREAMER_DEFAULT_CAMERA_FORMAT "video/x-raw,format=I420,width=352,height=288" #define MEDIA_STREAMER_DEFAULT_AUDIO_RAW_FORMAT "audio/x-raw,channels=1,rate=8000,format=S16LE" diff --git a/packaging/capi-media-streamer.spec b/packaging/capi-media-streamer.spec index 8cac7e6..76ffd39 100644 --- a/packaging/capi-media-streamer.spec +++ b/packaging/capi-media-streamer.spec @@ -1,6 +1,6 @@ Name: capi-media-streamer Summary: A Media Streamer API -Version: 0.1.56 +Version: 0.1.57 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_streamer_gst_webrtc.c b/src/media_streamer_gst_webrtc.c index 353f629..25df152 100644 --- a/src/media_streamer_gst_webrtc.c +++ b/src/media_streamer_gst_webrtc.c @@ -188,7 +188,7 @@ static void __on_answer_created_cb(GstPromise * promise, gpointer user_data) ms_debug_fleave(); } -int ms_webrtcbin_set_remote_session_description(media_streamer_node_s *node, const char *sdp_msg) +int ms_webrtcbin_set_remote_session_description(media_streamer_node_s *webrtc_node, const char *sdp_msg) { GstSDPMessage *gst_sdp; gchar *sdp; @@ -198,14 +198,14 @@ int ms_webrtcbin_set_remote_session_description(media_streamer_node_s *node, con GstElement *webrtcbin; int ret = MEDIA_STREAMER_ERROR_NONE; - ms_retvm_if(node == NULL || node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: empty webrtcbin"); + ms_retvm_if(webrtc_node == NULL || webrtc_node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: empty webrtcbin"); ms_retvm_if(sdp_msg == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "sdp_msg is NULL"); ms_debug_fenter(); node_klass_type = ms_node_get_klass_by_its_type(MEDIA_STREAMER_NODE_TYPE_WEBRTC); - if (!(webrtcbin = ms_find_element_in_bin_by_type(node->gst_element, node_klass_type))) { + if (!(webrtcbin = ms_find_element_in_bin_by_type(webrtc_node->gst_element, node_klass_type))) { ms_error("Could not find webrtcbin by type[%s, %s]", node_klass_type->klass_name, node_klass_type->default_name); return MEDIA_STREAMER_ERROR_INVALID_OPERATION; } @@ -239,7 +239,7 @@ int ms_webrtcbin_set_remote_session_description(media_streamer_node_s *node, con __ms_webrtcbin_set_session_description(webrtcbin, offer, TRUE); gst_webrtc_session_description_free(offer); - ms_webrtcbin_on_negotiation_process_answer(webrtcbin, node); + ms_webrtcbin_on_negotiation_process_answer(webrtcbin, webrtc_node); } else { ms_error("type is %s, it is not a answer or offer", type); } @@ -253,7 +253,7 @@ end: return ret; } -int ms_webrtcbin_add_ice_candidate(media_streamer_node_s *node, const char *ice_msg) +int ms_webrtcbin_add_ice_candidate(media_streamer_node_s *webrtc_node, const char *ice_msg) { gchar *candidate; gint sdpmlineindex; @@ -261,13 +261,13 @@ int ms_webrtcbin_add_ice_candidate(media_streamer_node_s *node, const char *ice_ GstElement *webrtcbin; int ret; - ms_retvm_if(node == NULL || node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: empty webrtcbin"); + ms_retvm_if(webrtc_node == NULL || webrtc_node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Error: empty webrtcbin"); ms_retvm_if(ice_msg == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ice_msg is NULL"); ms_debug_fenter(); node_klass_type = ms_node_get_klass_by_its_type(MEDIA_STREAMER_NODE_TYPE_WEBRTC); - if (!(webrtcbin = ms_find_element_in_bin_by_type(node->gst_element, node_klass_type))) { + if (!(webrtcbin = ms_find_element_in_bin_by_type(webrtc_node->gst_element, node_klass_type))) { ms_error("Could not find webrtcbin by type[%s, %s]", node_klass_type->klass_name, node_klass_type->default_name); return MEDIA_STREAMER_ERROR_INVALID_OPERATION; } @@ -284,6 +284,41 @@ int ms_webrtcbin_add_ice_candidate(media_streamer_node_s *node, const char *ice_ return MEDIA_STREAMER_ERROR_NONE; } +int ms_webrtcbin_set_stun_server(media_streamer_node_s *webrtc_node, const char *stun_server_url) +{ + node_info_s *node_klass_type; + GstElement *webrtcbin; + GValue *val; + const gchar *stun_server = NULL; + + ms_retvm_if(webrtc_node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL"); + ms_retvm_if(webrtc_node->gst_element == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "webrtc_container is NULL"); + ms_retvm_if(stun_server_url == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "stun_server_url is NULL"); + + node_klass_type = ms_node_get_klass_by_its_type(MEDIA_STREAMER_NODE_TYPE_WEBRTC); + if (!(webrtcbin = ms_find_element_in_bin_by_type(webrtc_node->gst_element, node_klass_type))) { + ms_error("Could not find webrtcbin by type[%s, %s]", node_klass_type->klass_name, node_klass_type->default_name); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + val = (GValue *)g_object_get_data(G_OBJECT(webrtc_node->gst_element), MEDIA_STREAMER_PARAM_WEBRTC_STUN_SERVER); + if (!val) { + ms_error("Failed to get [%s] val from [%s]", MEDIA_STREAMER_PARAM_WEBRTC_STUN_SERVER, GST_ELEMENT_NAME(webrtc_node->gst_element)); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + if (!(stun_server = g_value_get_string(val))) { + ms_error("Failed to g_value_get_string()"); + return MEDIA_STREAMER_ERROR_INVALID_OPERATION; + } + + g_object_set(G_OBJECT(webrtcbin), "stun-server", stun_server, NULL); + + ms_info("STUN server: %s", stun_server); + + return MEDIA_STREAMER_ERROR_NONE; +} + void ms_webrtcbin_on_negotiation_process_answer(GstElement *webrtcbin, media_streamer_node_s *webrtc_node) { GstPromise *promise; @@ -521,6 +556,7 @@ GstElement *ms_webrtc_element_create(void) ms_add_no_target_ghostpad(webrtc_container, MS_RTP_PAD_VIDEO_IN, GST_PAD_SINK); MS_SET_INT_STATIC_STRING_PARAM(webrtc_container, MEDIA_STREAMER_PARAM_WEBRTC_PEER_TYPE, DEFAULT_WEBRTC_PEER); + MS_SET_INT_STATIC_STRING_PARAM(webrtc_container, MEDIA_STREAMER_PARAM_WEBRTC_STUN_SERVER, DEFAULT_WEBRTC_STUN_SERVER); MS_SET_INT_STATIC_STRING_PARAM(webrtc_container, MEDIA_STREAMER_PARAM_WEBRTC_REMOTE_SESSION_DESCRIPTION, NULL); MS_SET_INT_STATIC_STRING_PARAM(webrtc_container, MEDIA_STREAMER_PARAM_WEBRTC_ADD_ICE_CANDIDATE, NULL); @@ -529,9 +565,10 @@ GstElement *ms_webrtc_element_create(void) return NULL; } - /* FIXME: these should be set from user */ + g_object_set(G_OBJECT(webrtcbin), "stun-server", DEFAULT_WEBRTC_STUN_SERVER, NULL); + + /* FIXME: should it be set by user? */ g_object_set(G_OBJECT(webrtcbin), "bundle-policy", 3, NULL); // 3:max-bundle - g_object_set(G_OBJECT(webrtcbin), "stun-server", "stun://stun.l.google.com:19302", NULL); ms_bin_add_element(webrtc_container, webrtcbin, FALSE); diff --git a/src/media_streamer_node.c b/src/media_streamer_node.c index b82ab05..f0706f2 100644 --- a/src/media_streamer_node.c +++ b/src/media_streamer_node.c @@ -51,6 +51,7 @@ static param_s param_table[] = { {MEDIA_STREAMER_PARAM_AUDIO_OUT_PORT, "audio_out_port"}, {MEDIA_STREAMER_PARAM_IP_ADDRESS, "address"}, {MEDIA_STREAMER_PARAM_WEBRTC_PEER_TYPE, "webrtc-peer-type"}, + {MEDIA_STREAMER_PARAM_WEBRTC_STUN_SERVER, "webrtc-stun-server"}, {MEDIA_STREAMER_PARAM_WEBRTC_REMOTE_SESSION_DESCRIPTION, "webrtc-remote-session-description"}, {MEDIA_STREAMER_PARAM_WEBRTC_ADD_ICE_CANDIDATE, "webrtc-add-ice-candidate"}, {MEDIA_STREAMER_PARAM_AUDIO_DEVICE, "audio_device"}, @@ -247,21 +248,34 @@ static int __ms_webrtc_node_set_property(media_streamer_node_s *node, param_s *p g_value_unset(val); g_value_init(val, G_TYPE_STRING); g_value_set_string(val, param_value); + + } else if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_WEBRTC_STUN_SERVER)) { + ret = ms_webrtcbin_set_stun_server(node, param_value); + if (ret != MEDIA_STREAMER_ERROR_NONE) { + ms_error("failed to set STUN server: %s", param_value); + return ret; + } + g_value_unset(val); + g_value_init(val, G_TYPE_STRING); + g_value_set_string(val, param_value); + } else if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_WEBRTC_REMOTE_SESSION_DESCRIPTION)) { ret = ms_webrtcbin_set_remote_session_description(node, param_value); if (ret != MEDIA_STREAMER_ERROR_NONE) { - ms_error("failed to set remote session description\n%s", param_value); + ms_error("failed to set remote session description:\n%s", param_value); return ret; } g_value_unset(val); g_value_init(val, G_TYPE_STRING); g_value_set_string(val, param_value); + } else if (!strcmp(param->param_name, MEDIA_STREAMER_PARAM_WEBRTC_ADD_ICE_CANDIDATE)) { ret = ms_webrtcbin_add_ice_candidate(node, param_value); if (ret != MEDIA_STREAMER_ERROR_NONE) { - ms_error("failed to add ICE candidate\n%s", param_value); + ms_error("failed to add ICE candidate: %s", param_value); return ret; } + } else { ms_error("failed to set property, undefined param name[%s]", param->param_name); return MEDIA_STREAMER_ERROR_INVALID_PARAMETER; -- 2.7.4