webrtc_ini: Add new item to enable network simulator 59/265759/7
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 28 Oct 2021 06:06:45 +0000 (15:06 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Mon, 8 Nov 2021 00:41:37 +0000 (09:41 +0900)
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 <sc11.lee@samsung.com>
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc_ini.c
src/webrtc_source.c

index 37da9ce4140c7d32ed5126e8ac78ee8e0cd48905..6d816374c3c34b320fb53462da02ccefbae4686e 100644 (file)
@@ -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;
index 1ba56a99cdfd13f96a7b5135e77417023b455eee..70c7168546f29d05e5e951783f2c9a6d7e4d1583 100644 (file)
@@ -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
index efc778f19687cd6cc2852a6ef6ff266e5e239651..3045eee0f0eea573777037aae14db0dbc734a0b7 100644 (file)
@@ -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);
index 63f6312d5d27681abe4449089b8a0ab29581b325..32f4acfd1569043d30b31739ec264e13312fff44 100644 (file)
 #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);