Added VideoFile / VideoFile + Subtitles / HTTPsource playing Scenarios. 15/49215/2
authorVyacheslav Valkovoy <v.valkovoy@samsung.com>
Thu, 8 Oct 2015 14:13:25 +0000 (17:13 +0300)
committerVyacheslav Valkovoy <v.valkovoy@samsung.com>
Thu, 8 Oct 2015 14:15:25 +0000 (17:15 +0300)
Change-Id: I1775b1f3da09424a2e92299770d25f4c516e9756
Signed-off-by: Vyacheslav Valkovoy <v.valkovoy@samsung.com>
include/media_streamer_gst.h
include/media_streamer_util.h
src/media_streamer_gst.c
src/media_streamer_node.c
src/media_streamer_util.c
test/media_streamer_test.c

index fb253cc3c97ac3bd56b283ce87ebbb8095e46b3d..c664cc7a6da1149f11e3ecc85882872b89e45dd2 100755 (executable)
 
 #define MEDIA_STREAMER_PAYLOADER_KLASS "Codec/Payloader/Network/RTP"
 #define MEDIA_STREAMER_RTP_KLASS "Filter/Network/RTP"
+
 #define MEDIA_STREAMER_DEPAYLOADER_KLASS "Depayloader/Network/RTP"
 #define MEDIA_STREAMER_BIN_KLASS "Generic/Bin"
+#define MEDIA_STREAMER_OVERLAY_KLASS "Filter/Editor"
 #define MEDIA_STREAMER_PARSER_KLASS "Codec/Parser/Converter"
 #define MEDIA_STREAMER_CONVERTER_KLASS "Filter/Converter"
 #define MEDIA_STREAMER_DECODER_KLASS "Codec/Decoder"
  */
 void __ms_generate_dots(GstElement *bin, gchar *name_tag);
 
+/**
+ * @brief Finds GstElement by klass name.
+ *
+ * @since_tizen 3.0
+ */
+GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin,
+                                           const gchar *klass_name, const gchar *bin_name);
+
 /**
  * @brief Creates GstElement by klass name.
  *
@@ -129,7 +139,18 @@ gboolean __ms_element_set_property(GstElement *src_element,
 gboolean __ms_element_unlink(GstElement *src_element);
 
 /**
- * @brief Callback function to link decodebin with the sink element at the streamer part.
+ * @brief Callback function to filter factories while decodebin is searching them.
+ *
+ * @since_tizen 3.0
+ */
+gint __ms_decodebin_autoplug_select(GstElement *bin,
+                                    GstPad *pad,
+                                    GstCaps *caps,
+                                    GstElementFactory *factory,
+                                    gpointer data);
+
+/**
+ * @brief Callback function to link decodebin for file playing.
  *
  * @since_tizen 3.0
  */
@@ -142,6 +163,13 @@ void __decodebin_newpad_streamer_cb(GstElement *decodebin, GstPad *pad, gpointer
  */
 void __decodebin_newpad_cb(GstElement *decodebin, GstPad *pad, gpointer user_data);
 
+/**
+ * @brief Callback function to link decodebin with the sink element at the client part.
+ *
+ * @since_tizen 3.0
+ */
+void __decodebin_newpad_client_cb(GstElement *decodebin, GstPad *pad, gpointer user_data);
+
 /**
  * @brief Creates next element by klass or by properties and links with the previous one.
  *
index e1ffa30d9612a18928e29533c8cd61ba335c38ff..074d3d821c76b6d9f45dfc18e976507c8863097b 100755 (executable)
@@ -114,20 +114,22 @@ typedef struct __media_streamer_ini {
 #define DEFAULT_VIDEO_SOURCE                "ximagesrc"
 #define DEFAULT_APP_SOURCE                  "appsrc"
 #define DEFAULT_AUDIO_SINK                  "pulsesink"
-#define DEFAULT_VIDEO_SINK                  "autovideosink"
+#define DEFAULT_VIDEO_SINK                  "waylandsink"
 #define DEFAULT_VIDEO_CONVERT               "videoconvert"
+#define DEFAULT_TEXT_OVERLAY                "textoverlay"
 #define DEFAULT_AUDIO_CONVERT               "audioconvert"
 #define DEFAULT_AUDIO_RESAMPLE              "audioresample"
 #define DEFAULT_APP_SINK                    "appsink"
 
 /* udp streaming */
 #define DEFAULT_UDP_SOURCE                  "udpsrc"
+#define DEFAULT_HTTP_SOURCE                 "souphttpsrc"
 #define DEFAULT_UDP_SINK                    "udpsink"
 #define DEFAULT_RTP_BIN                     "rtpbin"
 
 /* video format defaults */
-#define DEFAULT_VIDEO_ENCODER               "omxh264enc"
-#define DEFAULT_VIDEO_DECODER               "omxh264dec"
+#define DEFAULT_VIDEO_ENCODER               "avenc_h263"
+#define DEFAULT_VIDEO_DECODER               "avdec_h263"
 #define DEFAULT_VIDEO_PARSER                "h263parse"
 #define DEFAULT_VIDEO_RTPPAY                "rtph263pay"
 #define DEFAULT_VIDEO_RTPDEPAY              "rtph263depay"
@@ -145,6 +147,7 @@ typedef struct __media_streamer_ini {
 #define MS_ELEMENT_IS_INPUT(el) g_strrstr(el, "in")
 #define MS_ELEMENT_IS_AUDIO(el) g_strrstr(el, "audio")
 #define MS_ELEMENT_IS_VIDEO(el) g_strrstr(el, "video")
+#define MS_ELEMENT_IS_TEXT(el) g_strrstr(el, "text")
 #define MS_ELEMENT_IS_ENCODER(el) g_strrstr(el, "encoder")
 #define MS_ELEMENT_IS_DECODER(el) g_strrstr(el, "decoder")
 
@@ -236,6 +239,13 @@ gchar *__ms_ini_get_string(dictionary *dict, const char *ini_path,
  */
 const gchar *__ms_convert_mime_to_string(media_format_mimetype_e mime);
 
+/**
+ * @brief Converts Media Format mime type into rtp media type.
+ *
+ * @since_tizen 3.0
+ */
+const gchar *__ms_convert_mime_to_rtp_format(media_format_mimetype_e mime);
+
 /**
  * @brief Converts Caps stream format into Media Format mime type.
  *
index 511b2f7c64e486c541e71a20d841a6d7c246ebba..a6132d5683b46a8780678998be24a8e5d1388cd6 100755 (executable)
@@ -351,9 +351,9 @@ static void __ms_link_elements_on_pad_added_cb(GstPad *new_pad, GstElement *sink
 }
 #endif
 
-static GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin,
-                                                  const gchar *klass_name,
-                                                  const gchar *bin_name)
+GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin,
+                                           const gchar *klass_name,
+                                           const gchar *bin_name)
 {
        GValue elem = G_VALUE_INIT;
        GstIterator *bin_iterator = gst_bin_iterate_sorted(GST_BIN(sink_bin));
@@ -368,6 +368,7 @@ static GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin,
 
        while (GST_ITERATOR_OK == gst_iterator_next(bin_iterator, &elem)) {
                found_element = (GstElement *) g_value_get_object(&elem);
+
                const gchar *found_klass = gst_element_factory_get_klass(gst_element_get_factory(found_element));
 
                if (klass_name && g_strrstr(found_klass, klass_name)) {
@@ -376,6 +377,7 @@ static GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin,
                        pad_iterator = gst_element_iterate_sink_pads(found_element);
                        while (GST_ITERATOR_OK == gst_iterator_next(pad_iterator, &element)) {
                                pad = (GstPad *) g_value_get_object(&element);
+
                                if (!gst_pad_is_linked(pad)) {
                                        unlinked_pad_found = TRUE;
                                }
@@ -402,31 +404,33 @@ static GstElement *__ms_bin_find_element_by_klass(GstElement *sink_bin,
        return found ? found_element : NULL;
 }
 
-int __ms_get_rank_increase(const char *factory_class)
+int __ms_get_rank_increase(const char *factory_name)
 {
        gint rank_priority = 20;
        gint rank_second = 10;
+       gint rank_skip = -10;
        gint ret = 0;
 
-       if (g_strrstr(factory_class, "Dsp"))
+       if (g_strrstr(factory_name, "av"))
                ret = rank_priority;
-       else if (g_strrstr(factory_class, "HW"))
-               ret = rank_priority;
-       else if (g_strrstr(factory_class, "Arm"))
+       else if (g_strrstr(factory_name, "omx"))
                ret = rank_second;
+       else if (g_strrstr(factory_name, "v4l2video"))
+               ret = rank_skip;
 
        return ret;
 }
 
 int __ms_factory_rank_compare(GstPluginFeature *first_feature, GstPluginFeature *second_feature)
 {
-       const gchar *class;
+       const gchar *name;
        int first_feature_rank_inc=0, second_feature_rank_inc = 0;
 
-       class = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(first_feature));
-               first_feature_rank_inc = __ms_get_rank_increase(class);
-       class = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(second_feature));
-               second_feature_rank_inc = __ms_get_rank_increase(class);
+       name = gst_plugin_feature_get_plugin_name(first_feature);
+       first_feature_rank_inc = __ms_get_rank_increase(name);
+
+       name = gst_plugin_feature_get_plugin_name(second_feature);
+       second_feature_rank_inc = __ms_get_rank_increase(name);
 
        return (gst_plugin_feature_get_rank(second_feature) + second_feature_rank_inc) -
                 (gst_plugin_feature_get_rank(first_feature) + first_feature_rank_inc );
@@ -445,12 +449,11 @@ GstElement *__ms_create_element_by_registry(GstPad *src_pad, const gchar *klass_
        GList *factories;
        const GList *pads;
        GstElement *next_element = NULL;
-       GstCaps *new_pad_caps = NULL;
 
-       new_pad_caps = gst_pad_query_caps(src_pad, NULL);
+       GstCaps *new_pad_caps = gst_pad_query_caps(src_pad, NULL);
 
        factories = gst_registry_feature_filter(gst_registry_get(),
-                                               (GstPluginFeatureFilter)__ms_feature_filter, FALSE, NULL);
+                                           (GstPluginFeatureFilter)__ms_feature_filter, FALSE, NULL);
        factories = g_list_sort(factories, (GCompareFunc)__ms_factory_rank_compare);
 
        for(; factories != NULL ; factories = factories->next) {
@@ -476,7 +479,7 @@ GstElement *__ms_create_element_by_registry(GstPad *src_pad, const gchar *klass_
 
                                intersect_caps = gst_caps_intersect_full(new_pad_caps, static_caps, GST_CAPS_INTERSECT_FIRST);
 
-                               if (!gst_caps_is_empty(intersect_caps)) {
+                               if ((!gst_caps_is_any(static_caps)) && (!gst_caps_is_empty(intersect_caps))) {
                                        if (!next_element) {
                                                next_element = __ms_element_create(GST_OBJECT_NAME(factory), NULL);
                                        }
@@ -486,7 +489,8 @@ GstElement *__ms_create_element_by_registry(GstPad *src_pad, const gchar *klass_
                        }
                }
        }
-
+       gst_caps_unref(new_pad_caps);
+       gst_plugin_feature_list_free(factories);
        return next_element;
 }
 
@@ -500,38 +504,41 @@ GstElement * __ms_link_with_new_element(GstElement *previous_element,
 
        GValue element = G_VALUE_INIT;
        GstPad *sink_pad = NULL;
-       GstPad *src_pad = NULL;
+       GstPad *prev_elem_sink_pad = NULL;
        GstIterator *pad_iterator = NULL;
 
        if (next_elem_bin_name) {
                pad_iterator = gst_element_iterate_sink_pads(new_element);
-               while (GST_ITERATOR_OK == gst_iterator_next(pad_iterator, &element))
-               {
+               while (GST_ITERATOR_OK == gst_iterator_next(pad_iterator, &element)) {
                        sink_pad = (GstPad *)g_value_get_object(&element);
-                       src_pad = gst_element_get_static_pad(previous_element, "sink");
+                       prev_elem_sink_pad = gst_element_get_static_pad(previous_element, "sink");
 
-                       new_pad_caps = gst_pad_query_caps(src_pad, 0);
+                       new_pad_caps = gst_pad_query_caps(prev_elem_sink_pad, 0);
                        new_pad_struct = gst_caps_get_structure(new_pad_caps, 0);
                        new_pad_type = gst_structure_get_name(new_pad_struct);
 
                        if (!gst_pad_is_linked(sink_pad)) {
                                if(!strncmp(new_pad_type,GST_PAD_NAME(sink_pad), COMPARED_NUMBER)) {
                                        if (gst_element_link_pads_filtered(previous_element, "src", new_element,
-                                                                           GST_PAD_NAME(sink_pad), NULL)) {
+                                                       GST_PAD_NAME(sink_pad), NULL)) {
                                                ms_info("Succeeded to link [%s] -> [%s]\n",
-                                                        GST_ELEMENT_NAME(previous_element),
-                                                        GST_ELEMENT_NAME(new_element));
+                                GST_ELEMENT_NAME(previous_element),
+                                GST_ELEMENT_NAME(new_element));
                                        } else {
                                                ms_error("Failed to link [%s] -> [%s]\n",
-                                                         GST_ELEMENT_NAME(previous_element),
-                                                         GST_ELEMENT_NAME(new_element));
+                                 GST_ELEMENT_NAME(previous_element),
+                                 GST_ELEMENT_NAME(new_element));
                                        }
                                }
                        }
+                       MS_SAFE_UNREF(prev_elem_sink_pad);
+                       gst_caps_unref(new_pad_caps);
                        g_value_reset(&element);
+
                }
                g_value_unset(&element);
                gst_iterator_free(pad_iterator);
+
        } else {
                gboolean ret = gst_element_link_pads_filtered(previous_element, NULL, new_element, NULL, NULL);
 
@@ -543,6 +550,13 @@ GstElement * __ms_link_with_new_element(GstElement *previous_element,
                        ms_error("Failed to link [%s] and [%s] \n",
                      GST_ELEMENT_NAME(previous_element),
                      GST_ELEMENT_NAME(new_element));
+
+                       /*Remove created element*/
+                       if (gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(new_element)), new_element)) {
+                               ms_debug("Element removed from bin successfully ");
+                       } else {
+                               ms_error("Element was not removed from bin");
+                       }
                        new_element = NULL;
                }
        }
@@ -558,20 +572,10 @@ GstElement *__ms_combine_next_element(GstElement *previous_element,
        GstElement *found_element = NULL;
        GstElement *parent_element = NULL;
 
-       char *plugin_name = NULL;
-       char *format_prefix = NULL;
-
-       media_format_h vfmt_encoded = NULL;
-       media_format_create(&vfmt_encoded);
-       if (media_format_set_video_mime(vfmt_encoded, MEDIA_FORMAT_H264_SP) != MEDIA_FORMAT_ERROR_NONE) {
-               ms_error("media_format_set_video_mime failed!\n");
+       if(!previous_element) {
+               return NULL;
        }
 
-       media_format_set_video_width(vfmt_encoded, 1280);
-       media_format_set_video_height(vfmt_encoded, 720);
-       media_format_set_video_avg_bps(vfmt_encoded, 1031);
-       media_format_set_video_max_bps(vfmt_encoded, 2063);
-
        parent_element = (GstElement *)gst_element_get_parent(previous_element);
 
        /*Look for node created by user*/
@@ -590,35 +594,20 @@ GstElement *__ms_combine_next_element(GstElement *previous_element,
                        return NULL;
 
                /* Create element by element name*/
-               } else if(!found_element && !next_elem_klass_name) {
+               } else if(!found_element && !next_elem_klass_name && default_element) {
                        found_element = __ms_element_create(default_element, NULL);
 
                /* Create element by predefined format element type*/
-               } else if(!found_element && element_type) {
+               } else if(!found_element && MS_ELEMENT_IS_ENCODER(next_elem_bin_name)) {
 
                        dictionary *dict = NULL;
-                       media_format_mimetype_e mime;
-
-                       if (MEDIA_FORMAT_ERROR_NONE != media_format_get_video_info(vfmt_encoded, &mime,
-                                                                                   NULL, NULL, NULL, NULL)) {
-                               media_format_get_audio_info(vfmt_encoded, &mime, NULL, NULL, NULL, NULL);
-                       }
 
                        __ms_load_ini_dictionary(&dict);
 
-                       format_prefix = g_strdup_printf("%s:%s", __ms_convert_mime_to_string(mime), element_type);
-                       plugin_name = __ms_ini_get_string(dict, format_prefix, default_element);
-
-                       if (MS_ELEMENT_IS_ENCODER(next_elem_bin_name)) {
-                               if (MS_ELEMENT_IS_VIDEO(next_elem_bin_name)) {
-                                       found_element = __ms_video_encoder_element_create(dict, mime);
-                               } else if (MS_ELEMENT_IS_AUDIO(next_elem_bin_name)) {
-                                       found_element = __ms_audio_encoder_element_create();
-                               }
-                       } else if (MS_ELEMENT_IS_DECODER(next_elem_bin_name)) {
-                               if (MS_ELEMENT_IS_VIDEO(next_elem_bin_name)) {
-                                       found_element = __ms_video_decoder_element_create(dict, mime);
-                               }
+                       if (MS_ELEMENT_IS_VIDEO(next_elem_bin_name)) {
+                               found_element = __ms_video_encoder_element_create(dict, MEDIA_FORMAT_H263);
+                       } else {
+                               found_element = __ms_audio_encoder_element_create();
                        }
 
                        __ms_destroy_ini_dictionary(dict);
@@ -631,27 +620,70 @@ GstElement *__ms_combine_next_element(GstElement *previous_element,
                }
 
                /*Add created element*/
-               if (found_element && gst_bin_add(GST_BIN(parent_element), found_element)) {
-                       ms_debug("Element [%s] added into [%s] bin",
-                                 GST_ELEMENT_NAME(found_element),
-                                 GST_ELEMENT_NAME(parent_element));
+               if (found_element) {
+                       if (gst_bin_add(GST_BIN(parent_element), found_element)) {
+                               ms_debug("Element [%s] added into [%s] bin",
+                                                GST_ELEMENT_NAME(found_element),
+                                                GST_ELEMENT_NAME(parent_element));
+
+                               gst_element_sync_state_with_parent(found_element);
+                               previous_element = __ms_link_with_new_element(previous_element, found_element, NULL);
+                               __ms_generate_dots(parent_element, GST_ELEMENT_NAME(found_element));
+                       } else {
+                               ms_error("Element [%s] was not added into [%s] bin",
+                                                GST_ELEMENT_NAME(found_element),
+                                                GST_ELEMENT_NAME(parent_element));
+                               MS_SAFE_UNREF(found_element);
+                               found_element = NULL;
+                       }
                } else {
-                       ms_error("Element [%s] was not added into [%s] bin",
-                                 GST_ELEMENT_NAME(found_element),
-                                 GST_ELEMENT_NAME(parent_element));
+                       ms_error("Could not find compatible element to link [%s]",GST_ELEMENT_NAME(previous_element));
                }
-               previous_element = __ms_link_with_new_element(previous_element, found_element, NULL);
        }
 
-       gst_element_sync_state_with_parent(found_element);
-       __ms_generate_dots(parent_element, GST_ELEMENT_NAME(found_element));
-
-       MS_SAFE_FREE(plugin_name);
-       MS_SAFE_FREE(format_prefix);
+       MS_SAFE_UNREF(parent_element);
 
        return found_element;
 }
 
+ gint __ms_decodebin_autoplug_select(GstElement *bin,
+                                    GstPad *pad,
+                                    GstCaps *caps,
+                                    GstElementFactory *factory,
+                                    gpointer data)
+{
+       /* NOTE : GstAutoplugSelectResult is defined in gstplay-enum.h but not exposed */
+       typedef enum {
+               GST_AUTOPLUG_SELECT_TRY,
+               GST_AUTOPLUG_SELECT_EXPOSE,
+               GST_AUTOPLUG_SELECT_SKIP
+       } GstAutoplugSelectResult;
+
+       gchar *factory_name = NULL;
+       const gchar *klass = NULL;
+
+       factory_name = GST_OBJECT_NAME(factory);
+       klass = gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS);
+
+       ms_debug("Decodebin: found new element [%s] to link [%s]\n\n", factory_name, klass);
+
+       if ((g_strrstr(klass, "Codec/Decoder/Video"))) {
+
+               /* Skip Video4Linux decoders */
+               if (g_strrstr(factory_name, "v4l2video")) {
+                       ms_debug("Decodebin: skipping [%s] by not required\n", factory_name);
+                       return GST_AUTOPLUG_SELECT_SKIP;
+               }
+
+               /* Skip OMX HW decoders */
+               if (g_strrstr(factory_name, "omx")) {
+                       ms_debug("Decodebin: skipping [%s] by disabled", factory_name);
+                       return GST_AUTOPLUG_SELECT_SKIP;
+               }
+       }
+
+       return GST_AUTOPLUG_SELECT_TRY;
+}
 
 void __decodebin_newpad_streamer_cb(GstElement *decodebin, GstPad *new_pad, gpointer user_data)
 {
@@ -686,6 +718,7 @@ void __decodebin_newpad_streamer_cb(GstElement *decodebin, GstPad *new_pad, gpoi
                found_element = __ms_combine_next_element(found_element, MEDIA_STREAMER_PAYLOADER_KLASS, NULL, NULL, NULL);
                found_element = __ms_combine_next_element(found_element, MEDIA_STREAMER_BIN_KLASS, "rtp_container", NULL, NULL);
        }
+       gst_caps_unref(new_pad_caps);
 }
 
 void __decodebin_newpad_cb(GstElement *decodebin, GstPad *new_pad, gpointer user_data)
@@ -694,11 +727,14 @@ void __decodebin_newpad_cb(GstElement *decodebin, GstPad *new_pad, gpointer user
        ms_retm_if(ms_streamer == NULL, "Handle is NULL");
 
        GstElement *found_element = NULL;
+       GstElement *queue_element = NULL;
 
        GstCaps *new_pad_caps = NULL;
        GstStructure *new_pad_struct = NULL;
        const gchar *new_pad_type = NULL;
 
+       GstElement *sink_bin = NULL;
+
        ms_info("Received new pad '%s' from [%s]", GST_PAD_NAME(new_pad), GST_ELEMENT_NAME(decodebin));
 
        /* Check the new pad's type */
@@ -706,17 +742,120 @@ void __decodebin_newpad_cb(GstElement *decodebin, GstPad *new_pad, gpointer user
        new_pad_struct = gst_caps_get_structure(new_pad_caps, 0);
        new_pad_type = gst_structure_get_name(new_pad_struct);
 
-       if(MS_ELEMENT_IS_VIDEO(new_pad_type)) {
-               found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_VIDEO_CONVERT);
-       } else if (MS_ELEMENT_IS_AUDIO(new_pad_type)) {
+       if (MS_ELEMENT_IS_AUDIO(new_pad_type)) {
+               sink_bin = ms_streamer->sink_audio_bin;
                found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_AUDIO_CONVERT);
+       } else if (MS_ELEMENT_IS_VIDEO(new_pad_type)) {
+               sink_bin = ms_streamer->sink_video_bin;
+               found_element = __ms_bin_find_element_by_klass(GST_ELEMENT_PARENT(decodebin), MEDIA_STREAMER_OVERLAY_KLASS, NULL);
+               if (!found_element) {
+                       found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_VIDEO_CONVERT);
+               } else {
+                       found_element = __ms_combine_next_element(decodebin, MEDIA_STREAMER_OVERLAY_KLASS, NULL, NULL, NULL);
+                       return;
+               }
+       } else if (MS_ELEMENT_IS_TEXT(new_pad_type)) {
+               sink_bin = ms_streamer->sink_video_bin;
+               found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_TEXT_OVERLAY);
+               found_element = __ms_combine_next_element(found_element, NULL, NULL, NULL, DEFAULT_VIDEO_CONVERT);
+       } else {
+               ms_error("Pad type of the element is invalid");
+               return;
+       }
+
+       /* Check if sink bin has been added to pipeline before */
+       if (sink_bin && gst_object_get_parent(GST_OBJECT(sink_bin)) == NULL) {
+
+               /*Add created sink bin*/
+               if (gst_bin_add(GST_BIN(ms_streamer->pipeline), sink_bin)) {
+                       ms_debug("Bin [%s] added into [%s] bin",
+                                        GST_ELEMENT_NAME(sink_bin),
+                                        GST_ELEMENT_NAME(ms_streamer->pipeline));
+
+                       gst_element_sync_state_with_parent(sink_bin);
+               } else {
+                       ms_error("Bin [%s] was not added into [%s] bin",
+                                        GST_ELEMENT_NAME(sink_bin),
+                                        GST_ELEMENT_NAME(ms_streamer->pipeline));
+               }
+
+               queue_element = __ms_element_create(DEFAULT_QUEUE, NULL);
+
+               /*Add created queue element*/
+               if (gst_bin_add(GST_BIN(sink_bin), queue_element)) {
+                       ms_debug("Element [%s] added into [%s] bin",
+                                        GST_ELEMENT_NAME(queue_element),
+                                        GST_ELEMENT_NAME(sink_bin));
+
+                       gst_element_sync_state_with_parent(queue_element);
+                       found_element = __ms_link_with_new_element(found_element, queue_element, NULL);
+                       __ms_generate_dots(ms_streamer->pipeline, GST_ELEMENT_NAME(found_element));
+               } else {
+                       ms_error("Element [%s] was not added into [%s] bin",
+                                        GST_ELEMENT_NAME(queue_element),
+                                        GST_ELEMENT_NAME(sink_bin));
+               }
        }
 
        /* Getting Sink */
        found_element = __ms_combine_next_element(found_element, MEDIA_STREAMER_SINK_KLASS, NULL, NULL, NULL);
+
+       if(!found_element) {
+               ms_error("Could not link to sink element \n");
+       }
+
+       gst_caps_unref(new_pad_caps);
        __ms_generate_dots(ms_streamer->pipeline, "pipeline_linked");
 }
 
+void __decodebin_newpad_client_cb(GstElement *decodebin, GstPad *new_pad, gpointer user_data)
+{
+       media_streamer_node_s *ms_node = (media_streamer_node_s *)user_data;
+       ms_retm_if(ms_node == NULL, "Handle is NULL");
+
+       GstElement *found_element = NULL;
+
+       GstCaps *new_pad_caps = NULL;
+       GstStructure *new_pad_struct = NULL;
+       const gchar *new_pad_type = NULL;
+
+       ms_info("Received new pad '%s' from [%s]", GST_PAD_NAME(new_pad), GST_ELEMENT_NAME(decodebin));
+
+       /* Check the new pad's type */
+       new_pad_caps = gst_pad_query_caps(new_pad, 0);
+       new_pad_struct = gst_caps_get_structure(new_pad_caps, 0);
+       new_pad_type = gst_structure_get_name(new_pad_struct);
+
+       if (MS_ELEMENT_IS_AUDIO(new_pad_type)) {
+               found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_AUDIO_CONVERT);
+       } else if (MS_ELEMENT_IS_VIDEO(new_pad_type)) {
+
+               found_element = __ms_bin_find_element_by_klass(GST_ELEMENT_PARENT(decodebin), MEDIA_STREAMER_OVERLAY_KLASS, NULL);
+               if (!found_element) {
+                       found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_VIDEO_CONVERT);
+               } else {
+                       found_element = __ms_combine_next_element(decodebin, MEDIA_STREAMER_OVERLAY_KLASS, NULL, NULL, NULL);
+                       return;
+               }
+       } else if (MS_ELEMENT_IS_TEXT(new_pad_type)) {
+
+               found_element = __ms_combine_next_element(decodebin, NULL, NULL, NULL, DEFAULT_TEXT_OVERLAY);
+               found_element = __ms_combine_next_element(found_element, NULL, NULL, NULL, DEFAULT_VIDEO_CONVERT);
+       }
+       else {
+               ms_error("Pad type of the element is invalid");
+               return;
+       }
+
+       /* Getting Sink */
+       found_element = __ms_combine_next_element(found_element, MEDIA_STREAMER_SINK_KLASS, NULL, NULL, NULL);
+
+       if(!found_element) {
+               ms_error("Could not link to sink element \n");
+       }
+       gst_caps_unref(new_pad_caps);
+}
+
 static gboolean __ms_sink_bin_prepare(media_streamer_node_s *ms_node,
                                       GstElement *sink_bin, GstPad *source_pad)
 {
@@ -731,7 +870,7 @@ static gboolean __ms_sink_bin_prepare(media_streamer_node_s *ms_node,
 
        /* Getting Depayloader */
        found_element = __ms_bin_find_element_by_klass(sink_bin, MEDIA_STREAMER_DEPAYLOADER_KLASS,
-                                                       MEDIA_STREAMER_NODE_TYPE_NONE);
+                                                   MEDIA_STREAMER_NODE_TYPE_NONE);
 
        if (!found_element) {
                found_element = __ms_create_element_by_registry(source_pad, MEDIA_STREAMER_DEPAYLOADER_KLASS);
@@ -748,19 +887,23 @@ static gboolean __ms_sink_bin_prepare(media_streamer_node_s *ms_node,
 
        previous_element = found_element;
        src_pad = gst_element_get_static_pad(found_element, "src");
-
        __ms_add_ghostpad(found_element, "sink", sink_bin, "sink");
 
-       previous_element = __ms_combine_next_element(previous_element, NULL, NULL, NULL, DEFAULT_QUEUE);
-
        /* Getting Decodebin */
        decodebin_usage = ms_node->parent_streamer->ini.use_decodebin;
        found_element = __ms_bin_find_element_by_klass(sink_bin, MEDIA_STREAMER_BIN_KLASS, MEDIA_STREAMER_NODE_TYPE_NONE);
 
        if (!found_element) {
                if (decodebin_usage) {
-                       previous_element = __ms_combine_next_element(previous_element, MEDIA_STREAMER_BIN_KLASS, NULL, NULL, NULL);
-                       g_signal_connect(previous_element, "pad-added", G_CALLBACK(__decodebin_newpad_cb), (gpointer )ms_node);
+
+                       found_element = __ms_element_create("decodebin", NULL);
+                       gst_bin_add_many((GstBin *)sink_bin, found_element, NULL);
+                       gst_element_sync_state_with_parent(found_element);
+                       g_signal_connect(found_element, "pad-added", G_CALLBACK(__decodebin_newpad_client_cb), (gpointer )ms_node);
+                       g_signal_connect(found_element, "autoplug-select", G_CALLBACK(__ms_decodebin_autoplug_select), NULL);
+                       previous_element = __ms_link_with_new_element(previous_element, found_element, NULL);
+                       __ms_element_set_state(found_element, GST_STATE_PLAYING);
+
                } else {
                        src_pad = gst_element_get_static_pad(previous_element, "src");
                        new_pad_caps = gst_pad_query_caps(src_pad, 0);
@@ -785,7 +928,7 @@ static gboolean __ms_sink_bin_prepare(media_streamer_node_s *ms_node,
        } else {
 
                /* If decode element was added but not linked yet */
-               if (!gst_pad_is_linked(src_pad)) {
+               if (!gst_pad_is_linked(gst_element_get_static_pad(found_element, "sink"))) {
                        previous_element = __ms_link_with_new_element(previous_element, found_element, NULL);
                } else {
 
@@ -828,6 +971,9 @@ static void __ms_rtpbin_pad_added_cb(GstElement *src, GstPad *new_pad, gpointer
        src_pad_caps = gst_pad_query_caps(target_pad, NULL);
 
        if (ms_node->parent_streamer && !gst_caps_is_any(src_pad_caps)) {
+
+               g_mutex_lock(&ms_node->parent_streamer->mutex_lock);
+
                gchar *source_pad_name = NULL;
                GstElement *sink_bin = NULL;
                GstStructure *src_pad_struct = NULL;
@@ -849,30 +995,32 @@ static void __ms_rtpbin_pad_added_cb(GstElement *src, GstPad *new_pad, gpointer
                        gst_ghost_pad_set_target(GST_GHOST_PAD(source_pad), new_pad);
                        gst_pad_set_active(source_pad, TRUE);
 
-                       g_mutex_lock(&ms_node->parent_streamer->mutex_lock);
                        if (__ms_sink_bin_prepare(ms_node, sink_bin, source_pad)) {
 
+                               gboolean add_ret = TRUE;
                                if (gst_object_get_parent(GST_OBJECT(sink_bin)) == NULL) {
-                                       gst_bin_add(GST_BIN(ms_node->parent_streamer->pipeline), sink_bin);
+                                       add_ret = gst_bin_add(GST_BIN(ms_node->parent_streamer->pipeline), sink_bin);
                                }
 
-                               gst_element_sync_state_with_parent(sink_bin);
+                               if(add_ret) {
+                                       gst_element_sync_state_with_parent(sink_bin);
 
-                               if (gst_element_link_pads(ms_node->gst_element, source_pad_name, sink_bin, "sink")) {
-                                       __ms_element_set_state(ms_node->gst_element, GST_STATE_PLAYING);
-                                       __ms_generate_dots(ms_node->parent_streamer->pipeline, "playing");
-                               } else {
-                                       ms_error("Failed to link [rtp_containeer].[%s] and [sink_bin].[sink]\n", source_pad_name);
+                                       if (gst_element_link_pads(ms_node->gst_element, source_pad_name, sink_bin, "sink")) {
+                                               __ms_element_set_state(ms_node->gst_element, GST_STATE_PLAYING);
+                                               __ms_generate_dots(ms_node->parent_streamer->pipeline, "playing");
+                                       } else {
+                                               ms_error("Failed to link [rtp_containeer].[%s] and [sink_bin].[sink]\n", source_pad_name);
+                                       }
                                }
                        } else {
                                ms_error("Failed to prepare sink_bin for pad type [%s]\n", src_pad_type);
                        }
 
-                       g_mutex_unlock(&ms_node->parent_streamer->mutex_lock);
-
                        MS_SAFE_UNREF(source_pad);
                        MS_SAFE_GFREE(source_pad_name);
                }
+               g_mutex_unlock(&ms_node->parent_streamer->mutex_lock);
+
        } else {
                ms_debug("Node doesn`t have parent streamer or caps media type\n");
        }
@@ -1083,7 +1231,12 @@ GstElement *__ms_rtp_element_create(media_streamer_node_s *ms_node)
        ms_retvm_if(!rtp_container || !rtp_elem, (GstElement *)NULL,
                    "Error: creating elements for rtp container");
 
-       gst_bin_add(GST_BIN(rtp_container), rtp_elem);
+       if(!gst_bin_add(GST_BIN(rtp_container), rtp_elem)) {
+               MS_SAFE_UNREF(rtp_container);
+               MS_SAFE_UNREF(rtp_elem);
+               return NULL;
+       }
+
        g_signal_connect(rtp_elem, "pad-added", G_CALLBACK(__ms_rtpbin_pad_added_cb), ms_node);
 
        return rtp_container;
@@ -1213,6 +1366,10 @@ int __ms_add_node_into_bin(media_streamer_s *ms_streamer, media_streamer_node_s
                        gst_ret = gst_bin_add(GST_BIN(ms_streamer->topology_bin), ms_node->gst_element);
                        bin_name = g_strdup(MEDIA_STREAMER_TOPOLOGY_BIN_NAME);
                        break;
+               case MEDIA_STREAMER_NODE_TYPE_VIDEO_DECODER:
+                       gst_ret = gst_bin_add(GST_BIN(ms_streamer->sink_video_bin), ms_node->gst_element);
+                       bin_name = g_strdup(MEDIA_STREAMER_VIDEO_SINK_BIN_NAME);
+                       break;
                case MEDIA_STREAMER_NODE_TYPE_VIDEO_DEPAY:
                        gst_ret = gst_bin_add(GST_BIN(ms_streamer->sink_video_bin), ms_node->gst_element);
                        bin_name = g_strdup(MEDIA_STREAMER_VIDEO_SINK_BIN_NAME);
@@ -1573,7 +1730,9 @@ int __ms_element_set_fmt(media_streamer_node_s *node, const char *pad_name, medi
        if (node->type == MEDIA_STREAMER_NODE_TYPE_RTP) {
                /* It is needed to set 'application/x-rtp' for audio and video udpsrc*/
                media_format_mimetype_e mime;
+               int audio_channels, audio_samplerate;
                GstElement *rtp_elem, *rtcp_elem;
+               gchar *rtp_caps_str = NULL;
 
                /*Check if it is a valid pad*/
                GstPad *pad = gst_element_get_static_pad(node->gst_element, pad_name);
@@ -1585,15 +1744,18 @@ int __ms_element_set_fmt(media_streamer_node_s *node, const char *pad_name, medi
                if (MEDIA_FORMAT_ERROR_NONE == media_format_get_video_info(fmt, &mime, NULL, NULL, NULL, NULL)) {
                        __ms_get_rtp_elements(node, &rtp_elem, &rtcp_elem, "video", "in", FALSE);
 
-                       caps = gst_caps_from_string("application/x-rtp,media=video,clock-rate=90000,encoding-name=H264");
+                       rtp_caps_str = g_strdup_printf("application/x-rtp,media=video,clock-rate=90000,encoding-name=%s",
+                                       __ms_convert_mime_to_rtp_format(mime));
+                       caps = gst_caps_from_string(rtp_caps_str);
                        ms_retvm_if(caps == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Fail creating caps from fmt.");
 
                        obj = __ms_get_property_owner(rtp_elem, "caps", &value);
-               } else if (MEDIA_FORMAT_ERROR_NONE == media_format_get_audio_info(fmt, &mime, NULL, NULL, NULL, NULL)) {
+               } else if (MEDIA_FORMAT_ERROR_NONE == media_format_get_audio_info(fmt, &mime, &audio_channels, &audio_samplerate, NULL, NULL)) {
                        __ms_get_rtp_elements(node, &rtp_elem, &rtcp_elem, "audio", "in", FALSE);
 
-                       caps = gst_caps_from_string("application/x-rtp,media=audio,clock-rate=44100,encoding-name=L16,"
-                                                   "encoding-params=1,channels=1,payload=96");
+                       rtp_caps_str = g_strdup_printf("application/x-rtp,media=audio,clock-rate=%d,encoding-name=%s,channels=%d,payload=96",
+                                       audio_samplerate, __ms_convert_mime_to_rtp_format(mime), audio_channels);
+                       caps = gst_caps_from_string(rtp_caps_str);
                        ms_retvm_if(caps == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "Fail creating caps from fmt.");
 
                        obj = __ms_get_property_owner(rtp_elem, "caps", &value);
@@ -1602,6 +1764,7 @@ int __ms_element_set_fmt(media_streamer_node_s *node, const char *pad_name, medi
                        return MEDIA_STREAMER_ERROR_INVALID_PARAMETER;
                }
 
+               MS_SAFE_GFREE(rtp_caps_str);
                MS_SAFE_UNREF(pad);
        } else {
                caps = __ms_create_caps_from_fmt(fmt);
index e37bd6f9fa50849d11f3878c0e5d6a474cf36947..cb4c07e90e05bb3f1a856f047ebbc38be2e5d2ff 100755 (executable)
@@ -161,7 +161,8 @@ int __ms_node_create(media_streamer_node_s *node,
                        dec_use = iniparser_getboolean(dict, "general:use decodebin", DEFAULT_USE_DECODEBIN);
                        if (dec_use) {
                                node->gst_element = __ms_element_create("decodebin", NULL);
-                               g_signal_connect(node->gst_element, "pad-added", G_CALLBACK (__decodebin_newpad_cb), (gpointer)node);
+                               g_signal_connect(node->gst_element, "pad-added", G_CALLBACK(__decodebin_newpad_client_cb), (gpointer )node);
+                               g_signal_connect(node->gst_element, "autoplug-select", G_CALLBACK(__ms_decodebin_autoplug_select), NULL);
                        } else {
                                format_prefix = g_strdup_printf("%s:decoder", __ms_convert_mime_to_string(mime));
                                plugin_name = __ms_ini_get_string(dict,
@@ -284,7 +285,7 @@ int __ms_src_node_create(media_streamer_node_s *node)
                        node->gst_element = __ms_element_create(DEFAULT_UDP_SOURCE, NULL);
                        break;
                case MEDIA_STREAMER_NODE_SRC_TYPE_HTTP:
-                       ms_error("Error: not implemented yet");
+                       node->gst_element = __ms_element_create(DEFAULT_HTTP_SOURCE, NULL);
                        break;
                case MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA:
                        plugin_name = __ms_ini_get_string(dict,
@@ -512,7 +513,13 @@ int __ms_autoplug_prepare(media_streamer_s *ms_streamer)
                        gst_bin_add_many((GstBin *)ms_streamer->topology_bin, found_element, NULL);
 
                        gst_element_sync_state_with_parent(found_element);
-                       g_signal_connect(found_element, "pad-added", G_CALLBACK (__decodebin_newpad_streamer_cb), ms_streamer);
+
+                       if(__ms_bin_find_element_by_klass(ms_streamer->topology_bin,MEDIA_STREAMER_BIN_KLASS, "rtp_container")) {
+                               g_signal_connect(found_element, "pad-added", G_CALLBACK (__decodebin_newpad_streamer_cb), ms_streamer);
+                       } else {
+                               g_signal_connect(found_element, "pad-added", G_CALLBACK (__decodebin_newpad_cb), ms_streamer);
+                       }
+                       g_signal_connect(found_element, "autoplug-select", G_CALLBACK(__ms_decodebin_autoplug_select), NULL);
 
                        found_element = __ms_link_with_new_element(unlinked_element, found_element, NULL);
                        __ms_generate_dots(ms_streamer->pipeline, GST_ELEMENT_NAME(found_element));
@@ -792,4 +799,4 @@ int __ms_node_write_param_into_value(media_streamer_node_s *node, const char *pa
        *param_value = string_val;
 
        return MEDIA_STREAMER_ERROR_NONE;
-}
+}
\ No newline at end of file
index 201a92f65db4872ae00b6b08f2e7f1157f3a6fa9..bac167fe34ef93a08d2710c370049cdc0eec38a9 100755 (executable)
@@ -192,7 +192,27 @@ const gchar *__ms_convert_mime_to_string(media_format_mimetype_e mime)
                default:
                        ms_error("Invalid or Unsupported media format [%d].", mime);
                        return NULL;
-                       break;
+       }
+
+}
+
+const gchar *__ms_convert_mime_to_rtp_format(media_format_mimetype_e mime)
+{
+       switch (mime) {
+               case MEDIA_FORMAT_I420:
+               case MEDIA_FORMAT_YV12:
+                       return "RAW";
+               case MEDIA_FORMAT_H263:
+                       return "H263";
+               case MEDIA_FORMAT_H264_HP:
+               case MEDIA_FORMAT_H264_MP:
+               case MEDIA_FORMAT_H264_SP:
+                       return "H264";
+               case MEDIA_FORMAT_PCM:
+                       return "L16";
+               default:
+                       ms_error("Invalid or Unsupported media format [%d].", mime);
+                       return NULL;
        }
 
 }
index d14b5e4fb36c4de4b2bad62858067209a778c26f..48c16f60002bfa107d6f8f4ab059efb64b76f97a 100755 (executable)
@@ -28,15 +28,18 @@ typedef enum {
        MENU_STATE_MAIN_MENU,
        MENU_STATE_BROADCAST_MENU,
        MENU_STATE_VOIP_MENU,
+       MENU_STATE_PLAYING_MENU,
        MENU_STATE_PRESET_MENU
 } menu_state_e;
 
 typedef enum {
        SUBMENU_STATE_UNKNOWN,
        SUBMENU_STATE_GETTING_IP,
-       SUBMENU_STATE_GETTING_URI,
+       SUBMENU_STATE_GETTING_VIDEOFILE_URI,
+       SUBMENU_STATE_GETTING_SUBFILE_URI,
        SUBMENU_STATE_AUTOPLUG,
        SUBMENU_STATE_SCENARIO,
+       SUBMENU_STATE_PLAYING_SCENARIO,
        SUBMENU_STATE_FORMAT
 } submenu_state_e;
 
@@ -64,7 +67,9 @@ typedef enum
        SCENARIO_MODE_VIDEOTEST_SCREEN,
        SCENARIO_MODE_AUDIOTEST_PHONE,
        SCENARIO_MODE_TEST_VIDEO_AUDIO,
-       SCENARIO_MODE_FILESRC_VIDEO_AUDIO,
+       SCENARIO_MODE_FILE_VIDEO_AUDIO,
+       SCENARIO_MODE_FILE_SUBTITLE_VIDEO_AUDIO,
+       SCENARIO_MODE_HTTP_VIDEO_AUDIO,
        SCENARIO_MODE_APPSRC_APPSINK
 } scenario_mode_e;
 
@@ -90,6 +95,7 @@ GMainLoop *g_loop;
 
 gchar *g_broadcast_address = NULL;
 gchar *g_uri = NULL;
+gchar *g_sub_uri = NULL;
 menu_state_e g_menu_state = MENU_STATE_MAIN_MENU;
 submenu_state_e g_sub_menu_state = SUBMENU_STATE_UNKNOWN;
 preset_type_e g_menu_preset = PRESET_UNKNOWN;
@@ -99,7 +105,6 @@ gboolean g_autoplug_mode = FALSE;
 gboolean g_video_is_on = FALSE;
 gboolean g_audio_is_on = FALSE;
 
-
 media_format_h vfmt_raw = NULL;
 media_format_h vfmt_encoded = NULL;
 media_format_h afmt_raw = NULL;
@@ -115,28 +120,26 @@ static void streamer_error_cb(media_streamer_h streamer,
        g_print("Media Streamer posted error [%d] \n", error);
 }
 
-static gboolean _create(media_streamer_h *streamer)
+static void _create(media_streamer_h *streamer)
 {
        g_print("== create \n");
        int ret = MEDIA_STREAMER_ERROR_NONE;
 
        if (*streamer != NULL) {
-               return TRUE;
+               return;
        }
 
        ret = media_streamer_create(streamer);
 
        if (ret != MEDIA_STREAMER_ERROR_NONE) {
                g_print("Fail to create media streamer");
-               return FALSE;
+               return;
        }
 
        media_streamer_set_error_cb(*streamer, streamer_error_cb, NULL);
-
-       return TRUE;
 }
 
-static gboolean _prepare(void)
+static void _prepare(void)
 {
        g_print("== prepare \n");
        int ret = MEDIA_STREAMER_ERROR_NONE;
@@ -144,14 +147,12 @@ static gboolean _prepare(void)
        ret = media_streamer_prepare(current_media_streamer);
        if (ret != MEDIA_STREAMER_ERROR_NONE) {
                g_print("Fail to prepare media streamer");
-               return FALSE;
+               return;
        }
        g_print("== success prepare \n");
-
-       return TRUE;
 }
 
-static gboolean _unprepare(void)
+static void _unprepare(void)
 {
        g_print("== unprepare \n");
        int ret = MEDIA_STREAMER_ERROR_NONE;
@@ -159,14 +160,12 @@ static gboolean _unprepare(void)
        ret = media_streamer_unprepare(current_media_streamer);
        if (ret != MEDIA_STREAMER_ERROR_NONE) {
                g_print("Fail to unprepare media streamer");
-               return FALSE;
+               return;
        }
        g_print("== success unprepare \n");
-
-       return TRUE;
 }
 
-static gboolean _play()
+static void _play()
 {
        g_print("== play \n");
        int ret = MEDIA_STREAMER_ERROR_NONE;
@@ -174,14 +173,12 @@ static gboolean _play()
        ret = media_streamer_play(current_media_streamer);
        if (ret != MEDIA_STREAMER_ERROR_NONE) {
                g_print("Fail to play media streamer");
-               return FALSE;
+               return;
        }
        g_print("== success play \n");
-
-       return TRUE;
 }
 
-static gboolean _pause()
+static void _pause()
 {
        g_print("== pause \n");
        int ret = MEDIA_STREAMER_ERROR_NONE;
@@ -189,14 +186,12 @@ static gboolean _pause()
        ret = media_streamer_pause(current_media_streamer);
        if (ret != MEDIA_STREAMER_ERROR_NONE) {
                g_print("Fail to pause media streamer");
-               return FALSE;
+               return;
        }
        g_print("== success pause \n");
-
-       return TRUE;
 }
 
-static gboolean _stop()
+static void _stop()
 {
        g_print("== stop \n");
        int ret = MEDIA_STREAMER_ERROR_NONE;
@@ -204,11 +199,9 @@ static gboolean _stop()
        ret = media_streamer_stop(current_media_streamer);
        if (ret != MEDIA_STREAMER_ERROR_NONE) {
                g_print("Fail to stop media streamer");
-               return FALSE;
+               return;
        }
        g_print("== success stop \n");
-
-       return TRUE;
 }
 
 static gboolean _destroy(media_streamer_h streamer)
@@ -256,7 +249,7 @@ static void create_formats(void)
 
        /* Define encoded video format */
        media_format_create(&vfmt_encoded);
-       if (media_format_set_video_mime(vfmt_encoded, MEDIA_FORMAT_H263) != MEDIA_FORMAT_ERROR_NONE) {
+       if (media_format_set_video_mime(vfmt_encoded, MEDIA_FORMAT_H264_SP) != MEDIA_FORMAT_ERROR_NONE) {
                g_print("media_format_set_video_mime failed!");
        }
        media_format_set_video_width(vfmt_encoded, 800);
@@ -324,7 +317,36 @@ static void set_rtp_params(media_streamer_node_h rtp_node,
        params = NULL;
 }
 
-static gboolean _create_rtp_streamer(media_streamer_node_h rtp_bin)
+static void _create_file_playing()
+{
+       media_streamer_node_h file_src = NULL;
+       media_streamer_node_create_src( MEDIA_STREAMER_NODE_SRC_TYPE_FILE, &file_src);
+       media_streamer_node_set_param(file_src,MEDIA_STREAMER_PARAM_URI, g_uri);
+       media_streamer_node_add(current_media_streamer, file_src);
+}
+
+static void _create_file_sub_playing()
+{
+       media_streamer_node_h file_sub_src = NULL;
+       media_streamer_node_create_src( MEDIA_STREAMER_NODE_SRC_TYPE_FILE, &file_sub_src);
+       media_streamer_node_set_param(file_sub_src,MEDIA_STREAMER_PARAM_URI, g_uri);
+       media_streamer_node_add(current_media_streamer, file_sub_src);
+
+       media_streamer_node_h txt_src = NULL;
+       media_streamer_node_create_src( MEDIA_STREAMER_NODE_SRC_TYPE_FILE, &txt_src);
+       media_streamer_node_set_param(txt_src,MEDIA_STREAMER_PARAM_URI, g_sub_uri);
+       media_streamer_node_add(current_media_streamer, txt_src);
+}
+
+static void _create_http_playing()
+{
+       media_streamer_node_h http_src = NULL;
+       media_streamer_node_create_src( MEDIA_STREAMER_NODE_SRC_TYPE_HTTP, &http_src);
+       media_streamer_node_set_param(http_src,MEDIA_STREAMER_PARAM_URI, g_uri);
+       media_streamer_node_add(current_media_streamer, http_src);
+}
+
+static void _create_rtp_streamer(media_streamer_node_h rtp_bin)
 {
        g_print("== _create_rtp_streamer \n");
 
@@ -339,9 +361,6 @@ static gboolean _create_rtp_streamer(media_streamer_node_h rtp_bin)
                } else if (g_scenario_mode == SCENARIO_MODE_VIDEOTEST_SCREEN ||
                    g_scenario_mode == SCENARIO_MODE_TEST_VIDEO_AUDIO) {
                        media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_TEST, &video_src);
-               } else if (g_scenario_mode == SCENARIO_MODE_FILESRC_VIDEO_AUDIO) {
-                       media_streamer_node_create_src( MEDIA_STREAMER_NODE_SRC_TYPE_FILE, &video_src);
-                       media_streamer_node_set_param(video_src,MEDIA_STREAMER_PARAM_URI, g_uri);
                }
 
                media_streamer_node_add(current_media_streamer, video_src);
@@ -400,11 +419,9 @@ static gboolean _create_rtp_streamer(media_streamer_node_h rtp_bin)
 
                g_print("== success streamer audio part \n");
        }
-
-       return TRUE;
 }
 
-static gboolean _create_rtp_streamer_autoplug(media_streamer_node_h rtp_bin)
+static void _create_rtp_streamer_autoplug(media_streamer_node_h rtp_bin)
 {
        g_print("== _create_rtp_streamer_autoplug \n");
 
@@ -415,13 +432,10 @@ static gboolean _create_rtp_streamer_autoplug(media_streamer_node_h rtp_bin)
 
                if (g_scenario_mode == SCENARIO_MODE_CAMERA_SCREEN ||
             g_scenario_mode == SCENARIO_MODE_FULL_VIDEO_AUDIO) {
-                       media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA,     &video_src);
+                       media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA, &video_src);
                } else if (g_scenario_mode == SCENARIO_MODE_VIDEOTEST_SCREEN ||
                    g_scenario_mode == SCENARIO_MODE_TEST_VIDEO_AUDIO) {
                        media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_TEST, &video_src);
-               } else if (g_scenario_mode == SCENARIO_MODE_FILESRC_VIDEO_AUDIO) {
-                       media_streamer_node_create_src( MEDIA_STREAMER_NODE_SRC_TYPE_FILE, &video_src);
-                       media_streamer_node_set_param(video_src,MEDIA_STREAMER_PARAM_URI, g_uri);
                }
 
                media_streamer_node_add(current_media_streamer, video_src);
@@ -437,7 +451,6 @@ static gboolean _create_rtp_streamer_autoplug(media_streamer_node_h rtp_bin)
                if (g_scenario_mode == SCENARIO_MODE_MICROPHONE_PHONE ||
             g_scenario_mode == SCENARIO_MODE_FULL_VIDEO_AUDIO) {
                        media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_CAPTURE, &audio_src);
-                       media_streamer_node_add(current_media_streamer, audio_src);
                } else if (g_scenario_mode == SCENARIO_MODE_AUDIOTEST_PHONE ||
                    g_scenario_mode == SCENARIO_MODE_TEST_VIDEO_AUDIO) {
                        media_streamer_node_create_src(MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_TEST, &audio_src);
@@ -447,11 +460,9 @@ static gboolean _create_rtp_streamer_autoplug(media_streamer_node_h rtp_bin)
 
                g_print("== success streamer_autoplug audio part \n");
        }
-
-       return TRUE;
 }
 
-static gboolean _create_rtp_client(media_streamer_node_h rtp_bin)
+static void _create_rtp_client(media_streamer_node_h rtp_bin)
 {
        g_print("== _create_rtp_client \n");
 
@@ -510,11 +521,9 @@ static gboolean _create_rtp_client(media_streamer_node_h rtp_bin)
 
                g_print("== success client audio part \n");
        }
-
-       return TRUE;
 }
 
-static gboolean _create_rtp_client_autoplug(media_streamer_node_h rtp_bin)
+static void _create_rtp_client_autoplug(media_streamer_node_h rtp_bin)
 {
        g_print("== _create_rtp_client_autoplug \n");
 
@@ -537,8 +546,6 @@ static gboolean _create_rtp_client_autoplug(media_streamer_node_h rtp_bin)
 
                g_print("== success client_autoplug audio part \n");
        }
-
-       return TRUE;
 }
 
 static media_streamer_node_h _create_rtp(int video_port,
@@ -571,10 +578,12 @@ static void buffer_status_cb(media_streamer_node_h node,
                guint64 size = strlen(test);
 
                media_packet_h packet;
-               media_packet_create_from_external_memory(vfmt_encoded,
-                               (void *)test, size, NULL, NULL, &packet);
+               media_packet_create_from_external_memory(vfmt_encoded, (void *)test, size, NULL, NULL, &packet);
                media_streamer_node_push_packet(node, packet);
                count++;
+
+               media_packet_destroy(packet);
+               g_free(test);
        } else {
                media_streamer_node_push_packet(node, NULL);
                g_print("Buffer status cb got overflow\n");
@@ -599,7 +608,7 @@ static void eos_cb(media_streamer_node_h node, void *user_data)
        g_print("Got EOS cb from appsink\n");
 }
 
-static gboolean _create_app_test()
+static void _create_app_test()
 {
        g_print("== _create_appsrc \n");
 
@@ -623,8 +632,6 @@ static gboolean _create_app_test()
        media_streamer_sink_set_eos_cb(app_sink, eos_cb, NULL);
 
        g_print("== success appsrc part \n");
-
-       return TRUE;
 }
 //#endif
 
@@ -661,6 +668,11 @@ void reset_current_menu_state(void)
                g_free(g_uri);
                g_uri = NULL;
        }
+
+       if (g_sub_uri != NULL) {
+               g_free(g_sub_uri);
+               g_sub_uri = NULL;
+       }
 }
 
 void quit()
@@ -679,7 +691,13 @@ static void display_getting_ip_menu(void)
 static void display_getting_uri_menu(void)
 {
        g_print("\n");
-       g_print("Please input URI for playing\n");
+       g_print("Please input video URI for playing\n");
+}
+
+static void display_getting_sub_uri_menu(void)
+{
+       g_print("\n");
+       g_print("Please input Subtitle path for playing\n");
 }
 
 static void display_autoplug_select_menu(void)
@@ -696,16 +714,32 @@ static void display_scenario_select_menu(void)
 {
        g_print("\n");
        g_print("Please select Scenario mode\n");
-       g_print("By default will be used [%d] mode\n",
-                       g_scenario_mode);
+       g_print("By default will be used [%d] mode\n", g_scenario_mode);
        g_print("1. Camera -> Screen \n");
        g_print("2. Microphone -> Phones\n");
        g_print("3. Camera + Microphone -> Screen + Phones\n");
        g_print("4. Video test -> Screen\n");
        g_print("5. Audio test -> Phones\n");
        g_print("6. Video test + Audio test -> Screen + Phones\n");
-       g_print("7. Filesrc -> Screen + Phones\n");
-       g_print("8. Appsrc -> Appsink\n");
+
+}
+
+static void display_playing_scenario_select_menu(void)
+{
+       g_print("\n");
+       g_print("====================================================\n");
+       g_print("   media streamer test: Playing menu v0.3\n");
+       g_print("----------------------------------------------------\n");
+       g_print("\n");
+       g_print("Please select Playing Scenario mode\n");
+       g_print("By default will be used [%d] mode\n",  g_scenario_mode);
+       g_print("1. VideoFile playing \n");
+       g_print("2. VideoFile + SubtitleFile playing \n");
+       g_print("3. HTTP Source playing \n");
+       g_print("4. Appsrc -> Appsink \n");
+       g_print("b. back \n");
+       g_print("----------------------------------------------------\n");
+       g_print("====================================================\n");
 }
 
 static void display_preset_menu(void)
@@ -765,6 +799,7 @@ static void display_main_menu(void)
        g_print("----------------------------------------------------\n");
        g_print("1. Broadcast \n");
        g_print("2. VOIP \n");
+       g_print("3. Local Playing \n");
        g_print("q. quit \n");
        g_print("----------------------------------------------------\n");
        g_print("====================================================\n");
@@ -783,6 +818,9 @@ static void display_menu(void)
                        case MENU_STATE_VOIP_MENU:
                                display_voip_menu();
                                break;
+                       case MENU_STATE_PLAYING_MENU:
+                               display_preset_menu();
+                               break;
                        case MENU_STATE_PRESET_MENU:
                                display_preset_menu();
                                break;
@@ -795,15 +833,21 @@ static void display_menu(void)
                        case SUBMENU_STATE_GETTING_IP:
                                display_getting_ip_menu();
                                break;
-                       case SUBMENU_STATE_GETTING_URI:
+                       case SUBMENU_STATE_GETTING_VIDEOFILE_URI:
                                display_getting_uri_menu();
                                break;
+                       case SUBMENU_STATE_GETTING_SUBFILE_URI:
+                               display_getting_sub_uri_menu();
+                               break;
                        case SUBMENU_STATE_AUTOPLUG:
                                display_autoplug_select_menu();
                                break;
                        case SUBMENU_STATE_SCENARIO:
                                display_scenario_select_menu();
                                break;
+                       case SUBMENU_STATE_PLAYING_SCENARIO:
+                               display_playing_scenario_select_menu();
+                               break;
                        case SUBMENU_STATE_FORMAT:
                                /* display_format_menu(); */
                                break;
@@ -822,22 +866,18 @@ static void run_preset(void)
        switch (g_menu_preset) {
                case PRESET_RTP_STREAMER:
                        rtp_bin = _create_rtp(VIDEO_PORT, AUDIO_PORT, FALSE);
-                       if (g_autoplug_mode && (g_scenario_mode != SCENARIO_MODE_APPSRC_APPSINK)) {
+                       if (g_autoplug_mode) {
                                _create_rtp_streamer_autoplug(rtp_bin);
-                       } else if ((g_scenario_mode != SCENARIO_MODE_APPSRC_APPSINK)) {
-                               _create_rtp_streamer(rtp_bin);
                        } else {
-                               _create_app_test();
+                               _create_rtp_streamer(rtp_bin);
                        }
                        break;
                case PRESET_RTP_CLIENT:
                        rtp_bin = _create_rtp(VIDEO_PORT, AUDIO_PORT, TRUE);
-                       if (g_autoplug_mode && (g_scenario_mode != SCENARIO_MODE_APPSRC_APPSINK)) {
+                       if (g_autoplug_mode) {
                                _create_rtp_client_autoplug(rtp_bin);
-                       } else if ((g_scenario_mode != SCENARIO_MODE_APPSRC_APPSINK)) {
-                               _create_rtp_client(rtp_bin);
                        } else {
-                               _create_app_test();
+                               _create_rtp_client(rtp_bin);
                        }
                        break;
                case PRESET_VOIP:
@@ -872,6 +912,23 @@ static void run_preset(void)
        }
 }
 
+void run_playing_preset(void)
+{
+       create_formats();
+
+       if (g_scenario_mode == SCENARIO_MODE_FILE_VIDEO_AUDIO) {
+               _create_file_playing();
+       } else if (g_scenario_mode == SCENARIO_MODE_FILE_SUBTITLE_VIDEO_AUDIO) {
+               _create_file_sub_playing();
+       } else if (g_scenario_mode == SCENARIO_MODE_HTTP_VIDEO_AUDIO) {
+               _create_http_playing();
+       } else if ((g_scenario_mode == SCENARIO_MODE_APPSRC_APPSINK)) {
+               _create_app_test();
+       } else {
+               g_print("Invalid playing menu preset was selected!");
+       }
+}
+
 void _interpret_main_menu(char *cmd)
 {
        int len = strlen(cmd);
@@ -881,6 +938,8 @@ void _interpret_main_menu(char *cmd)
                        g_menu_state = MENU_STATE_BROADCAST_MENU;
                } else if (!strncmp(cmd, "2", len)) {
                        g_menu_state = MENU_STATE_VOIP_MENU;
+               } else if (!strncmp(cmd, "3", len)) {
+                       g_menu_state = MENU_STATE_PLAYING_MENU;
                } else if (!strncmp(cmd, "q", len)) {
                        quit();
                }
@@ -946,12 +1005,36 @@ void _interpret_voip_menu(char *cmd)
        }
 }
 
+void _interpret_playing_scenario_menu(char *cmd)
+{
+       int len = strlen(cmd);
+
+       if (len == 1) {
+               if (!strncmp(cmd, "1", len)) {
+                       g_scenario_mode = SCENARIO_MODE_FILE_VIDEO_AUDIO;
+                       g_sub_menu_state = SUBMENU_STATE_GETTING_VIDEOFILE_URI;
+                       return;
+               } else if (!strncmp(cmd, "2", len)) {
+                       g_scenario_mode = SCENARIO_MODE_FILE_SUBTITLE_VIDEO_AUDIO;
+                       g_sub_menu_state = SUBMENU_STATE_GETTING_VIDEOFILE_URI;
+                       return;
+               } else if (!strncmp(cmd, "3", len)) {
+                       g_scenario_mode = SCENARIO_MODE_HTTP_VIDEO_AUDIO;
+                       g_sub_menu_state = SUBMENU_STATE_GETTING_VIDEOFILE_URI;
+                       return;
+               } else if (!strncmp(cmd, "4", len)) {
+                       g_scenario_mode = SCENARIO_MODE_APPSRC_APPSINK;
+               }
+       }
+       g_sub_menu_state = SUBMENU_STATE_UNKNOWN;
+}
+
+
 void _interpret_scenario_menu(char *cmd)
 {
        int len = strlen(cmd);
 
-       if (len == 1 || len == 2)
-       {
+       if (len == 1) {
                if (!strncmp(cmd, "1", len)) {
                        g_scenario_mode = SCENARIO_MODE_CAMERA_SCREEN;
                        g_video_is_on = TRUE;
@@ -976,18 +1059,6 @@ void _interpret_scenario_menu(char *cmd)
                        g_scenario_mode = SCENARIO_MODE_TEST_VIDEO_AUDIO;
                        g_video_is_on = TRUE;
                        g_audio_is_on = TRUE;
-               } else if (!strncmp(cmd, "7", len)) {
-                       g_scenario_mode = SCENARIO_MODE_FILESRC_VIDEO_AUDIO;
-                       g_video_is_on = TRUE;
-                       g_audio_is_on = TRUE;
-                       if (g_menu_preset & PRESET_RTP_STREAMER) {
-                               g_sub_menu_state = SUBMENU_STATE_GETTING_URI;
-                               return;
-                       }
-               } else if (!strncmp(cmd, "8", len)) {
-                       g_scenario_mode = SCENARIO_MODE_APPSRC_APPSINK;
-                       g_video_is_on = FALSE;
-                       g_audio_is_on = FALSE;
                }
        }
 
@@ -1014,6 +1085,28 @@ void _interpret_getting_ip_menu(char *cmd)
        g_sub_menu_state = SUBMENU_STATE_SCENARIO;
 }
 
+void _interpret_getting_sub_uri_menu(char *cmd)
+{
+       if (cmd) {
+               if (g_sub_uri != NULL) {
+                       g_free(g_sub_uri);
+               }
+               g_sub_uri = g_strdup(cmd);
+               g_print("== URI set to [%s]\n", g_sub_uri);
+       } else {
+               g_print("Empty URI!\n");
+               return;
+       }
+
+       if (g_menu_state == MENU_STATE_PLAYING_MENU) {
+               run_playing_preset();
+               g_sub_menu_state = SUBMENU_STATE_UNKNOWN;
+       } else {
+               g_sub_menu_state = SUBMENU_STATE_UNKNOWN;
+               run_preset();
+       }
+}
+
 void _interpret_getting_uri_menu(char *cmd)
 {
        if (cmd) {
@@ -1027,8 +1120,17 @@ void _interpret_getting_uri_menu(char *cmd)
                return;
        }
 
-       g_sub_menu_state = SUBMENU_STATE_UNKNOWN;
-       run_preset();
+       if (g_menu_state == MENU_STATE_PLAYING_MENU) {
+               if (g_scenario_mode == SCENARIO_MODE_FILE_SUBTITLE_VIDEO_AUDIO) {
+                       g_sub_menu_state = SUBMENU_STATE_GETTING_SUBFILE_URI;
+               } else {
+                       run_playing_preset();
+                       g_sub_menu_state = SUBMENU_STATE_UNKNOWN;
+               }
+       } else {
+               g_sub_menu_state = SUBMENU_STATE_UNKNOWN;
+               run_preset();
+       }
 }
 
 void _interpret_autoplug_menu(char *cmd)
@@ -1069,17 +1171,21 @@ void _interpret_preset_menu(char *cmd)
 
                } else if (!strncmp(cmd, "2", len)) {
                        /* call the run_preset function after autoplug mode was selected; */
-                       g_sub_menu_state = SUBMENU_STATE_AUTOPLUG;
+                       if (g_menu_state == MENU_STATE_PLAYING_MENU) {
+                               g_sub_menu_state = SUBMENU_STATE_PLAYING_SCENARIO;
+                       } else {
+                               g_sub_menu_state = SUBMENU_STATE_AUTOPLUG;
+                       }
                } else if (!strncmp(cmd, "4", len)) {
                        _prepare();
                } else if (!strncmp(cmd, "5", len)) {
                        _unprepare();
                } else if (!strncmp(cmd, "6", len)) {
-                       _play(g_media_streamer);
+                       _play();
                } else if (!strncmp(cmd, "7", len)) {
-                       _pause(g_media_streamer);
+                       _pause();
                } else if (!strncmp(cmd, "8", len)) {
-                       _stop(g_media_streamer);
+                       _stop();
                } else if (!strncmp(cmd, "9", len)) {
                        _destroy(current_media_streamer);
                } else if (!strncmp(cmd, "b", len)) {
@@ -1090,6 +1196,7 @@ void _interpret_preset_menu(char *cmd)
                        } else {
                                reset_current_menu_state();
                        }
+                       g_sub_menu_state = SUBMENU_STATE_UNKNOWN;
                        display_menu();
                }
 
@@ -1111,6 +1218,9 @@ static void interpret_cmd(char *cmd)
                        case MENU_STATE_VOIP_MENU:
                                _interpret_voip_menu(cmd);
                                break;
+                       case MENU_STATE_PLAYING_MENU:
+                               _interpret_preset_menu(cmd);
+                               break;
                        case MENU_STATE_PRESET_MENU:
                                _interpret_preset_menu(cmd);
                                break;
@@ -1124,9 +1234,12 @@ static void interpret_cmd(char *cmd)
                        case SUBMENU_STATE_GETTING_IP:
                                _interpret_getting_ip_menu(cmd);
                                break;
-                       case SUBMENU_STATE_GETTING_URI:
+                       case SUBMENU_STATE_GETTING_VIDEOFILE_URI:
                                _interpret_getting_uri_menu(cmd);
                                break;
+                       case SUBMENU_STATE_GETTING_SUBFILE_URI:
+                               _interpret_getting_sub_uri_menu(cmd);
+                               break;
                        case SUBMENU_STATE_AUTOPLUG:
                                _interpret_autoplug_menu(cmd);
                                break;
@@ -1136,6 +1249,9 @@ static void interpret_cmd(char *cmd)
                        case SUBMENU_STATE_SCENARIO:
                                _interpret_scenario_menu(cmd);
                                break;
+                       case SUBMENU_STATE_PLAYING_SCENARIO:
+                               _interpret_playing_scenario_menu(cmd);
+                               break;
                        default:
                                g_print("*** Unknown Submenu state.\n");
                                break;