From: Sangchul Lee Date: Thu, 28 Oct 2021 06:06:45 +0000 (+0900) Subject: webrtc_ini: Add new item to enable network simulator X-Git-Tag: submit/tizen/20211109.062149~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F59%2F265759%2F7;p=platform%2Fcore%2Fapi%2Fwebrtc.git webrtc_ini: Add new item to enable network simulator The network simulator element will be imported when the item is set to 'yes' in the ini file. This element is added right after payload of a source bin. Dropping packets can be simulated by calling new internal API coming up next patch. Missing g_value_unset() is added. [Version] 0.3.1 [Issue Type] New feature Change-Id: Ia9231c68c19f6bec6bafb404b4d269c5ae3ab5d8 Signed-off-by: Sangchul Lee --- diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 37da9ce4..6d816374 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -288,6 +288,7 @@ typedef struct _ini_item_general_s { int stats_log_period; bool verbose_log; bool nice_verbose; + bool network_simulator; gchar **gst_args; gchar **gst_excluded_elements; const char *stun_server; diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 1ba56a99..70c71685 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.2.147 +Version: 0.3.1 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc_ini.c b/src/webrtc_ini.c index efc778f1..3045eee0 100644 --- a/src/webrtc_ini.c +++ b/src/webrtc_ini.c @@ -25,6 +25,7 @@ bool g_verbose = false; #define DEFAULT_STATS_LOG_PERIOD 0 /* sec */ #define DEFAULT_VERBOSE_LOG false #define DEFAULT_NICE_VERBOSE false +#define DEFAULT_NETWORK_SIMULATOR false #define DEFAULT_JITTERBUFFER_LATENCY 200 /* ms */ /* categories */ @@ -49,6 +50,7 @@ bool g_verbose = false; #define INI_ITEM_STATS_LOG_PERIOD "stats log period" #define INI_ITEM_VERBOSE_LOG "verbose log" #define INI_ITEM_NICE_VERBOSE "nice verbose" +#define INI_ITEM_NETWORK_SIMULATOR "network simulator" #define INI_ITEM_GST_ARGS "gstreamer arguments" #define INI_ITEM_GST_EXCLUDED_ELEMENTS "gstreamer excluded elements" #define INI_ITEM_STUN_SERVER "stun server" @@ -215,6 +217,7 @@ static void __dump_ini(webrtc_ini_s *ini) __dump_item(INI_ITEM_STATS_LOG_PERIOD, INI_ITEM_TYPE_INT, &ini->general.stats_log_period); __dump_item(INI_ITEM_VERBOSE_LOG, INI_ITEM_TYPE_BOOL, &ini->general.verbose_log); __dump_item(INI_ITEM_NICE_VERBOSE, INI_ITEM_TYPE_BOOL, &ini->general.nice_verbose); + __dump_item(INI_ITEM_NETWORK_SIMULATOR, INI_ITEM_TYPE_BOOL, &ini->general.network_simulator); __dump_item(INI_ITEM_GST_ARGS, INI_ITEM_TYPE_STRINGS, ini->general.gst_args); __dump_item(INI_ITEM_GST_EXCLUDED_ELEMENTS, INI_ITEM_TYPE_STRINGS, ini->general.gst_excluded_elements); __dump_item(INI_ITEM_STUN_SERVER, INI_ITEM_TYPE_STRING, (void *)ini->general.stun_server); @@ -450,6 +453,7 @@ int _load_ini(webrtc_s *webrtc) ini->general.nice_verbose = __ini_get_boolean(ini->dict, INI_CATEGORY_GENERAL, INI_ITEM_NICE_VERBOSE, DEFAULT_NICE_VERBOSE); if (ini->general.nice_verbose) g_setenv("NICE_DEBUG", "nice-verbose", TRUE); + ini->general.network_simulator = __ini_get_boolean(ini->dict, INI_CATEGORY_GENERAL, INI_ITEM_NETWORK_SIMULATOR, DEFAULT_NETWORK_SIMULATOR); __ini_read_list(ini->dict, INI_CATEGORY_GENERAL, INI_ITEM_GST_ARGS, &ini->general.gst_args); __ini_read_list(ini->dict, INI_CATEGORY_GENERAL, INI_ITEM_GST_EXCLUDED_ELEMENTS, &ini->general.gst_excluded_elements); ini->general.stun_server = __ini_get_string(ini->dict, INI_CATEGORY_GENERAL, INI_ITEM_STUN_SERVER, NULL); diff --git a/src/webrtc_source.c b/src/webrtc_source.c index 63f6312d..32f4acfd 100644 --- a/src/webrtc_source.c +++ b/src/webrtc_source.c @@ -28,39 +28,41 @@ #define GST_KLASS_NAME_CONVERTER_AUDIO "Filter/Converter/Audio" #define GST_KLASS_NAME_CONVERTER_VIDEO "Filter/Converter/Video" -#define DEFAULT_ELEMENT_CAMERASRC "v4l2src" -#define DEFAULT_ELEMENT_AUDIOSRC "pulsesrc" -#define DEFAULT_ELEMENT_VIDEOTESTSRC "videotestsrc" -#define DEFAULT_ELEMENT_AUDIOTESTSRC "audiotestsrc" -#define DEFAULT_ELEMENT_APPSRC "appsrc" -#define DEFAULT_ELEMENT_SCREENSRC "waylandsrc" -#define DEFAULT_ELEMENT_QUEUE "queue" -#define DEFAULT_ELEMENT_VOLUME "volume" -#define DEFAULT_ELEMENT_INPUT_SELECTOR "input-selector" -#define DEFAULT_ELEMENT_VIDEOCROP "videocrop" -#define DEFAULT_ELEMENT_FILESRC "filesrc" - - -#define ELEMENT_NAME_FIRST_CAPSFILTER "firstCapsfilter" -#define ELEMENT_NAME_RTP_CAPSFILTER "rtpCapsfilter" -#define ELEMENT_NAME_VIDEO_SRC "videoSrc" -#define ELEMENT_NAME_VIDEO_SWITCH "videoSwitch" -#define ELEMENT_NAME_VIDEO_MUTE_SRC "videoMuteSrc" -#define ELEMENT_NAME_VOLUME "volume" -#define ELEMENT_NAME_MIC_SRC "micSrc" -#define DEFAULT_NAME_FILE_SRC "fileSrc" -#define DEFAULT_NAME_AUDIO_QUEUE "audioQueue" -#define DEFAULT_NAME_VIDEO_QUEUE "videoQueue" -#define DEFAULT_NAME_AUDIO_CAPSFILTER "audioCapsfilter" -#define DEFAULT_NAME_VIDEO_CAPSFILTER "videoCapsfilter" -#define DEFAULT_NAME_AUDIO_PAYLOAD "audioPayload" -#define DEFAULT_NAME_VIDEO_PAYLOAD "videoPayload" -#define DEFAULT_NAME_VIDEOCROP "videoCrop" -#define DEFAULT_NAME_SCREENSRC "waylandSrc" -#define DEFAULT_NAME_AUDIO_FAKESINK "audioFakeSink" -#define DEFAULT_NAME_VIDEO_FAKESINK "videoFakeSink" -#define DEFAULT_NAME_AUDIO_APPSRC "audioAppsrc" -#define DEFAULT_NAME_VIDEO_APPSRC "videoAppsrc" +#define DEFAULT_ELEMENT_CAMERASRC "v4l2src" +#define DEFAULT_ELEMENT_AUDIOSRC "pulsesrc" +#define DEFAULT_ELEMENT_VIDEOTESTSRC "videotestsrc" +#define DEFAULT_ELEMENT_AUDIOTESTSRC "audiotestsrc" +#define DEFAULT_ELEMENT_APPSRC "appsrc" +#define DEFAULT_ELEMENT_SCREENSRC "waylandsrc" +#define DEFAULT_ELEMENT_QUEUE "queue" +#define DEFAULT_ELEMENT_VOLUME "volume" +#define DEFAULT_ELEMENT_INPUT_SELECTOR "input-selector" +#define DEFAULT_ELEMENT_VIDEOCROP "videocrop" +#define DEFAULT_ELEMENT_FILESRC "filesrc" +#define DEFAULT_ELEMENT_NETWORK_SIMULATOR "netsim" + +#define ELEMENT_NAME_FIRST_CAPSFILTER "firstCapsfilter" +#define ELEMENT_NAME_RTP_CAPSFILTER "rtpCapsfilter" +#define ELEMENT_NAME_VIDEO_SRC "videoSrc" +#define ELEMENT_NAME_VIDEO_SWITCH "videoSwitch" +#define ELEMENT_NAME_VIDEO_MUTE_SRC "videoMuteSrc" +#define ELEMENT_NAME_VOLUME "volume" +#define ELEMENT_NAME_MIC_SRC "micSrc" +#define DEFAULT_NAME_FILE_SRC "fileSrc" +#define DEFAULT_NAME_AUDIO_QUEUE "audioQueue" +#define DEFAULT_NAME_VIDEO_QUEUE "videoQueue" +#define DEFAULT_NAME_AUDIO_CAPSFILTER "audioCapsfilter" +#define DEFAULT_NAME_VIDEO_CAPSFILTER "videoCapsfilter" +#define DEFAULT_NAME_AUDIO_PAYLOAD "audioPayload" +#define DEFAULT_NAME_VIDEO_PAYLOAD "videoPayload" +#define DEFAULT_NAME_VIDEOCROP "videoCrop" +#define DEFAULT_NAME_SCREENSRC "waylandSrc" +#define DEFAULT_NAME_AUDIO_FAKESINK "audioFakeSink" +#define DEFAULT_NAME_VIDEO_FAKESINK "videoFakeSink" +#define DEFAULT_NAME_AUDIO_APPSRC "audioAppsrc" +#define DEFAULT_NAME_VIDEO_APPSRC "videoAppsrc" +#define DEFAULT_NAME_AUDIO_NETWORK_SIMULATOR "audioNetSim" +#define DEFAULT_NAME_VIDEO_NETWORK_SIMULATOR "videoNetSim" #define APPEND_ELEMENT(x_list, x_element) \ do { \ @@ -109,6 +111,7 @@ typedef struct { const char *payload_name; const char *capsfilter_name; const char *fakesink_name; + const char *network_simulator_name; } av_mapping_table_s; static av_mapping_table_s _av_tbl[AV_IDX_MAX] = { @@ -118,6 +121,7 @@ static av_mapping_table_s _av_tbl[AV_IDX_MAX] = { DEFAULT_NAME_AUDIO_PAYLOAD, DEFAULT_NAME_AUDIO_CAPSFILTER, DEFAULT_NAME_AUDIO_FAKESINK, + DEFAULT_NAME_AUDIO_NETWORK_SIMULATOR }, { DEFAULT_NAME_VIDEO_APPSRC, @@ -125,6 +129,7 @@ static av_mapping_table_s _av_tbl[AV_IDX_MAX] = { DEFAULT_NAME_VIDEO_PAYLOAD, DEFAULT_NAME_VIDEO_CAPSFILTER, DEFAULT_NAME_VIDEO_FAKESINK, + DEFAULT_NAME_VIDEO_NETWORK_SIMULATOR } }; @@ -850,7 +855,6 @@ static void __remove_probe_from_pad_for_render(webrtc_gst_slot_s *source, unsign static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool need_capsfilter, GList **element_list, bool is_audio) { - GstElement *capsfilter = NULL; GstElement *encoder = NULL; GstElement *payloader; GstElement *queue; @@ -873,7 +877,8 @@ static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source idx = GET_AV_IDX(is_audio); if (need_capsfilter) { - if (!(capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_FIRST_CAPSFILTER))) + GstElement *capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_FIRST_CAPSFILTER); + if (!capsfilter) return WEBRTC_ERROR_INVALID_OPERATION; APPEND_ELEMENT(*element_list, capsfilter); @@ -942,6 +947,13 @@ skip_encoder: goto error; APPEND_ELEMENT(*element_list, payloader); + if (webrtc->ini.general.network_simulator) { + GstElement *netsim = _create_element(DEFAULT_ELEMENT_NETWORK_SIMULATOR, NULL); + if (!netsim) + goto error; + APPEND_ELEMENT(*element_list, netsim); + } + if (!(queue = _create_element(DEFAULT_ELEMENT_QUEUE, NULL))) goto error; APPEND_ELEMENT(*element_list, queue); @@ -992,29 +1004,29 @@ static int __create_rest_of_elements_for_encoded_format(webrtc_s *webrtc, webrtc __make_encoded_caps_from_media_format(source, &media_type), NULL, payloader); - if (payloader == NULL) { - g_free(media_type); - return WEBRTC_ERROR_INVALID_OPERATION; - } + if (!payloader) + goto error; APPEND_ELEMENT(*element_list, payloader); - if (!(queue = _create_element(DEFAULT_ELEMENT_QUEUE, NULL))) { - g_free(media_type); - return WEBRTC_ERROR_INVALID_OPERATION; + if (webrtc->ini.general.network_simulator) { + GstElement *netsim = _create_element(DEFAULT_ELEMENT_NETWORK_SIMULATOR, NULL); + if (!netsim) + goto error; + APPEND_ELEMENT(*element_list, netsim); } + + if (!(queue = _create_element(DEFAULT_ELEMENT_QUEUE, NULL))) + goto error; APPEND_ELEMENT(*element_list, queue); - if (!(capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_RTP_CAPSFILTER))) { - g_free(media_type); - return WEBRTC_ERROR_INVALID_OPERATION; - } + if (!(capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_RTP_CAPSFILTER))) + goto error; APPEND_ELEMENT(*element_list, capsfilter); payload_id = __get_available_payload_id(webrtc); - if (payload_id == 0) { - g_free(media_type); - return WEBRTC_ERROR_INVALID_OPERATION; - } + if (payload_id == 0) + goto error; + source->av[GET_AV_IDX_BY_TYPE(source->media_types)].payload_id = payload_id; if ((sink_caps = __make_rtp_caps(media_type, payload_id))) { @@ -1023,8 +1035,11 @@ static int __create_rest_of_elements_for_encoded_format(webrtc_s *webrtc, webrtc } g_free(media_type); - return WEBRTC_ERROR_NONE; + +error: + g_free(media_type); + return WEBRTC_ERROR_INVALID_OPERATION; } //LCOV_EXCL_STOP @@ -1263,13 +1278,14 @@ static GstElement *__find_element_in_bin(GstBin *bin, const gchar *name) if (g_strrstr(GST_ELEMENT_NAME(element), name)) { LOG_DEBUG("found element by name [%s]", GST_ELEMENT_NAME(element)); + g_value_unset(&value); gst_iterator_free(bin_iterator); return element; } g_value_reset(&value); } - + g_value_unset(&value); gst_iterator_free(bin_iterator); return NULL; @@ -1762,14 +1778,17 @@ exit: static void __remove_rest_of_elements_for_filesrc_pipeline(webrtc_gst_slot_s *source, bool is_audio) { - GstBin *bin = NULL; - GstElement *queue = NULL; - GstElement *payload = NULL; - GstElement *capsfilter = NULL; - GstElement *fakesink = NULL; + GstBin *bin; + GstElement *queue; + GstElement *payload; + GstElement *capsfilter; + GstElement *fakesink; + GstElement *netsim; int av_idx = GET_AV_IDX(is_audio); RET_IF(source == NULL, "pad is NULL"); + RET_IF(source->webrtc == NULL, "webrtc is NULL"); + RET_IF(source->filesrc_pipeline == NULL, "filesrc_pipeline is NULL"); bin = GST_BIN(source->filesrc_pipeline); @@ -1786,6 +1805,12 @@ static void __remove_rest_of_elements_for_filesrc_pipeline(webrtc_gst_slot_s *so RET_IF(fakesink == NULL, "fakesink is NULL"); gst_bin_remove_many(bin, queue, payload, capsfilter, fakesink, NULL); + + if (source->webrtc->ini.general.network_simulator) { + netsim = gst_bin_get_by_name(bin, _av_tbl[av_idx].network_simulator_name); + RET_IF(netsim == NULL, "netsim is NULL"); + gst_bin_remove(bin, netsim); + } } static void __filesrc_pipeline_audio_stream_handoff_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data) @@ -1908,14 +1933,16 @@ static GstElement * __prepare_fakesink_for_filesrc_pipeline(webrtc_gst_slot_s *s static int __create_rest_of_elements_for_filesrc_pipeline(webrtc_gst_slot_s *source, GstPad *pad, bool is_audio) { - GstBin *bin = NULL; - GstElement *queue = NULL; - GstElement *payload = NULL; - GstElement *capsfilter = NULL; - GstElement *fakesink = NULL; + GstBin *bin; + GstElement *queue; + GstElement *payload; + GstElement *netsim; + GstElement *capsfilter; + GstElement *fakesink; GList *element_list = NULL; RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL"); + RET_VAL_IF(source->webrtc == NULL, WEBRTC_ERROR_INVALID_OPERATION, "webrtc is NULL"); RET_VAL_IF(source->filesrc_pipeline == NULL, WEBRTC_ERROR_INVALID_OPERATION, "filesrc_pipeline is NULL"); bin = GST_BIN(source->filesrc_pipeline); @@ -1928,6 +1955,12 @@ static int __create_rest_of_elements_for_filesrc_pipeline(webrtc_gst_slot_s *sou goto exit; APPEND_ELEMENT(element_list, payload); + if (source->webrtc->ini.general.network_simulator) { + if (!(netsim = _create_element(DEFAULT_ELEMENT_NETWORK_SIMULATOR, _av_tbl[GET_AV_IDX(is_audio)].network_simulator_name))) + goto exit; + APPEND_ELEMENT(element_list, netsim); + } + if (!(capsfilter = __prepare_capsfilter_for_filesrc_pipeline(source, is_audio))) goto exit; APPEND_ELEMENT(element_list, capsfilter);