Modified node creation logic 26/71526/1
authorVyacheslav Valkovoy <v.valkovoy@samsung.com>
Wed, 25 May 2016 17:45:19 +0000 (20:45 +0300)
committerVyacheslav Valkovoy <v.valkovoy@samsung.com>
Wed, 25 May 2016 17:45:40 +0000 (20:45 +0300)
Change-Id: I73a66dfd79848a984ae5b6941e06e12115cdb05b
Signed-off-by: Vyacheslav Valkovoy <v.valkovoy@samsung.com>
include/media_streamer_gst.h
include/media_streamer_priv.h
include/media_streamer_util.h
src/media_streamer.c
src/media_streamer_gst.c
src/media_streamer_node.c
src/media_streamer_util.c

index 25984237f6c770c0c828cb06913beb1b37a418a1..07f964b81c67c69a16cd7f422307691f6c8c6e78 100644 (file)
@@ -36,6 +36,8 @@
 #define MEDIA_STREAMER_CONVERTER_KLASS "Filter/Converter"
 #define MEDIA_STREAMER_DECODER_KLASS "Codec/Decoder"
 #define MEDIA_STREAMER_SINK_KLASS "Sink"
+#define MEDIA_STREAMER_STRICT "_strict_"
+
 
 /**
  * @brief Generates dot files for GStreamer pipeline.
@@ -74,6 +76,13 @@ GstElement *__ms_link_with_new_element(GstElement *previous_element, GstPad *pre
  */
 GstElement *__ms_element_create(const char *plugin_name, const char *name);
 
+/**
+ * @brief Creates GstElement from specified node_plug_s structure.
+ *
+ * @since_tizen 3.0
+ */
+GstElement *__ms_node_element_create(node_plug_s *plug_info, media_streamer_node_type_e type);
+
 /**
  * @brief Creates encoder GstElement by mime type.
  *
@@ -100,7 +109,7 @@ GstElement *__ms_audio_encoder_element_create(void);
  *
  * @since_tizen 3.0
  */
-GstElement *__ms_rtp_element_create(media_streamer_node_s *ms_node);
+GstElement *__ms_rtp_element_create(void);
 
 /**
  * @brief Prepares rtp container according to parameters data.
@@ -192,6 +201,12 @@ int __ms_element_get_pad_fmt(GstElement *gst_element, const char *pad_name, medi
  */
 int __ms_element_set_fmt(media_streamer_node_s *node, const char *pad_name, media_format_h fmt);
 
+/**
+ * @brief Creates GstCap's from mediaformat.
+ *
+ * @since_tizen 3.0
+ */
+GstCaps *__ms_create_caps_from_fmt(media_format_h fmt);
 /**
  * @brief Seeks GstElement to according time value.
  *
index 07aaee467392ecd0759b9540b9275ee6ad25691d..c930c6c6ae8af288cf096c2e7a696e672dfcab6a 100755 (executable)
@@ -60,6 +60,28 @@ typedef struct {
        char *origin_name;
 } param_s;
 
+/**
+ * @brief Media Streamer node_info type handle.
+ *
+ * @since_tizen 3.0
+ */
+typedef struct {
+       char *klass_name;
+       char *default_name;
+} node_info_s;
+
+/**
+ * @brief Media Streamer node_plug type handle.
+ *
+ * @since_tizen 3.0
+ */
+typedef struct {
+       node_info_s *info;
+       GstCaps *src_caps;
+       GstCaps *sink_caps;
+       gchar **exclude_names;
+} node_plug_s;
+
 /**
  * @brief Media Streamer type handle.
  *
index 9644286788eb170004d8c4e3eb5e688a3c482c00..2cb2d730c32762cc2068503610b633b28b726285 100644 (file)
@@ -93,10 +93,10 @@ extern "C" {
 
 /* Ini Utils */
 #ifndef MEDIA_STREAMER_INI_PATH
-       #define MEDIA_STREAMER_INI_PATH "/etc/media_streamer.ini"
+       #define MEDIA_STREAMER_INI_PATH "/etc/media_streamer.ini"
 #endif
 
-#define MEDIA_STREAMER_INI_MAX_STRLEN  100
+#define MEDIA_STREAMER_INI_MAX_STRLEN 100
 #define RTP_STREAM_DISABLED (0)
 
 /**
@@ -245,6 +245,14 @@ typedef struct {
                g_object_set_data_full(G_OBJECT(obj), key, (gpointer)val, __ms_rtp_param_value_destroy); \
        } while (0)
 
+#define MS_GET_CAPS_TYPE(caps, type) \
+       do { \
+               if (caps && gst_caps_get_size(caps) > 0) \
+                       type = gst_structure_get_name(gst_caps_get_structure(caps, 0)); \
+               else \
+                       type = NULL; \
+       } while (0)
+
 /**
  * @brief Loads media streamer settings from ini file.
  *        The default values will be used if error has occurred.
@@ -274,6 +282,13 @@ gboolean __ms_destroy_ini_dictionary(dictionary *dict);
  */
 gchar *__ms_ini_get_string(dictionary *dict, const char *ini_path, char *default_str);
 
+/**
+ * @brief Reads comma-separated string list from ini file.
+ *
+ * @since_tizen 3.0
+ */
+void __ms_ini_read_list(dictionary *dict, const char *key, gchar ***list);
+
 /**
  * @brief Converts Media Format mime type into Caps media format string.
  *
index 1110273922973d11fc0c86af1d25b92b4cdf6fdc..d573a54071e09223cb327cff1e474290bf204cea 100644 (file)
@@ -98,9 +98,10 @@ int media_streamer_node_create(media_streamer_node_type_e type, media_format_h i
                __ms_node_destroy(ms_node);
                ms_error("Error creating Node [%d]", ret);
                return ret;
+       } else {
+               ms_info("Node [%s] created", ms_node->name);
        }
 
-       ms_info("Node [%s] created", ms_node->name);
        *node = (media_streamer_node_h) ms_node;
 
        return ret;
index 7ebdee1bf5e501a134ad55c1b105f66173ad0bb2..583a1c5fbcea2e865dd83f1eb12ee154739fcc47 100755 (executable)
@@ -23,6 +23,8 @@
 #define H264_PARSER_CONFIG_INTERVAL 5
 #define H264_ENCODER_ZEROLATENCY 0x00000004
 
+#define NODE_CONF_FIELD_LEN 100
+
 void __ms_generate_dots(GstElement *bin, gchar *name_tag)
 {
        gchar *dot_name;
@@ -236,16 +238,11 @@ static gboolean __ms_get_peer_element(GstPad *source_pad, GstElement *found_elem
 
 const gchar *__ms_get_pad_type(GstPad *element_pad)
 {
-       const gchar *element_pad_type = NULL;
-       GstCaps *element_pad_caps = gst_pad_query_caps(element_pad, 0);
-       if (gst_caps_get_size(element_pad_caps) > 0) {
-               GstStructure *element_pad_struct = gst_caps_get_structure(element_pad_caps, 0);
-               element_pad_type = gst_structure_get_name(element_pad_struct);
-       } else {
-               ms_debug("Caps size of element is 0");
-       }
-       gst_caps_unref(element_pad_caps);
-       return element_pad_type;
+       const gchar *pad_type = NULL;
+       GstCaps *pad_caps = gst_pad_query_caps(element_pad, 0);
+       MS_GET_CAPS_TYPE(pad_caps, pad_type);
+       gst_caps_unref(pad_caps);
+       return pad_type;
 }
 
 static gboolean __ms_intersect_pads(GstPad *src_pad, GstPad *sink_pad)
@@ -829,7 +826,7 @@ static gboolean __ms_sink_bin_prepare(media_streamer_s * ms_streamer, GstPad * s
                        previous_element = __ms_combine_next_element(previous_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_SINK_KLASS, NULL, NULL);
                }
        } else if (MS_ELEMENT_IS_AUDIO(src_pad_type)) {
-               previous_element = __ms_combine_next_element(previous_element, NULL, ms_streamer->topology_bin, MEDIA_STREAMER_DECODER_KLASS, NULL, NULL);
+               previous_element = __ms_combine_next_element(previous_element, src_pad, ms_streamer->topology_bin, MEDIA_STREAMER_DECODER_KLASS, NULL, NULL);
                previous_element = __ms_combine_next_element(previous_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_QUEUE_KLASS, NULL, DEFAULT_QUEUE);
                previous_element = __ms_combine_next_element(previous_element, NULL, ms_streamer->sink_bin, MEDIA_STREAMER_SINK_KLASS, NULL, NULL);
        } else {
@@ -915,6 +912,113 @@ GstElement *__ms_element_create(const char *plugin_name, const char *name)
        return plugin_elem;
 }
 
+static gboolean __ms_feature_node_filter(GstPluginFeature *feature, gpointer data)
+{
+       node_plug_s *plug_info = (node_plug_s*)data;
+
+       if (!GST_IS_ELEMENT_FACTORY(feature))
+               return FALSE;
+
+       gboolean can_accept = FALSE;
+       GstElementFactory *factory = GST_ELEMENT_FACTORY(feature);
+       const gchar *factory_klass = gst_element_factory_get_klass(factory);
+
+       if (plug_info && g_strrstr(factory_klass, plug_info->info->klass_name)) {
+
+               if (GST_IS_CAPS(plug_info->src_caps))
+                       can_accept = can_accept || gst_element_factory_can_src_any_caps(factory, plug_info->src_caps);
+
+               if (GST_IS_CAPS(plug_info->sink_caps))
+                       can_accept = can_accept || gst_element_factory_can_sink_any_caps(factory, plug_info->sink_caps);
+
+               if (can_accept) {
+                       int index = 0;
+                       for ( ; plug_info->exclude_names && plug_info->exclude_names[index]; ++index) {
+                               if (g_strrstr(GST_OBJECT_NAME(factory), plug_info->exclude_names[index])) {
+                                       ms_debug("Skipping compatible factory [%s] as excluded.", GST_OBJECT_NAME(factory));
+                                       return FALSE;
+                               }
+                       }
+
+                       ms_info("[INFO] Found compatible factory [%s] for klass [%s]",
+                               GST_OBJECT_NAME(factory), factory_klass);
+                       return TRUE;
+               }
+
+       }
+
+       return FALSE;
+}
+
+GstElement *__ms_node_element_create(node_plug_s *plug_info, media_streamer_node_type_e type)
+{
+       dictionary *dict = NULL;
+       GstElement *gst_element = NULL;
+
+       const gchar *src_type, *sink_type;
+       MS_GET_CAPS_TYPE(plug_info->src_caps, src_type);
+       MS_GET_CAPS_TYPE(plug_info->sink_caps, sink_type);
+
+       /* 1. Main priority:
+        * If Node klass defined as MEDIA_STREAMER_STRICT,
+        * element will be created immediately by default_name */
+       if (!strncmp(plug_info->info->klass_name, MEDIA_STREAMER_STRICT, 10)
+                       || ( !src_type && !sink_type)) {
+
+               if(type == MEDIA_STREAMER_NODE_TYPE_RTP)
+                       gst_element = __ms_rtp_element_create();
+               else
+                       gst_element = __ms_element_create(plug_info->info->default_name, NULL);
+       } else {
+               /* 2. Second priority:
+                * Try to get plugin name that defined in ini file
+                * according with node type and specified format. */
+               ms_info("Specified node formats types: in[%s] - out[%s]", sink_type, src_type);
+               gchar conf_key[NODE_CONF_FIELD_LEN] = {0,};
+               if (snprintf(conf_key, NODE_CONF_FIELD_LEN, "node type %d:%s", type, (sink_type ? sink_type : src_type)) >= NODE_CONF_FIELD_LEN) {
+                       ms_error("Failed to generate config field name, size >= %d", NODE_CONF_FIELD_LEN);
+                       return NULL;
+               }
+
+               __ms_load_ini_dictionary(&dict);
+               gchar *plugin_name = __ms_ini_get_string(dict, conf_key, NULL);
+
+               if (plugin_name) {
+                       gst_element = __ms_element_create(plugin_name, NULL);
+                       MS_SAFE_GFREE(plugin_name);
+               }
+               __ms_destroy_ini_dictionary(dict);
+       }
+
+       /* 3. Third priority:
+        * If previous cases did not create a valid gst_element,
+        * try to find compatible plugin in gstreamer registry.
+        * Elements that are compatible but defined as excluded will be skipped*/
+       if(!gst_element) {
+               __ms_load_ini_dictionary(&dict);
+
+               /* Read exclude elements list */
+               __ms_ini_read_list(dict, "general:exclude elements", &plug_info->exclude_names);
+
+               GList *factories = gst_registry_feature_filter(gst_registry_get(),
+                       __ms_feature_node_filter, TRUE, plug_info);
+
+               if (factories) {
+                       GstElementFactory *factory = GST_ELEMENT_FACTORY(factories->data);
+                       gst_element = __ms_element_create(GST_OBJECT_NAME(factory), NULL);
+               } else {
+                       ms_error("Error: could not found any compatible element for node [%d]: in[%s] - out[%s]",
+                               type, sink_type, src_type);
+               }
+
+               g_strfreev(plug_info->exclude_names);
+               gst_plugin_list_free(factories);
+               __ms_destroy_ini_dictionary(dict);
+       }
+
+       return gst_element;
+}
+
 GstElement *__ms_video_encoder_element_create(dictionary * dict, media_format_mimetype_e mime)
 {
        char *plugin_name = NULL;
@@ -1050,10 +1154,8 @@ GstElement *__ms_audio_encoder_element_create(void)
        return audio_enc_bin;
 }
 
-GstElement *__ms_rtp_element_create(media_streamer_node_s * ms_node)
+GstElement *__ms_rtp_element_create(void)
 {
-       ms_retvm_if(ms_node == NULL, (GstElement *) NULL, "Error empty rtp node Handle");
-
        GstElement *rtp_container = gst_bin_new("rtp_container");
        ms_retvm_if(!rtp_container, (GstElement *) NULL, "Error: creating elements for rtp container");
 
@@ -1387,7 +1489,7 @@ int __ms_pipeline_create(media_streamer_s *ms_streamer)
        return ret;
 }
 
-static GstCaps *__ms_create_caps_from_fmt(media_format_h fmt)
+GstCaps *__ms_create_caps_from_fmt(media_format_h fmt)
 {
        GstCaps *caps = NULL;
        gchar *caps_name = NULL;
index 222780ef0b52f7e96c6a679f73cdb719bde4a29c..849a61bb8da0c8800aad6f2a4e5fd0f49ad9bf3c 100755 (executable)
@@ -46,6 +46,35 @@ param_s param_table[] = {
        {NULL, NULL}
 };
 
+node_info_s nodes_info[] = {
+       {NULL, NULL},                              /* MEDIA_STREAMER_NODE_TYPE_NONE */
+       {"Source", "fakesrc"},                     /* MEDIA_STREAMER_NODE_TYPE_SRC */
+       {"Sink", "fakesink"},                      /* MEDIA_STREAMER_NODE_TYPE_SINK */
+       {"Codec/Encoder", "x264enc"},              /* MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER */
+       {"Codec/Decoder", "avdec_h264"},           /* MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER */
+       {"Codec/Encoder", "amrnbenc"},             /* MEDIA_STREAMER_NODE_TYPE_AUDIO_ENCODER */
+       {"Codec/Decoder", "amrnbdec"},             /* MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER */
+       {MEDIA_STREAMER_STRICT, "videoconvert"},   /* MEDIA_STREAMER_NODE_TYPE_VIDEO_CONVERTER */
+       {MEDIA_STREAMER_STRICT, "audioconvert"},   /* MEDIA_STREAMER_NODE_TYPE_AUDIO_CONVERTER */
+       {MEDIA_STREAMER_STRICT, "audioresample"},  /* MEDIA_STREAMER_NODE_TYPE_AUDIO_RESAMPLE */
+       {"Payloader", "rtph264pay"},               /* MEDIA_STREAMER_NODE_TYPE_VIDEO_PAY */
+       {"Payloader", "rtpamrpay"},                /* MEDIA_STREAMER_NODE_TYPE_AUDIO_PAY */
+       {"Depayloader", "rtph264depay"},           /* MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY */
+       {"Depayloader", "rtpamrdepay"},            /* MEDIA_STREAMER_NODE_TYPE_AUDIO_DEPAY */
+       {MEDIA_STREAMER_STRICT, "capsfilter"},     /* MEDIA_STREAMER_NODE_TYPE_FILTER */
+       {MEDIA_STREAMER_STRICT, "tee"},            /* MEDIA_STREAMER_NODE_TYPE_TEE */
+       {MEDIA_STREAMER_STRICT, "queue"},          /* MEDIA_STREAMER_NODE_TYPE_QUEUE */
+       {MEDIA_STREAMER_STRICT, "multiqueue"},     /* MEDIA_STREAMER_NODE_TYPE_MQUEUE */
+       {"Codec/Muxer", "qtmux"},                  /* MEDIA_STREAMER_NODE_TYPE_MUXER */
+       {"Codec/Demuxer", "qtdemux"},              /* MEDIA_STREAMER_NODE_TYPE_DEMUXER */
+       {MEDIA_STREAMER_STRICT, "rtpbin"},         /* MEDIA_STREAMER_NODE_TYPE_RTP */
+       {MEDIA_STREAMER_STRICT, "input-selector"}, /* MEDIA_STREAMER_NODE_TYPE_INPUT_SELECTOR */
+       {MEDIA_STREAMER_STRICT, "output-selector"},/* MEDIA_STREAMER_NODE_TYPE_OUTPUT_SELECTOR */
+       {MEDIA_STREAMER_STRICT, "interleave"},     /* MEDIA_STREAMER_NODE_TYPE_INTERLEAVE */
+       {MEDIA_STREAMER_STRICT, "deinterleave"},   /* MEDIA_STREAMER_NODE_TYPE_DEINTERLEAVE */
+       {NULL, NULL}
+};
+
 static gboolean __ms_rtp_node_has_property(media_streamer_node_s *ms_node, const gchar *param_name)
 {
        ms_retvm_if(!ms_node || !ms_node->gst_element, FALSE, "Error: empty node");
@@ -124,87 +153,25 @@ int __ms_node_create(media_streamer_node_s *node, media_format_h in_fmt, media_f
        ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
 
        int ret = MEDIA_STREAMER_ERROR_NONE;
-       dictionary *dict = NULL;
-       char *plugin_name = NULL;
-       media_format_mimetype_e mime;
 
-       if (MEDIA_FORMAT_ERROR_NONE != media_format_get_video_info(out_fmt, &mime, NULL, NULL, NULL, NULL))
-               media_format_get_audio_info(out_fmt, &mime, NULL, NULL, NULL, NULL);
-       char *format_prefix = NULL;
+       GstCaps *sink_caps = in_fmt ? __ms_create_caps_from_fmt(in_fmt) : NULL;
+       GstCaps *src_caps = out_fmt ? __ms_create_caps_from_fmt(out_fmt) : NULL;
 
-       __ms_load_ini_dictionary(&dict);
+       node_plug_s plug_info = {&(nodes_info[node->type]), src_caps, sink_caps, NULL};
+       ms_info("Creating node with info: klass_name[%s]; default[%s]",
+                       plug_info.info->klass_name, plug_info.info->default_name);
 
-       switch (node->type) {
-       case MEDIA_STREAMER_NODE_TYPE_VIDEO_ENCODER:
-               format_prefix = g_strdup_printf("%s:encoder", __ms_convert_mime_to_string(mime));
-               plugin_name = __ms_ini_get_string(dict, format_prefix, DEFAULT_VIDEO_ENCODER);
-               node->gst_element = __ms_video_encoder_element_create(dict, mime);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER:
-               format_prefix = g_strdup_printf("%s:decoder", __ms_convert_mime_to_string(mime));
-               plugin_name = __ms_ini_get_string(dict, format_prefix, DEFAULT_VIDEO_DECODER);
-               node->gst_element = __ms_video_decoder_element_create(dict, mime);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_PARSER:
-               format_prefix = g_strdup_printf("%s:parser", __ms_convert_mime_to_string(mime));
-               plugin_name = __ms_ini_get_string(dict, format_prefix, DEFAULT_VIDEO_PARSER);
-               node->gst_element = __ms_element_create(plugin_name, NULL);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_FILTER:
-               node->gst_element = __ms_element_create(DEFAULT_FILTER, NULL);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_VIDEO_PAY:
-               format_prefix = g_strdup_printf("%s:rtppay", __ms_convert_mime_to_string(mime));
-               plugin_name = __ms_ini_get_string(dict, format_prefix, DEFAULT_VIDEO_RTPPAY);
-               node->gst_element = __ms_element_create(plugin_name, NULL);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_AUDIO_PAY:
-               plugin_name = __ms_ini_get_string(dict, "audio-raw:rtppay", DEFAULT_AUDIO_RTPPAY);
-               node->gst_element = __ms_element_create(plugin_name, NULL);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY:
-               format_prefix = g_strdup_printf("%s:rtpdepay", __ms_convert_mime_to_string(mime));
-               plugin_name = __ms_ini_get_string(dict, format_prefix, DEFAULT_VIDEO_RTPDEPAY);
-               node->gst_element = __ms_element_create(plugin_name, NULL);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_AUDIO_DEPAY:
-               plugin_name = __ms_ini_get_string(dict, "audio-raw:rtpdepay", DEFAULT_AUDIO_RTPDEPAY);
-               node->gst_element = __ms_element_create(plugin_name, NULL);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_RTP:
-               node->gst_element = __ms_rtp_element_create(node);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_QUEUE:
-               node->gst_element = __ms_element_create(DEFAULT_QUEUE, NULL);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_AUDIO_ENCODER:
-               node->gst_element = __ms_audio_encoder_element_create();
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_AUDIO_DECODER:
-               node->gst_element = __ms_element_create(DEFAULT_AUDIO_DECODER, NULL);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_VIDEO_CONVERTER:
-               node->gst_element = __ms_element_create(DEFAULT_VIDEO_CONVERT, NULL);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_AUDIO_CONVERTER:
-               node->gst_element = __ms_element_create(DEFAULT_AUDIO_CONVERT, NULL);
-               break;
-       case MEDIA_STREAMER_NODE_TYPE_AUDIO_RESAMPLE:
-               node->gst_element = __ms_element_create(DEFAULT_AUDIO_RESAMPLE, NULL);
-               break;
-       default:
-               ms_error("Error: invalid node Type [%d]", node->type);
-               break;
-       }
+       node->gst_element = __ms_node_element_create(&plug_info, node->type);
+       if (node->gst_element)
+               node->name = gst_element_get_name(node->gst_element);
+       else
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
 
-       MS_SAFE_FREE(plugin_name);
-       MS_SAFE_FREE(format_prefix);
-       __ms_destroy_ini_dictionary(dict);
+       if (src_caps)
+               gst_caps_unref(src_caps);
 
-       if (node->gst_element == NULL)
-               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
-       else
-               node->name = gst_element_get_name(node->gst_element);
+       if (sink_caps)
+               gst_caps_unref(sink_caps);
 
        return ret;
 }
index 8ed41a3ae88de6978f4c47bf5221931aebb24b02..818e2089e6cd95e1c65fabfb3e7c70f0f22d5844 100644 (file)
@@ -82,16 +82,16 @@ gchar *__ms_ini_get_string(dictionary *dict, const char *ini_path, char *default
        ms_retvm_if(ini_path == NULL, NULL, "Invalid ini path");
 
        if (dict == NULL) {
-               result_str = g_strdup(default_str);
+               result_str = default_str;
        } else {
                gchar *str = NULL;
                str = iniparser_getstring(dict, ini_path, default_str);
                if (str && (strlen(str) > 0) && (strlen(str) < MEDIA_STREAMER_INI_MAX_STRLEN))
-                       result_str = g_strdup(str);
+                       result_str = str;
                else
-                       result_str = g_strdup(default_str);
+                       result_str = default_str;
        }
-       return result_str;
+       return result_str ? g_strdup(result_str) : NULL;
 }
 
 gboolean __ms_load_ini_dictionary(dictionary **dict)
@@ -127,7 +127,7 @@ gboolean __ms_destroy_ini_dictionary(dictionary *dict)
        return TRUE;
 }
 
-static void __ms_ini_read_list(dictionary *dict, const char* key, gchar ***list)
+void __ms_ini_read_list(dictionary *dict, const char* key, gchar ***list)
 {
        ms_retm_if(!dict || !list || !key, "Handle is NULL");