[0.6.126] refactoring about _create_pipeline 43/187543/4
authorEunhae Choi <eunhae1.choi@samsung.com>
Fri, 24 Aug 2018 00:56:52 +0000 (09:56 +0900)
committerEunhae Choi <eunhae1.choi@samsung.com>
Fri, 24 Aug 2018 04:19:56 +0000 (13:19 +0900)
- refactoring the __mmplayer_gst_create_pipeline()
  to improve the cyclomatic complexity issue

Change-Id: I2b43fef33d2136ba35fc6b49921a1d33a970cbec

packaging/libmm-player.spec
src/include/mm_player_gst.h
src/include/mm_player_priv.h
src/include/mm_player_tracks.h
src/mm_player_gst.c
src/mm_player_priv.c
src/mm_player_tracks.c

index 446a356..75cb815 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-player
 Summary:    Multimedia Framework Player Library
-Version:    0.6.125
+Version:    0.6.126
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index ca3d48a..a95876b 100644 (file)
@@ -45,8 +45,6 @@ gint __mmplayer_gst_handle_stream_error(mm_player_t* player, GError* error, GstM
 
 gboolean __mmplayer_handle_gst_error(mm_player_t* player, GstMessage * message, GError* error);
 int __mmplayer_gst_set_state(mm_player_t* player, GstElement * element,  GstState state, gboolean async, gint timeout);
-void __mmplayer_gst_bus_msg_callback(GstMessage *msg, gpointer data);
-GstBusSyncReply __mmplayer_gst_bus_sync_callback(GstBus * bus, GstMessage * message, gpointer data);
 
 int __mmplayer_gst_start(mm_player_t* player);
 int __mmplayer_gst_stop(mm_player_t* player);
@@ -59,6 +57,11 @@ gboolean __mmplayer_gst_seek(mm_player_t* player, GstElement * element, gdouble
 int __mmplayer_gst_set_position(mm_player_t* player, int format, gint64 position, gboolean internal_called);
 int __mmplayer_gst_get_position(mm_player_t* player, int format, gint64* position);
 int __mmplayer_gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos);
+int __mmplayer_gst_build_es_pipeline(mm_player_t* player);
+int __mmplayer_gst_build_pd_pipeline(mm_player_t* player);
+int __mmplayer_gst_build_pipeline(mm_player_t* player);
+int __mmplayer_gst_add_bus_watch(mm_player_t* player);
+GstElement* __mmplayer_gst_build_source(mm_player_t* player);
 
 #ifdef __cplusplus
 }
index df9b082..6f48c8b 100644 (file)
@@ -955,6 +955,16 @@ void __mmplayer_audio_stream_clear_buffer(mm_player_t* player, gboolean send_all
 gboolean __mmplayer_configure_audio_callback(mm_player_t* player);
 MMStreamingType __mmplayer_get_stream_service_type(mm_player_t* player);
 int __mmplayer_get_video_angle(mm_player_t* player, int *user_angle, int *org_angle);
+gboolean __mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink);
+void __mmplayer_add_signal_connection(mm_player_t* player, GObject* object, MMPlayerSignalType type, const gchar* signal, GCallback cb_funct, gpointer u_data);
+void __mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data);
+gint __mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPad* pad, GstCaps* caps, GstElementFactory* factory, gpointer data);
+gboolean __mmplayer_try_to_plug_decodebin(mm_player_t* player, GstPad *srcpad, const GstCaps *caps);
+void __mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data);
+GstElement* __mmplayer_create_decodebin(mm_player_t* player);
+int __mmplayer_gst_element_add_bucket_to_bin(GstBin* bin, GList* element_bucket);
+int __mmplayer_gst_element_link_bucket(GList* element_bucket);
+void __mmplayer_typefind_have_type(GstElement *tf, guint probability, GstCaps *caps, gpointer data);
 
 #ifdef __cplusplus
        }
index c9f1bdc..1de0c09 100644 (file)
 #ifdef _MULTI_TRACK
 typedef bool (*_mmplayer_track_selected_subtitle_language_cb)(int track_num, void *user_data);
 #endif
-void _mmplayer_track_initialize(mm_player_t *player);
+void __mmplayer_track_initialize(mm_player_t *player);
 
-void _mmplayer_track_destroy(mm_player_t *player);
+void __mmplayer_track_destroy(mm_player_t *player);
 
-void _mmplayer_track_update_info(mm_player_t *player, MMPlayerTrackType type, GstPad *sinkpad);
+void __mmplayer_track_update_info(mm_player_t *player, MMPlayerTrackType type, GstPad *sinkpad);
 
 int _mmplayer_get_track_count(MMHandleType hplayer,  MMPlayerTrackType type, int *count);
 
index c509f1b..afe38d4 100644 (file)
@@ -28,6 +28,7 @@
 #include <dlog.h>
 #include <mm_error.h>
 #include <mm_attrs_private.h>
+#include <gst/app/gstappsrc.h>
 
 #include "mm_player_gst.h"
 #include "mm_player_priv.h"
@@ -1995,69 +1996,7 @@ __mmplayer_gst_handle_async_done_message(mm_player_t* player, GstMessage *msg)
        return;
 }
 
-
-#if 0
-#endif
-
-int
-__mmplayer_gst_set_state(mm_player_t* player, GstElement * element,  GstState state, gboolean async, gint timeout)
-{
-       GstState element_state = GST_STATE_VOID_PENDING;
-       GstState element_pending_state = GST_STATE_VOID_PENDING;
-       GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(element, MM_ERROR_INVALID_ARGUMENT);
-
-       LOGD("setting [%s] element state to : %s\n", GST_ELEMENT_NAME(element), gst_element_state_get_name(state));
-
-       /* set state */
-       ret = gst_element_set_state(element, state);
-
-       if (ret == GST_STATE_CHANGE_FAILURE) {
-               LOGE("failed to set [%s] state\n", GST_ELEMENT_NAME(element));
-
-               /* dump state of all element */
-               __mmplayer_dump_pipeline_state(player);
-
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       /* return here so state transition to be done in async mode */
-       if (async) {
-               LOGD("async state transition. not waiting for state complete.\n");
-               return MM_ERROR_NONE;
-       }
-
-       /* wait for state transition */
-       ret = gst_element_get_state(element, &element_state, &element_pending_state, timeout * GST_SECOND);
-
-       if (ret == GST_STATE_CHANGE_FAILURE || (state != element_state)) {
-               LOGE("failed to change [%s] element state to [%s] within %d sec\n",
-                       GST_ELEMENT_NAME(element),
-                       gst_element_state_get_name(state), timeout);
-
-               LOGE(" [%s] state : %s   pending : %s \n",
-                       GST_ELEMENT_NAME(element),
-                       gst_element_state_get_name(element_state),
-                       gst_element_state_get_name(element_pending_state));
-
-               /* dump state of all element */
-               __mmplayer_dump_pipeline_state(player);
-
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       LOGD("[%s] element state has changed\n", GST_ELEMENT_NAME(element));
-
-       MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
-}
-
-void
+static void
 __mmplayer_gst_bus_msg_callback(GstMessage *msg, gpointer data)
 {
        mm_player_t* player = (mm_player_t*)(data);
@@ -2183,72 +2122,890 @@ __mmplayer_gst_bus_msg_callback(GstMessage *msg, gpointer data)
                break;
        }
 
-       /* should not call 'gst_message_unref(msg)' */
-       return;
-}
+       /* should not call 'gst_message_unref(msg)' */
+       return;
+}
+
+static GstBusSyncReply
+__mmplayer_gst_bus_sync_callback(GstBus * bus, GstMessage * message, gpointer data)
+{
+       mm_player_t *player = (mm_player_t *)data;
+       GstBusSyncReply reply = GST_BUS_DROP;
+
+       if (!(player->pipeline && player->pipeline->mainbin)) {
+               LOGE("player pipeline handle is null");
+               return GST_BUS_PASS;
+       }
+
+       if (!__mmplayer_gst_check_useful_message(player, message)) {
+               gst_message_unref(message);
+               return GST_BUS_DROP;
+       }
+
+       switch (GST_MESSAGE_TYPE(message)) {
+       case GST_MESSAGE_STATE_CHANGED:
+               /* post directly for fast launch */
+               if (player->sync_handler) {
+                       __mmplayer_gst_bus_msg_callback(message, player);
+                       reply = GST_BUS_DROP;
+               } else
+                       reply = GST_BUS_PASS;
+               break;
+       case GST_MESSAGE_TAG:
+               __mmplayer_gst_extract_tag_from_msg(player, message);
+
+               #if 0 // debug
+               {
+                       GstTagList *tags = NULL;
+
+                       gst_message_parse_tag(message, &tags);
+                       if (tags) {
+                               LOGE("TAGS received from element \"%s\".\n",
+                               GST_STR_NULL(GST_ELEMENT_NAME(GST_MESSAGE_SRC(message))));
+
+                               gst_tag_list_foreach(tags, print_tag, NULL);
+                               gst_tag_list_free(tags);
+                               tags = NULL;
+                       }
+                       break;
+               }
+               #endif
+               break;
+
+       case GST_MESSAGE_DURATION_CHANGED:
+               __mmplayer_gst_handle_duration(player, message);
+               break;
+       case GST_MESSAGE_ASYNC_DONE:
+               /* NOTE:Don't call gst_callback directly
+                * because previous frame can be showed even though this message is received for seek.
+                */
+       default:
+               reply = GST_BUS_PASS;
+               break;
+       }
+
+       if (reply == GST_BUS_DROP)
+               gst_message_unref(message);
+
+       return reply;
+}
+
+static void
+__mmplayer_gst_appsrc_feed_data_mem(GstElement *element, guint size, gpointer user_data)
+{
+       GstElement *appsrc = element;
+       MMPlayerInputBuffer *buf = (MMPlayerInputBuffer *)user_data;
+       GstBuffer *buffer = NULL;
+       GstFlowReturn ret = GST_FLOW_OK;
+       gint len = size;
+
+       MMPLAYER_RETURN_IF_FAIL(element);
+       MMPLAYER_RETURN_IF_FAIL(buf);
+
+       buffer = gst_buffer_new();
+
+       if (buf->offset < 0 || buf->len < 0) {
+               LOGE("invalid buf info %d %d", buf->offset, buf->len);
+               return;
+       }
+
+       if (buf->offset >= buf->len) {
+               LOGD("call eos appsrc");
+               g_signal_emit_by_name(appsrc, "end-of-stream", &ret);
+               return;
+       }
+
+       if (buf->len - buf->offset < size)
+               len = buf->len - buf->offset;
+
+       gst_buffer_insert_memory(buffer, -1, gst_memory_new_wrapped(0, (guint8 *)(buf->buf + buf->offset), len, 0, len, NULL, NULL));
+       GST_BUFFER_OFFSET(buffer) = (guint64)buf->offset;
+       GST_BUFFER_OFFSET_END(buffer) = (guint64)(buf->offset + len);
+
+       //LOGD("feed buffer %p, offset %u-%u length %u", buffer, buf->offset, (buf->offset+len), len);
+       g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret);
+
+       buf->offset += len;
+}
+
+static gboolean
+__mmplayer_gst_appsrc_seek_data_mem(GstElement *element, guint64 size, gpointer user_data)
+{
+       MMPlayerInputBuffer *buf = (MMPlayerInputBuffer *)user_data;
+
+       MMPLAYER_RETURN_VAL_IF_FAIL(buf, FALSE);
+
+       buf->offset  = (int)size;
+
+       return TRUE;
+}
+
+void
+__mmplayer_gst_appsrc_feed_data(GstElement *element, guint size, gpointer user_data)
+{
+       mm_player_t *player  = (mm_player_t*)user_data;
+       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_DEFAULT;
+       guint64 current_level_bytes = 0;
+
+       MMPLAYER_RETURN_IF_FAIL(player);
+
+       if (g_strrstr(GST_ELEMENT_NAME(element), "audio"))
+               type = MM_PLAYER_STREAM_TYPE_AUDIO;
+       else if (g_strrstr(GST_ELEMENT_NAME(element), "video"))
+               type = MM_PLAYER_STREAM_TYPE_VIDEO;
+       else if (g_strrstr(GST_ELEMENT_NAME(element), "subtitle"))
+               type = MM_PLAYER_STREAM_TYPE_TEXT;
+       else {
+               LOGE("can not enter here");
+               return;
+       }
+
+       g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
+
+       LOGI("type: %d, level: %llu", type, current_level_bytes);
+
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
+       if (player->media_stream_buffer_status_cb[type])
+               player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param[type]);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
+}
+
+void
+__mmplayer_gst_appsrc_enough_data(GstElement *element, gpointer user_data)
+{
+       mm_player_t *player  = (mm_player_t*)user_data;
+       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_DEFAULT;
+       guint64 current_level_bytes = 0;
+
+       MMPLAYER_RETURN_IF_FAIL(player);
+
+       if (g_strrstr(GST_ELEMENT_NAME(element), "audio"))
+               type = MM_PLAYER_STREAM_TYPE_AUDIO;
+       else if (g_strrstr(GST_ELEMENT_NAME(element), "video"))
+               type = MM_PLAYER_STREAM_TYPE_VIDEO;
+       else if (g_strrstr(GST_ELEMENT_NAME(element), "subtitle"))
+               type = MM_PLAYER_STREAM_TYPE_TEXT;
+       else {
+               LOGE("can not enter here");
+               return;
+       }
+
+       LOGI("type: %d, buffer is full", type);
+
+       g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
+
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
+
+       if (player->media_stream_buffer_status_cb[type])
+               player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW, current_level_bytes, player->buffer_cb_user_param[type]);
+
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
+}
+
+gboolean
+__mmplayer_gst_appsrc_seek_data(GstElement * element, guint64 position, gpointer user_data)
+{
+       mm_player_t *player  = (mm_player_t*)user_data;
+       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_DEFAULT;
+
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+
+       if (g_strrstr(GST_ELEMENT_NAME(element), "audio"))
+               type = MM_PLAYER_STREAM_TYPE_AUDIO;
+       else if (g_strrstr(GST_ELEMENT_NAME(element), "video"))
+               type = MM_PLAYER_STREAM_TYPE_VIDEO;
+       else if (g_strrstr(GST_ELEMENT_NAME(element), "subtitle"))
+               type = MM_PLAYER_STREAM_TYPE_TEXT;
+       else {
+               LOGE("can not enter here");
+               return TRUE;
+       }
+
+       LOGD("type: %d, pos: %llu", type, position);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
+
+       if (player->media_stream_seek_data_cb[type])
+               player->media_stream_seek_data_cb[type](type, position, player->seek_cb_user_param[type]);
+       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
+
+       return TRUE;
+}
+
+static gboolean
+__mmplayer_gst_create_es_decoder(mm_player_t *player, MMPlayerStreamType type, GstPad* srcpad)
+{
+#define MAX_LEN_NAME 20
+
+       gboolean ret = FALSE;
+       GstPad *sinkpad = NULL;
+       gchar *prefix = NULL;
+       gchar dec_name[MAX_LEN_NAME] = {0};
+       enum MainElementID elem_id = MMPLAYER_M_NUM;
+
+       MMPlayerGstElement *mainbin = NULL;
+       GstElement *decodebin = NULL;
+       GstCaps *dec_caps = NULL;
+
+       MMPLAYER_FENTER();
+
+       MMPLAYER_RETURN_VAL_IF_FAIL(player &&
+                                               player->pipeline &&
+                                               player->pipeline->mainbin, FALSE);
+       MMPLAYER_RETURN_VAL_IF_FAIL(srcpad, FALSE);
+
+       mainbin = player->pipeline->mainbin;
+       switch (type) {
+       case MM_PLAYER_STREAM_TYPE_AUDIO:
+               prefix = "audio";
+               elem_id = MMPLAYER_M_AUTOPLUG_A_DEC;
+       break;
+       case MM_PLAYER_STREAM_TYPE_VIDEO:
+               prefix = "video";
+               elem_id = MMPLAYER_M_AUTOPLUG_V_DEC;
+       break;
+       default:
+               LOGE("invalid type %d", type);
+               return FALSE;
+       }
+
+       if (mainbin[elem_id].gst) {
+               LOGE("elem(%d) is already created", elem_id);
+               return FALSE;
+       }
+
+       snprintf(dec_name, sizeof(dec_name), "%s_decodebin", prefix);
+
+       /* create decodebin */
+       decodebin = gst_element_factory_make("decodebin", dec_name);
+       if (!decodebin) {
+               LOGE("failed to create %s", dec_name);
+               return FALSE;
+       }
+
+       mainbin[elem_id].id = elem_id;
+       mainbin[elem_id].gst = decodebin;
+
+       /* raw pad handling signal */
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
+                                                                               G_CALLBACK(__mmplayer_gst_decode_pad_added), (gpointer)player);
+
+       /* This signal is emitted whenever decodebin finds a new stream. It is emitted
+       before looking for any elements that can handle that stream.*/
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select",
+                                                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_select), (gpointer)player);
+
+       /* This signal is emitted when a element is added to the bin.*/
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added",
+                                                                               G_CALLBACK(__mmplayer_gst_element_added), (gpointer)player);
+
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), decodebin)) {
+               LOGE("failed to add new decodebin");
+               return FALSE;
+       }
+
+       dec_caps = gst_pad_query_caps(srcpad, NULL);
+       if (dec_caps) {
+               //LOGD("got pad %s:%s , dec_caps %" GST_PTR_FORMAT, GST_DEBUG_PAD_NAME(srcpad), dec_caps);
+               g_object_set(G_OBJECT(decodebin), "sink-caps", dec_caps, NULL);
+               gst_caps_unref(dec_caps);
+       }
+
+       sinkpad = gst_element_get_static_pad(decodebin, "sink");
+
+       if (!sinkpad || gst_pad_link(srcpad, sinkpad) != GST_PAD_LINK_OK) {
+               LOGE("failed to link [%s:%s] to decoder", GST_DEBUG_PAD_NAME(srcpad));
+               goto ERROR;
+       }
+       gst_object_unref(GST_OBJECT(sinkpad));
+
+       gst_element_sync_state_with_parent(decodebin);
+       MMPLAYER_FLEAVE();
+       return TRUE;
+
+ERROR:
+       if (sinkpad)
+               gst_object_unref(GST_OBJECT(sinkpad));
+
+       if (mainbin[elem_id].gst) {
+               gst_element_set_state(mainbin[elem_id].gst, GST_STATE_NULL);
+               gst_bin_remove(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), mainbin[elem_id].gst);
+               gst_object_unref(mainbin[elem_id].gst);
+               mainbin[elem_id].gst = NULL;
+       }
+
+       MMPLAYER_FLEAVE();
+       return ret;
+}
+
+static gboolean
+__mmplayer_gst_create_es_path(mm_player_t* player, MMPlayerStreamType type, GstCaps* caps)
+{
+#define MAX_LEN_NAME 20
+       MMPlayerGstElement *mainbin = NULL;
+       gchar *prefix = NULL;
+       enum MainElementID src_id = MMPLAYER_M_NUM, queue_id = MMPLAYER_M_NUM;
+
+       gchar src_name[MAX_LEN_NAME] = {0}, queue_name[MAX_LEN_NAME] = {0};
+       GstElement *src = NULL, *queue = NULL;
+       GstPad *srcpad = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->mainbin, FALSE);
+
+       mainbin = player->pipeline->mainbin;
+
+       LOGD("type(%d) path is creating", type);
+       switch (type) {
+       case MM_PLAYER_STREAM_TYPE_AUDIO:
+               prefix = "audio";
+               if (mainbin[MMPLAYER_M_SRC].gst)
+                       src_id = MMPLAYER_M_2ND_SRC;
+               else
+                       src_id = MMPLAYER_M_SRC;
+               queue_id = MMPLAYER_M_A_BUFFER;
+       break;
+       case MM_PLAYER_STREAM_TYPE_VIDEO:
+               prefix = "video";
+               src_id = MMPLAYER_M_SRC;
+               queue_id = MMPLAYER_M_V_BUFFER;
+       break;
+       case MM_PLAYER_STREAM_TYPE_TEXT:
+               prefix = "subtitle";
+               src_id = MMPLAYER_M_SUBSRC;
+               queue_id = MMPLAYER_M_S_BUFFER;
+       break;
+       default:
+               LOGE("invalid type %d", type);
+               return FALSE;
+       }
+
+       snprintf(src_name, sizeof(src_name), "%s_appsrc", prefix);
+       snprintf(queue_name, sizeof(queue_name), "%s_queue", prefix);
+
+       /* create source */
+       src = gst_element_factory_make("appsrc", src_name);
+       if (!src) {
+               LOGF("failed to create %s", src_name);
+               goto ERROR;
+       }
+
+       mainbin[src_id].id = src_id;
+       mainbin[src_id].gst = src;
+
+       g_object_set(G_OBJECT(src), "format", GST_FORMAT_TIME,
+                                                               "caps", caps, NULL);
+
+       /* size of many video frames are larger than default blocksize as 4096 */
+       if (type == MM_PLAYER_STREAM_TYPE_VIDEO)
+               g_object_set(G_OBJECT(src), "blocksize", (guint)1048576, NULL);
+
+       if (player->media_stream_buffer_max_size[type] > 0)
+               g_object_set(G_OBJECT(src), "max-bytes", player->media_stream_buffer_max_size[type], NULL);
+
+       if (player->media_stream_buffer_min_percent[type] > 0)
+               g_object_set(G_OBJECT(src), "min-percent", player->media_stream_buffer_min_percent[type], NULL);
+
+       /*Fix Seek External Demuxer: set audio and video appsrc as seekable */
+       gst_app_src_set_stream_type((GstAppSrc*)G_OBJECT(src), GST_APP_STREAM_TYPE_SEEKABLE);
+
+       __mmplayer_add_signal_connection(player, G_OBJECT(src), MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
+                                                                                       G_CALLBACK(__mmplayer_gst_appsrc_seek_data), (gpointer)player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(src), MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
+                                                                                       G_CALLBACK(__mmplayer_gst_appsrc_feed_data), (gpointer)player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(src), MM_PLAYER_SIGNAL_TYPE_OTHERS, "enough-data",
+                                                                                       G_CALLBACK(__mmplayer_gst_appsrc_enough_data), (gpointer)player);
+
+       /* create queue */
+       queue = gst_element_factory_make("queue2", queue_name);
+       if (!queue) {
+               LOGE("failed to create %s", queue_name);
+               goto ERROR;
+       }
+       g_object_set(G_OBJECT(queue), "max-size-buffers", 2, NULL);
+
+       mainbin[queue_id].id = queue_id;
+       mainbin[queue_id].gst = queue;
+
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), mainbin[src_id].gst)) {
+               LOGE("failed to add src");
+               goto ERROR;
+       }
+
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), mainbin[queue_id].gst)) {
+               LOGE("failed to add queue");
+               goto ERROR;
+       }
+
+       if (!gst_element_link(mainbin[src_id].gst, mainbin[queue_id].gst)) {
+               LOGE("failed to link src and queue");
+               goto ERROR;
+       }
+
+       /* create decoder */
+       srcpad = gst_element_get_static_pad(mainbin[queue_id].gst, "src");
+       if (!srcpad) {
+               LOGE("failed to get srcpad of queue");
+               goto ERROR;
+       }
+
+       if (type == MM_PLAYER_STREAM_TYPE_TEXT) {
+               __mmplayer_try_to_plug_decodebin(player, gst_element_get_static_pad(mainbin[queue_id].gst, "src"), caps);
+       } else {
+               if (!__mmplayer_gst_create_es_decoder(player, type, srcpad)) {
+                       LOGE("failed to create decoder");
+                       gst_object_unref(GST_OBJECT(srcpad));
+                       goto ERROR;
+               }
+       }
+       gst_object_unref(GST_OBJECT(srcpad));
+       return TRUE;
+
+ERROR:
+       if (mainbin[src_id].gst) {
+               gst_element_set_state(mainbin[src_id].gst, GST_STATE_NULL);
+               gst_bin_remove(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), mainbin[src_id].gst);
+               gst_object_unref(mainbin[src_id].gst);
+               mainbin[src_id].gst = NULL;
+       }
+
+       if (mainbin[queue_id].gst) {
+               gst_element_set_state(mainbin[queue_id].gst, GST_STATE_NULL);
+               gst_bin_remove(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), mainbin[queue_id].gst);
+               gst_object_unref(mainbin[queue_id].gst);
+               mainbin[queue_id].gst = NULL;
+       }
+
+       return FALSE;
+}
+
+static void
+__mmplayer_gst_rtp_dynamic_pad(GstElement *element, GstPad *pad, gpointer data)
+{
+       GstPad *sinkpad = NULL;
+       GstCaps* caps = NULL;
+       GstElement* new_element = NULL;
+       GstStructure* str = NULL;
+       const gchar* name = NULL;
+
+       mm_player_t* player = (mm_player_t*) data;
+
+       MMPLAYER_FENTER();
+
+       MMPLAYER_RETURN_IF_FAIL(element && pad);
+       MMPLAYER_RETURN_IF_FAIL(player &&
+                                       player->pipeline &&
+                                       player->pipeline->mainbin);
+
+
+       /* payload type is recognizable. increase num_dynamic and wait for sinkbin creation.
+        * num_dynamic_pad will decreased after creating a sinkbin.
+        */
+       player->num_dynamic_pad++;
+       LOGD("stream count inc : %d\n", player->num_dynamic_pad);
+
+       caps = gst_pad_query_caps(pad, NULL);
+
+       MMPLAYER_CHECK_NULL(caps);
+
+       /* clear  previous result*/
+       player->have_dynamic_pad = FALSE;
+
+       str = gst_caps_get_structure(caps, 0);
+
+       if (!str) {
+               LOGE("cannot get structure from caps.\n");
+               goto ERROR;
+       }
+
+       name = gst_structure_get_name(str);
+       if (!name) {
+               LOGE("cannot get mimetype from structure.\n");
+               goto ERROR;
+       }
+
+       if (strstr(name, "video")) {
+               gint stype = 0;
+               mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype);
+
+               if (stype == MM_DISPLAY_SURFACE_NULL || stype == MM_DISPLAY_SURFACE_REMOTE) {
+                       if (player->v_stream_caps) {
+                               gst_caps_unref(player->v_stream_caps);
+                               player->v_stream_caps = NULL;
+                       }
+
+                       new_element = gst_element_factory_make("fakesink", NULL);
+                       player->num_dynamic_pad--;
+                       goto NEW_ELEMENT;
+               }
+       }
+
+       /* clear  previous result*/
+       player->have_dynamic_pad = FALSE;
+
+       if (!__mmplayer_try_to_plug_decodebin(player, pad, caps)) {
+               LOGE("failed to autoplug for caps");
+               goto ERROR;
+       }
+
+       /* check if there's dynamic pad*/
+       if (player->have_dynamic_pad) {
+               LOGE("using pad caps assums there's no dynamic pad !\n");
+               goto ERROR;
+       }
+
+       gst_caps_unref(caps);
+       caps = NULL;
+
+NEW_ELEMENT:
+
+       /* excute new_element if created*/
+       if (new_element) {
+               LOGD("adding new element to pipeline\n");
+
+               /* set state to READY before add to bin */
+               MMPLAYER_ELEMENT_SET_STATE(new_element, GST_STATE_READY);
+
+               /* add new element to the pipeline */
+               if (FALSE == gst_bin_add(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), new_element)) {
+                       LOGE("failed to add autoplug element to bin\n");
+                       goto ERROR;
+               }
+
+               /* get pad from element */
+               sinkpad = gst_element_get_static_pad(GST_ELEMENT(new_element), "sink");
+               if (!sinkpad) {
+                       LOGE("failed to get sinkpad from autoplug element\n");
+                       goto ERROR;
+               }
+
+               /* link it */
+               if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
+                       LOGE("failed to link autoplug element\n");
+                       goto ERROR;
+               }
+
+               gst_object_unref(sinkpad);
+               sinkpad = NULL;
+
+               /* run. setting PLAYING here since streamming source is live source */
+               MMPLAYER_ELEMENT_SET_STATE(new_element, GST_STATE_PLAYING);
+       }
+
+       if (caps)
+               gst_caps_unref(caps);
+
+       MMPLAYER_FLEAVE();
+
+       return;
+
+STATE_CHANGE_FAILED:
+ERROR:
+       /* FIXIT : take care if new_element has already added to pipeline */
+       if (new_element)
+               gst_object_unref(GST_OBJECT(new_element));
+
+       if (sinkpad)
+               gst_object_unref(GST_OBJECT(sinkpad));
+
+       if (caps)
+               gst_caps_unref(caps);
+
+       /* FIXIT : how to inform this error to MSL ????? */
+       /* FIXIT : I think we'd better to use g_idle_add() to destroy pipeline and
+        * then post an error to application
+        */
+}
+
+static void
+__mmplayer_gst_rtp_no_more_pads(GstElement *element,  gpointer data)
+{
+       mm_player_t* player = (mm_player_t*) data;
+
+       MMPLAYER_FENTER();
+
+       /* NOTE : we can remove fakesink here if there's no rtp_dynamic_pad. because whenever
+         * we connect autoplugging element to the pad which is just added to rtspsrc, we increase
+         * num_dynamic_pad. and this is no-more-pad situation which means no more pad will be added.
+         * So we can say this. if num_dynamic_pad is zero, it must be one of followings
+
+         * [1] audio and video will be dumped with filesink.
+         * [2] autoplugging is done by just using pad caps.
+         * [3] typefinding has happend in audio but audiosink is created already before no-more-pad signal
+         * and the video will be dumped via filesink.
+         */
+       if (player->num_dynamic_pad == 0) {
+               LOGD("it seems pad caps is directely used for autoplugging. removing fakesink now\n");
+
+               if (!__mmplayer_gst_remove_fakesink(player,
+                       &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK]))
+                       /* NOTE : __mmplayer_pipeline_complete() can be called several time. because
+                        * signaling mechanism(pad-added, no-more-pad, new-decoded-pad) from various
+                        * source element are not same. To overcome this situation, this function will called
+                        * several places and several times. Therefore, this is not an error case.
+                        */
+                       return;
+       }
+
+       /* create dot before error-return. for debugging */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-no-more-pad");
+
+       player->no_more_pad = TRUE;
+
+       MMPLAYER_FLEAVE();
+}
+
+static GstElement*
+__mmplayer_gst_create_rtsp_src(mm_player_t* player)
+{
+       GstElement* element = NULL;
+       gchar *user_agent = NULL;
+       MMHandleType attrs = 0;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
+
+       /* get profile attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if (!attrs) {
+               LOGE("failed to get content attribute");
+               return NULL;
+       }
+
+       element = gst_element_factory_make("rtspsrc", "rtsp source");
+       if (!element) {
+               LOGE("failed to create rtspsrc element");
+               return NULL;
+       }
+
+       /* get attribute */
+       mm_attrs_get_string_by_name(attrs, "streaming_user_agent", &user_agent);
+
+       SECURE_LOGD("user_agent : %s", user_agent);
+
+       /* setting property to streaming source */
+       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
+       if (user_agent)
+               g_object_set(G_OBJECT(element), "user-agent", user_agent, NULL);
+
+       __mmplayer_add_signal_connection(player, G_OBJECT(element), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
+                                                                       G_CALLBACK(__mmplayer_gst_rtp_dynamic_pad), (gpointer)player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(element), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
+                                                                       G_CALLBACK(__mmplayer_gst_rtp_no_more_pads), (gpointer)player);
+
+       MMPLAYER_FLEAVE();
+       return element;
+}
+
+static GstElement*
+__mmplayer_gst_create_http_src(mm_player_t* player)
+{
+       GstElement* element = NULL;
+       MMHandleType attrs = 0;
+       gchar *user_agent, *cookies, **cookie_list;
+       gint http_timeout = DEFAULT_HTTP_TIMEOUT;
+       user_agent = cookies = NULL;
+       cookie_list = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
+
+       /* get profile attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if (!attrs) {
+               LOGE("failed to get content attribute");
+               return NULL;
+       }
+
+       LOGD("using http streamming source [%s]", player->ini.httpsrc_element);
+
+       element = gst_element_factory_make(player->ini.httpsrc_element, "http_streaming_source");
+       if (!element) {
+               LOGE("failed to create http streaming source element[%s]", player->ini.httpsrc_element);
+               return NULL;
+       }
+
+       /* get attribute */
+       mm_attrs_get_string_by_name(attrs, "streaming_cookie", &cookies);
+       mm_attrs_get_string_by_name(attrs, "streaming_user_agent", &user_agent);
+
+       if (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT)
+               http_timeout = player->ini.http_timeout;
+
+       /* get attribute */
+       SECURE_LOGD("location : %s", player->profile.uri);
+       SECURE_LOGD("cookies : %s", cookies);
+       SECURE_LOGD("user_agent :  %s", user_agent);
+       LOGD("timeout : %d", http_timeout);
+
+       /* setting property to streaming source */
+       g_object_set(G_OBJECT(element), "location", player->profile.uri,
+                               "timeout", http_timeout, "blocksize", (unsigned long)(64*1024), NULL);
+
+       /* parsing cookies */
+       if ((cookie_list = util_get_cookie_list((const char*)cookies))) {
+               g_object_set(G_OBJECT(element), "cookies", cookie_list, NULL);
+               g_strfreev(cookie_list);
+       }
+
+       if (user_agent)
+               g_object_set(G_OBJECT(element), "user-agent", user_agent, NULL);
+
+       if (MMPLAYER_URL_HAS_DASH_SUFFIX(player))
+               LOGW("[DASH] this is still experimental feature");
+
+       MMPLAYER_FLEAVE();
+       return element;
+}
+
+static GstElement*
+__mmplayer_gst_create_file_src(mm_player_t* player)
+{
+       GstElement* element = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
+
+       LOGD("using filesrc for 'file://' handler");
+       if (!util_get_storage_info(player->profile.uri, &player->storage_info[MMPLAYER_PATH_VOD])) {
+               LOGE("failed to get storage info");
+               return NULL;
+       }
+
+       element = gst_element_factory_make("filesrc", "source");
+       if (!element) {
+               LOGE("failed to create filesrc");
+               return NULL;
+       }
+
+       g_object_set(G_OBJECT(element), "location", (player->profile.uri)+7, NULL); /* uri+7 -> remove "file:// */
+
+       MMPLAYER_FLEAVE();
+       return element;
+}
+
+static gboolean __mmplayer_gst_msg_push(GstBus *bus, GstMessage *msg, gpointer data)
+{
+       mm_player_t *player = (mm_player_t *) data;
+
+       g_return_val_if_fail(player, FALSE);
+       g_return_val_if_fail(msg && GST_IS_MESSAGE(msg), FALSE);
+
+       gst_message_ref(msg);
+
+       g_mutex_lock(&player->bus_msg_q_lock);
+       g_queue_push_tail(player->bus_msg_q, msg);
+       g_mutex_unlock(&player->bus_msg_q_lock);
+
+       MMPLAYER_BUS_MSG_THREAD_LOCK(player);
+       MMPLAYER_BUS_MSG_THREAD_SIGNAL(player);
+       MMPLAYER_BUS_MSG_THREAD_UNLOCK(player);
+       return TRUE;
+}
+
+static gpointer __mmplayer_gst_bus_msg_thread(gpointer data)
+{
+       mm_player_t *player = (mm_player_t*)(data);
+       GstMessage *msg = NULL;
+       GstBus *bus = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player &&
+                                               player->pipeline &&
+                                               player->pipeline->mainbin &&
+                                               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+                                               NULL);
+
+       bus = gst_pipeline_get_bus(GST_PIPELINE(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
+       if (!bus) {
+               LOGE("cannot get BUS from the pipeline");
+               return NULL;
+       }
+
+       MMPLAYER_BUS_MSG_THREAD_LOCK(player);
+
+       LOGD("[handle: %p] gst bus msg thread will be started.", player);
+       while (!player->bus_msg_thread_exit) {
+               g_mutex_lock(&player->bus_msg_q_lock);
+               msg = g_queue_pop_head(player->bus_msg_q);
+               g_mutex_unlock(&player->bus_msg_q_lock);
+               if (msg == NULL) {
+                       MMPLAYER_BUS_MSG_THREAD_WAIT(player);
+                       continue;
+               }
+               MMPLAYER_BUS_MSG_THREAD_UNLOCK(player);
+               /* handle the gst msg */
+               __mmplayer_gst_bus_msg_callback(msg, player);
+               MMPLAYER_BUS_MSG_THREAD_LOCK(player);
+               gst_message_unref(msg);
+       }
+
+       MMPLAYER_BUS_MSG_THREAD_UNLOCK(player);
+       gst_object_unref(GST_OBJECT(bus));
+
+       MMPLAYER_FLEAVE();
+       return NULL;
+}
+
+#if 0
+#endif
+
+int
+__mmplayer_gst_set_state(mm_player_t* player, GstElement * element,  GstState state, gboolean async, gint timeout)
+{
+       GstState element_state = GST_STATE_VOID_PENDING;
+       GstState element_pending_state = GST_STATE_VOID_PENDING;
+       GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
+
+       MMPLAYER_FENTER();
+
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(element, MM_ERROR_INVALID_ARGUMENT);
+
+       LOGD("setting [%s] element state to : %s\n", GST_ELEMENT_NAME(element), gst_element_state_get_name(state));
+
+       /* set state */
+       ret = gst_element_set_state(element, state);
+
+       if (ret == GST_STATE_CHANGE_FAILURE) {
+               LOGE("failed to set [%s] state\n", GST_ELEMENT_NAME(element));
 
-GstBusSyncReply
-__mmplayer_gst_bus_sync_callback(GstBus * bus, GstMessage * message, gpointer data)
-{
-       mm_player_t *player = (mm_player_t *)data;
-       GstBusSyncReply reply = GST_BUS_DROP;
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state(player);
 
-       if (!(player->pipeline && player->pipeline->mainbin)) {
-               LOGE("player pipeline handle is null");
-               return GST_BUS_PASS;
+               return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       if (!__mmplayer_gst_check_useful_message(player, message)) {
-               gst_message_unref(message);
-               return GST_BUS_DROP;
+       /* return here so state transition to be done in async mode */
+       if (async) {
+               LOGD("async state transition. not waiting for state complete.\n");
+               return MM_ERROR_NONE;
        }
 
-       switch (GST_MESSAGE_TYPE(message)) {
-       case GST_MESSAGE_STATE_CHANGED:
-               /* post directly for fast launch */
-               if (player->sync_handler) {
-                       __mmplayer_gst_bus_msg_callback(message, player);
-                       reply = GST_BUS_DROP;
-               } else
-                       reply = GST_BUS_PASS;
-               break;
-       case GST_MESSAGE_TAG:
-               __mmplayer_gst_extract_tag_from_msg(player, message);
+       /* wait for state transition */
+       ret = gst_element_get_state(element, &element_state, &element_pending_state, timeout * GST_SECOND);
 
-               #if 0 // debug
-               {
-                       GstTagList *tags = NULL;
+       if (ret == GST_STATE_CHANGE_FAILURE || (state != element_state)) {
+               LOGE("failed to change [%s] element state to [%s] within %d sec\n",
+                       GST_ELEMENT_NAME(element),
+                       gst_element_state_get_name(state), timeout);
 
-                       gst_message_parse_tag(message, &tags);
-                       if (tags) {
-                               LOGE("TAGS received from element \"%s\".\n",
-                               GST_STR_NULL(GST_ELEMENT_NAME(GST_MESSAGE_SRC(message))));
+               LOGE(" [%s] state : %s   pending : %s \n",
+                       GST_ELEMENT_NAME(element),
+                       gst_element_state_get_name(element_state),
+                       gst_element_state_get_name(element_pending_state));
 
-                               gst_tag_list_foreach(tags, print_tag, NULL);
-                               gst_tag_list_free(tags);
-                               tags = NULL;
-                       }
-                       break;
-               }
-               #endif
-               break;
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state(player);
 
-       case GST_MESSAGE_DURATION_CHANGED:
-               __mmplayer_gst_handle_duration(player, message);
-               break;
-       case GST_MESSAGE_ASYNC_DONE:
-               /* NOTE:Don't call gst_callback directly
-                * because previous frame can be showed even though this message is received for seek.
-                */
-       default:
-               reply = GST_BUS_PASS;
-               break;
+               return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       if (reply == GST_BUS_DROP)
-               gst_message_unref(message);
+       LOGD("[%s] element state has changed\n", GST_ELEMENT_NAME(element));
 
-       return reply;
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
 }
 
 int __mmplayer_gst_start(mm_player_t* player)
@@ -3051,3 +3808,425 @@ int __mmplayer_gst_get_buffer_position(mm_player_t* player, int format, unsigned
        return MM_ERROR_NONE;
 }
 
+int __mmplayer_gst_build_es_pipeline(mm_player_t* player)
+{
+       MMHandleType attrs = 0;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       /* get profile attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if (!attrs) {
+               LOGE("failed to get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       SECURE_LOGD("uri : %s", player->profile.uri);
+
+       mm_attrs_set_int_by_name(attrs, "profile_prepare_async", TRUE);
+       if (mmf_attrs_commit(attrs)) /* return -1 if error */
+               LOGE("failed to commit");
+
+       if (player->v_stream_caps && !__mmplayer_gst_create_es_path(player, MM_PLAYER_STREAM_TYPE_VIDEO, player->v_stream_caps))
+               return MM_ERROR_PLAYER_INTERNAL;
+
+       if (player->a_stream_caps && !__mmplayer_gst_create_es_path(player, MM_PLAYER_STREAM_TYPE_AUDIO, player->a_stream_caps))
+               return MM_ERROR_PLAYER_INTERNAL;
+
+       if (player->s_stream_caps && !__mmplayer_gst_create_es_path(player, MM_PLAYER_STREAM_TYPE_TEXT, player->s_stream_caps))
+               return MM_ERROR_PLAYER_INTERNAL;
+
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+}
+
+int __mmplayer_gst_build_pd_pipeline(mm_player_t* player)
+{
+       MMPlayerGstElement *mainbin = NULL;
+       GstElement *pd_src = NULL;
+       GstElement *pd_queue = NULL;
+       GstElement *pd_decodebin = NULL;
+       GList* element_bucket = NULL;
+       MMHandleType attrs = 0;
+       gchar *path = NULL;
+       gint pre_buffering_time = player->streamer->buffering_req.prebuffer_time;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       /* get profile attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if (!attrs) {
+               LOGE("failed to get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       LOGD("http playback with progressive download : %d", player->pd_mode);
+
+       if (player->pd_mode == MM_PLAYER_PD_MODE_URI) {
+               mm_attrs_get_string_by_name(attrs, "pd_location", &path);
+               MMPLAYER_FREEIF(player->pd_file_save_path);
+
+               SECURE_LOGD("PD Location : %s", path);
+               if (!path) {
+                       LOGE("filed to find pd location");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+
+               if (!util_get_storage_info(path, &player->storage_info[MMPLAYER_PATH_VOD])) {
+                       LOGE("failed to get storage info");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+               player->pd_file_save_path = g_strdup(path);
+       }
+
+       pd_src = gst_element_factory_make("pdpushsrc", "PD pushsrc");
+       if (!pd_src) {
+               LOGE("failed to create PD push source");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       if (player->pd_mode == MM_PLAYER_PD_MODE_URI)
+               g_object_set(G_OBJECT(pd_src), "location", player->pd_file_save_path, NULL);
+       else
+               g_object_set(G_OBJECT(pd_src), "location", player->profile.uri, NULL);
+
+       mainbin = player->pipeline->mainbin;
+
+       /* take source element */
+       mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC;
+       mainbin[MMPLAYER_M_SRC].gst = pd_src;
+       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_SRC]);
+
+       /* setting queue */
+       LOGD("Picked queue2 element(pre buffer : %d ms)", pre_buffering_time);
+       pd_queue = gst_element_factory_make("queue2", "queue2");
+       if (!pd_queue) {
+               LOGE("failed to create pd buffer element");
+               goto ERROR;
+       }
+
+       /* take queue2 */
+       mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER;
+       mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = pd_queue;
+       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_MUXED_S_BUFFER]);
+
+       pre_buffering_time = (pre_buffering_time > 0) ? (pre_buffering_time) : (player->ini.http_buffering_time);
+
+       player->streamer->is_pd_mode = TRUE;
+
+       __mm_player_streaming_set_queue2(player->streamer, pd_queue, TRUE,
+                       player->ini.http_max_size_bytes, pre_buffering_time, 1.0,
+                       player->ini.http_buffering_limit, MUXED_BUFFER_TYPE_MEM_QUEUE, NULL, 0);
+
+       pd_decodebin = __mmplayer_create_decodebin(player);
+       if (!pd_decodebin) {
+               LOGE("failed to create decodebin");
+               goto ERROR;
+       }
+
+       /* default size of mq in decodebin is 2M
+        * but it can cause blocking issue during seeking depends on content. */
+       g_object_set(G_OBJECT(pd_decodebin), "max-size-bytes", (5*1024*1024), NULL);
+
+       mainbin[MMPLAYER_M_AUTOPLUG].id = MMPLAYER_M_AUTOPLUG;
+       mainbin[MMPLAYER_M_AUTOPLUG].gst = pd_decodebin;
+
+       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_AUTOPLUG]);
+
+       /* add elements to pipeline */
+       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element_bucket)) {
+               LOGE("failed to add elements to pipeline");
+               goto ERROR;
+       }
+
+       /* linking elements in the bucket by added order. */
+       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1) {
+               LOGE("failed to link some elements");
+               goto ERROR;
+       }
+
+       g_list_free(element_bucket);
+
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+
+ERROR:
+       MMPLAYER_FREEIF(player->pd_file_save_path);
+       g_list_free(element_bucket);
+
+       if (mainbin[MMPLAYER_M_SRC].gst)
+               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC].gst));
+
+       if (mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst)
+               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst));
+
+       if (mainbin[MMPLAYER_M_AUTOPLUG].gst)
+               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_AUTOPLUG].gst));
+
+       mainbin[MMPLAYER_M_SRC].gst = NULL;
+       mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = NULL;
+       mainbin[MMPLAYER_M_AUTOPLUG].gst = NULL;
+
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+int __mmplayer_gst_build_pipeline(mm_player_t* player)
+{
+       MMPlayerGstElement *mainbin = NULL;
+       GstElement* src_elem = NULL;
+       GstElement *autoplug_elem = NULL;
+       GList* element_bucket = NULL;
+       MMHandleType attrs = 0;
+       enum MainElementID autoplug_elem_id = MMPLAYER_M_NUM;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       /* get profile attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if (!attrs) {
+               LOGE("failed to get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       LOGD("uri type %d", player->profile.uri_type);
+
+       /* create source element */
+       switch (player->profile.uri_type) {
+       case MM_PLAYER_URI_TYPE_URL_RTSP:
+               src_elem = __mmplayer_gst_create_rtsp_src(player);
+               break;
+       case MM_PLAYER_URI_TYPE_URL_HTTP:
+               src_elem = __mmplayer_gst_create_http_src(player);
+               break;
+       case MM_PLAYER_URI_TYPE_FILE:
+               src_elem = __mmplayer_gst_create_file_src(player);
+               break;
+       case MM_PLAYER_URI_TYPE_SS:
+               {
+                       gint http_timeout = DEFAULT_HTTP_TIMEOUT;
+                       src_elem = gst_element_factory_make("souphttpsrc", "http streaming source");
+                       if (!src_elem) {
+                               LOGE("failed to create http streaming source element[%s]", player->ini.httpsrc_element);
+                               break;
+                       }
+
+                       if (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT) {
+                               LOGD("get timeout from ini");
+                               http_timeout = player->ini.http_timeout;
+                       }
+
+                       /* setting property to streaming source */
+                       g_object_set(G_OBJECT(src_elem), "location", player->profile.uri, "timeout", http_timeout, NULL);
+               }
+               break;
+       case MM_PLAYER_URI_TYPE_MEM:
+               {
+                       guint64 stream_type = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
+
+                       src_elem = gst_element_factory_make("appsrc", "mem-source");
+                       if (!src_elem) {
+                               LOGE("failed to create appsrc element");
+                               break;
+                       }
+
+                       g_object_set(src_elem, "stream-type", stream_type,
+                                       "size", player->profile.input_mem.len, "blocksize", (guint64)20480, NULL);
+
+                       __mmplayer_add_signal_connection(player, G_OBJECT(src_elem), MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
+                                                                                       G_CALLBACK(__mmplayer_gst_appsrc_seek_data_mem), (gpointer)&player->profile.input_mem);
+                       __mmplayer_add_signal_connection(player, G_OBJECT(src_elem), MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
+                                                                                       G_CALLBACK(__mmplayer_gst_appsrc_feed_data_mem), (gpointer)&player->profile.input_mem);
+               }
+               break;
+       default:
+               LOGE("not support uri type");
+               break;
+       }
+
+       if (!src_elem) {
+               LOGE("failed to create source element");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       mainbin = player->pipeline->mainbin;
+
+       /* take source element */
+       LOGD("source elem is created %s", GST_ELEMENT_NAME(src_elem));
+
+       mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC;
+       mainbin[MMPLAYER_M_SRC].gst = src_elem;
+       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_SRC]);
+
+       /* create next element for auto-plugging */
+       if (MMPLAYER_IS_HTTP_STREAMING(player)) {
+               autoplug_elem_id = MMPLAYER_M_TYPEFIND;
+               autoplug_elem = gst_element_factory_make("typefind", "typefinder");
+               if (!autoplug_elem) {
+                       LOGE("failed to create typefind element");
+                       goto ERROR;
+               }
+
+               __mmplayer_add_signal_connection(player, G_OBJECT(autoplug_elem), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type",
+                                                                       G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player);
+       } else if (!MMPLAYER_IS_RTSP_STREAMING(player)) {
+               autoplug_elem_id = MMPLAYER_M_AUTOPLUG;
+               autoplug_elem = __mmplayer_create_decodebin(player);
+               if (!autoplug_elem) {
+                       LOGE("failed to create decodebin");
+                       goto ERROR;
+               }
+
+               /* default size of mq in decodebin is 2M
+                * but it can cause blocking issue during seeking depends on content. */
+               g_object_set(G_OBJECT(autoplug_elem), "max-size-bytes", (5*1024*1024), NULL);
+       }
+
+       if (autoplug_elem) {
+               LOGD("autoplug elem is created %s", GST_ELEMENT_NAME(autoplug_elem));
+               mainbin[autoplug_elem_id].id = autoplug_elem_id;
+               mainbin[autoplug_elem_id].gst = autoplug_elem;
+
+               element_bucket = g_list_append(element_bucket, &mainbin[autoplug_elem_id]);
+       }
+
+       /* add elements to pipeline */
+       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element_bucket)) {
+               LOGE("failed to add elements to pipeline");
+               goto ERROR;
+       }
+
+       /* linking elements in the bucket by added order. */
+       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1) {
+               LOGE("failed to link some elements");
+               goto ERROR;
+       }
+
+       /* FIXME: need to check whether this is required or not. */
+       if (MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_RTSP_STREAMING(player)) {
+               /* create fakesink element for keeping the pipeline state PAUSED. if needed */
+               mainbin[MMPLAYER_M_SRC_FAKESINK].id = MMPLAYER_M_SRC_FAKESINK;
+               mainbin[MMPLAYER_M_SRC_FAKESINK].gst = gst_element_factory_make("fakesink", "state-holder");
+
+               if (!mainbin[MMPLAYER_M_SRC_FAKESINK].gst) {
+                       LOGE("failed to create fakesink");
+                       goto ERROR;
+               }
+               GST_OBJECT_FLAG_UNSET(mainbin[MMPLAYER_M_SRC_FAKESINK].gst, GST_ELEMENT_FLAG_SINK);
+
+               /* take ownership of fakesink. we are reusing it */
+               gst_object_ref(mainbin[MMPLAYER_M_SRC_FAKESINK].gst);
+
+               if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), mainbin[MMPLAYER_M_SRC_FAKESINK].gst)) {
+                       LOGE("failed to add fakesink to bin");
+                       gst_object_unref(mainbin[MMPLAYER_M_SRC_FAKESINK].gst);
+                       goto ERROR;
+               }
+       }
+
+       g_list_free(element_bucket);
+
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+
+ERROR:
+       g_list_free(element_bucket);
+
+       if (mainbin[MMPLAYER_M_SRC].gst)
+               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC].gst));
+
+       if (mainbin[autoplug_elem_id].gst)
+               gst_object_unref(GST_OBJECT(mainbin[autoplug_elem_id].gst));
+
+       if (mainbin[MMPLAYER_M_SRC_FAKESINK].gst)
+               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC_FAKESINK].gst));
+
+       mainbin[MMPLAYER_M_SRC].gst = NULL;
+       mainbin[autoplug_elem_id].gst = NULL;
+       mainbin[MMPLAYER_M_SRC_FAKESINK].gst = NULL;
+
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+int __mmplayer_gst_add_bus_watch(mm_player_t* player)
+{
+       GstBus  *bus = NULL;
+       MMPlayerGstElement *mainbin = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       mainbin = player->pipeline->mainbin;
+
+       /* connect bus callback */
+       bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[MMPLAYER_M_PIPE].gst));
+       if (!bus) {
+               LOGE("cannot get bus from pipeline");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       player->bus_watcher = gst_bus_add_watch(bus, (GstBusFunc)__mmplayer_gst_msg_push, player);
+       player->context.thread_default = g_main_context_get_thread_default();
+       if (player->context.thread_default == NULL) {
+               player->context.thread_default = g_main_context_default();
+               LOGD("thread-default context is the global default context");
+       }
+       LOGW("bus watcher thread context = %p, watcher : %d", player->context.thread_default, player->bus_watcher);
+
+       /* set sync handler to get tag synchronously */
+       gst_bus_set_sync_handler(bus, __mmplayer_gst_bus_sync_callback, player, NULL);
+       gst_object_unref(GST_OBJECT(bus));
+
+       /* create gst bus_msb_cb thread */
+       g_mutex_init(&player->bus_msg_thread_mutex);
+       g_cond_init(&player->bus_msg_thread_cond);
+       player->bus_msg_thread_exit = FALSE;
+       player->bus_msg_thread =
+               g_thread_try_new("gst_bus_msg_thread", __mmplayer_gst_bus_msg_thread, (gpointer)player, NULL);
+       if (!player->bus_msg_thread) {
+               LOGE("failed to create gst BUS msg thread");
+               g_mutex_clear(&player->bus_msg_thread_mutex);
+               g_cond_clear(&player->bus_msg_thread_cond);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+}
+
+GstElement* __mmplayer_gst_build_source(mm_player_t* player)
+{
+       GstElement* element = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->mainbin, NULL);
+
+       /* setup source for gapless play */
+       switch (player->profile.uri_type) {
+       /* file source */
+       case MM_PLAYER_URI_TYPE_FILE:
+               element = __mmplayer_gst_create_file_src(player);
+               break;
+       case MM_PLAYER_URI_TYPE_URL_HTTP:
+               element = __mmplayer_gst_create_http_src(player);
+               break;
+       default:
+               LOGE("not support uri type %d", player->profile.uri_type);
+               break;
+       }
+
+       if (!element) {
+               LOGE("failed to create source element");
+               return NULL;
+       }
+
+       MMPLAYER_FLEAVE();
+       return element;
+}
index 16dbe49..90ea951 100644 (file)
@@ -27,7 +27,6 @@
 ========================================================================================== */
 #include <glib.h>
 #include <gst/gst.h>
-#include <gst/app/gstappsrc.h>
 #include <gst/video/videooverlay.h>
 #include <gst/audio/gstaudiobasesink.h>
 #include <unistd.h>
@@ -136,33 +135,23 @@ static int                __mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps *c
 static int             __mmplayer_gst_create_audio_pipeline(mm_player_t* player);
 static int             __mmplayer_gst_create_text_pipeline(mm_player_t* player);
 static int             __mmplayer_gst_create_text_sink_bin(mm_player_t* player);
-static int             __mmplayer_gst_element_link_bucket(GList* element_bucket);
 
 static GstPadProbeReturn       __mmplayer_gst_selector_blocked(GstPad* pad, GstPadProbeInfo *info, gpointer data);
-static void            __mmplayer_gst_decode_pad_added(GstElement* elem, GstPad* pad, gpointer data);
 static void            __mmplayer_gst_decode_no_more_pads(GstElement* elem, gpointer data);
 static void            __mmplayer_gst_decode_callback(GstElement *decodebin, GstPad *pad, gpointer data);
 static void            __mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPad* pad, GstCaps *caps, gpointer data);
 static gboolean __mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPad* pad, GstCaps * caps,  gpointer data);
-static gint            __mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPad* pad, GstCaps * caps, GstElementFactory* factory, gpointer data);
 static void __mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPad* new_pad, gpointer data);
 static void __mmplayer_gst_decode_drained(GstElement *bin, gpointer data);
-static void    __mmplayer_gst_element_added(GstElement* bin, GstElement* element, gpointer data);
-static GstElement * __mmplayer_create_decodebin(mm_player_t* player);
-static gboolean __mmplayer_try_to_plug_decodebin(mm_player_t* player, GstPad *srcpad, const GstCaps *caps);
-static void    __mmplayer_typefind_have_type(GstElement *tf, guint probability, GstCaps *caps, gpointer data);
 static void    __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data);
 static gboolean __mmplayer_is_midi_type(gchar* str_caps);
 static gboolean __mmplayer_is_only_mp3_type(gchar *str_caps);
 static void    __mmplayer_set_audio_attrs(mm_player_t* player, GstCaps* caps);
 
-static void            __mmplayer_gst_rtp_no_more_pads(GstElement *element,  gpointer data);
-static void            __mmplayer_gst_rtp_dynamic_pad(GstElement *element, GstPad *pad, gpointer data);
 static gboolean        __mmplayer_update_subtitle(GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data);
 static void            __mmplayer_release_misc(mm_player_t* player);
 static void            __mmplayer_release_misc_post(mm_player_t* player);
 static gboolean        __mmplayer_init_gstreamer(mm_player_t* player);
-static gboolean __mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink);
 static GstPadProbeReturn __mmplayer_audio_stream_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
 static void __mmplayer_video_stream_decoded_preroll_cb(GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data);
 static void __mmplayer_video_stream_decoded_render_cb(GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data);
@@ -179,10 +168,10 @@ static gpointer __mmplayer_next_play_thread(gpointer data);
 static gboolean __mmplayer_add_dump_buffer_probe(mm_player_t *player, GstElement *element);
 static GstPadProbeReturn __mmplayer_dump_buffer_probe_cb(GstPad *pad,  GstPadProbeInfo *info, gpointer u_data);
 static void __mmplayer_release_dump_list(GList *dump_list);
-static int             __gst_realize(mm_player_t* player);
-static int             __gst_unrealize(mm_player_t* player);
-static int             __gst_adjust_subtitle_position(mm_player_t* player, int format, int position);
-static int             __gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param);
+static int             __mmplayer_gst_realize(mm_player_t* player);
+static int             __mmplayer_gst_unrealize(mm_player_t* player);
+static int             __mmplayer_gst_adjust_subtitle_position(mm_player_t* player, int format, int position);
+static int             __mmplayer_gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param);
 static gboolean __mmplayer_can_extract_pcm(mm_player_t* player);
 
 /* util */
@@ -199,14 +188,6 @@ static void __mmplayer_deactivate_old_path(mm_player_t *player);
 static GstElement *__mmplayer_element_create_and_link(mm_player_t *player, GstPad* pad, const char* name);
 static int __mmplayer_gst_create_plain_text_elements(mm_player_t* player);
 static guint32 _mmplayer_convert_fourcc_string_to_value(const gchar* format_name);
-static void            __gst_appsrc_feed_audio_data(GstElement *element, guint size, gpointer user_data);
-static void            __gst_appsrc_feed_video_data(GstElement *element, guint size, gpointer user_data);
-static void     __gst_appsrc_feed_subtitle_data(GstElement *element, guint size, gpointer user_data);
-static void            __gst_appsrc_enough_audio_data(GstElement *element, gpointer user_data);
-static void            __gst_appsrc_enough_video_data(GstElement *element, gpointer user_data);
-static gboolean        __gst_seek_audio_data(GstElement * appsrc, guint64 position, gpointer user_data);
-static gboolean        __gst_seek_video_data(GstElement * appsrc, guint64 position, gpointer user_data);
-static gboolean        __gst_seek_subtitle_data(GstElement * appsrc, guint64 position, gpointer user_data);
 static void            __mmplayer_gst_caps_notify_cb(GstPad * pad, GParamSpec * unused, gpointer data);
 static void            __mmplayer_audio_stream_send_data(mm_player_t* player, mm_player_audio_stream_buff_t *a_buffer);
 static void            __mmplayer_initialize_storage_info(mm_player_t* player, MMPlayerPathType path_type);
@@ -924,108 +905,7 @@ void __mmplayer_bus_msg_thread_destroy(MMHandleType hplayer)
        MMPLAYER_FLEAVE();
 }
 
-gboolean __mmplayer_gst_msg_push(GstBus *bus, GstMessage *msg, gpointer data)
-{
-       mm_player_t *player = (mm_player_t *) data;
-
-       g_return_val_if_fail(player, FALSE);
-       g_return_val_if_fail(msg && GST_IS_MESSAGE(msg), FALSE);
-
-       gst_message_ref(msg);
-
-       g_mutex_lock(&player->bus_msg_q_lock);
-       g_queue_push_tail(player->bus_msg_q, msg);
-       g_mutex_unlock(&player->bus_msg_q_lock);
-
-       MMPLAYER_BUS_MSG_THREAD_LOCK(player);
-       MMPLAYER_BUS_MSG_THREAD_SIGNAL(player);
-       MMPLAYER_BUS_MSG_THREAD_UNLOCK(player);
-       return TRUE;
-}
-
-static gpointer __mmplayer_gst_bus_msg_thread(gpointer data)
-{
-       mm_player_t *player = (mm_player_t*)(data);
-       GstMessage *msg = NULL;
-       GstBus *bus = NULL;
-
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player &&
-                                               player->pipeline &&
-                                               player->pipeline->mainbin &&
-                                               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
-                                               NULL);
-
-       bus = gst_pipeline_get_bus(GST_PIPELINE(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
-       if (!bus) {
-               LOGE("cannot get BUS from the pipeline");
-               return NULL;
-       }
-
-       MMPLAYER_BUS_MSG_THREAD_LOCK(player);
-
-       LOGD("[handle: %p] gst bus msg thread will be started.", player);
-       while (!player->bus_msg_thread_exit) {
-               g_mutex_lock(&player->bus_msg_q_lock);
-               msg = g_queue_pop_head(player->bus_msg_q);
-               g_mutex_unlock(&player->bus_msg_q_lock);
-               if (msg == NULL) {
-                       MMPLAYER_BUS_MSG_THREAD_WAIT(player);
-                       continue;
-               }
-               MMPLAYER_BUS_MSG_THREAD_UNLOCK(player);
-               /* handle the gst msg */
-               __mmplayer_gst_bus_msg_callback(msg, player);
-               MMPLAYER_BUS_MSG_THREAD_LOCK(player);
-               gst_message_unref(msg);
-       }
-
-       MMPLAYER_BUS_MSG_THREAD_UNLOCK(player);
-       gst_object_unref(GST_OBJECT(bus));
-
-       MMPLAYER_FLEAVE();
-       return NULL;
-}
-
-static void
-__mmplayer_gst_rtp_no_more_pads(GstElement *element,  gpointer data)
-{
-       mm_player_t* player = (mm_player_t*) data;
-
-       MMPLAYER_FENTER();
-
-       /* NOTE : we can remove fakesink here if there's no rtp_dynamic_pad. because whenever
-         * we connect autoplugging element to the pad which is just added to rtspsrc, we increase
-         * num_dynamic_pad. and this is no-more-pad situation which means no more pad will be added.
-         * So we can say this. if num_dynamic_pad is zero, it must be one of followings
-
-         * [1] audio and video will be dumped with filesink.
-         * [2] autoplugging is done by just using pad caps.
-         * [3] typefinding has happend in audio but audiosink is created already before no-more-pad signal
-         * and the video will be dumped via filesink.
-         */
-       if (player->num_dynamic_pad == 0) {
-               LOGD("it seems pad caps is directely used for autoplugging. removing fakesink now\n");
-
-               if (!__mmplayer_gst_remove_fakesink(player,
-                       &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK]))
-                       /* NOTE : __mmplayer_pipeline_complete() can be called several time. because
-                        * signaling mechanism(pad-added, no-more-pad, new-decoded-pad) from various
-                        * source element are not same. To overcome this situation, this function will called
-                        * several places and several times. Therefore, this is not an error case.
-                        */
-                       return;
-       }
-
-       /* create dot before error-return. for debugging */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-no-more-pad");
-
-       player->no_more_pad = TRUE;
-
-       MMPLAYER_FLEAVE();
-}
-
-static gboolean
+gboolean
 __mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink)
 {
        GstElement* parent = NULL;
@@ -1085,145 +965,6 @@ ERROR:
        return FALSE;
 }
 
-
-static void
-__mmplayer_gst_rtp_dynamic_pad(GstElement *element, GstPad *pad, gpointer data)
-{
-       GstPad *sinkpad = NULL;
-       GstCaps* caps = NULL;
-       GstElement* new_element = NULL;
-       GstStructure* str = NULL;
-       const gchar* name = NULL;
-
-       mm_player_t* player = (mm_player_t*) data;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_IF_FAIL(element && pad);
-       MMPLAYER_RETURN_IF_FAIL(player &&
-                                       player->pipeline &&
-                                       player->pipeline->mainbin);
-
-
-       /* payload type is recognizable. increase num_dynamic and wait for sinkbin creation.
-        * num_dynamic_pad will decreased after creating a sinkbin.
-        */
-       player->num_dynamic_pad++;
-       LOGD("stream count inc : %d\n", player->num_dynamic_pad);
-
-       caps = gst_pad_query_caps(pad, NULL);
-
-       MMPLAYER_CHECK_NULL(caps);
-
-       /* clear  previous result*/
-       player->have_dynamic_pad = FALSE;
-
-       str = gst_caps_get_structure(caps, 0);
-
-       if (!str) {
-               LOGE("cannot get structure from caps.\n");
-               goto ERROR;
-       }
-
-       name = gst_structure_get_name(str);
-       if (!name) {
-               LOGE("cannot get mimetype from structure.\n");
-               goto ERROR;
-       }
-
-       if (strstr(name, "video")) {
-               gint stype = 0;
-               mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype);
-
-               if (stype == MM_DISPLAY_SURFACE_NULL || stype == MM_DISPLAY_SURFACE_REMOTE) {
-                       if (player->v_stream_caps) {
-                               gst_caps_unref(player->v_stream_caps);
-                               player->v_stream_caps = NULL;
-                       }
-
-                       new_element = gst_element_factory_make("fakesink", NULL);
-                       player->num_dynamic_pad--;
-                       goto NEW_ELEMENT;
-               }
-       }
-
-       /* clear  previous result*/
-       player->have_dynamic_pad = FALSE;
-
-       if (!__mmplayer_try_to_plug_decodebin(player, pad, caps)) {
-               LOGE("failed to autoplug for caps");
-               goto ERROR;
-       }
-
-       /* check if there's dynamic pad*/
-       if (player->have_dynamic_pad) {
-               LOGE("using pad caps assums there's no dynamic pad !\n");
-               goto ERROR;
-       }
-
-       gst_caps_unref(caps);
-       caps = NULL;
-
-NEW_ELEMENT:
-
-       /* excute new_element if created*/
-       if (new_element) {
-               LOGD("adding new element to pipeline\n");
-
-               /* set state to READY before add to bin */
-               MMPLAYER_ELEMENT_SET_STATE(new_element, GST_STATE_READY);
-
-               /* add new element to the pipeline */
-               if (FALSE == gst_bin_add(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), new_element)) {
-                       LOGE("failed to add autoplug element to bin\n");
-                       goto ERROR;
-               }
-
-               /* get pad from element */
-               sinkpad = gst_element_get_static_pad(GST_ELEMENT(new_element), "sink");
-               if (!sinkpad) {
-                       LOGE("failed to get sinkpad from autoplug element\n");
-                       goto ERROR;
-               }
-
-               /* link it */
-               if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
-                       LOGE("failed to link autoplug element\n");
-                       goto ERROR;
-               }
-
-               gst_object_unref(sinkpad);
-               sinkpad = NULL;
-
-               /* run. setting PLAYING here since streamming source is live source */
-               MMPLAYER_ELEMENT_SET_STATE(new_element, GST_STATE_PLAYING);
-       }
-
-       if (caps)
-               gst_caps_unref(caps);
-
-       MMPLAYER_FLEAVE();
-
-       return;
-
-STATE_CHANGE_FAILED:
-ERROR:
-       /* FIXIT : take care if new_element has already added to pipeline */
-       if (new_element)
-               gst_object_unref(GST_OBJECT(new_element));
-
-       if (sinkpad)
-               gst_object_unref(GST_OBJECT(sinkpad));
-
-       if (caps)
-               gst_caps_unref(caps);
-
-       /* FIXIT : how to inform this error to MSL ????? */
-       /* FIXIT : I think we'd better to use g_idle_add() to destroy pipeline and
-        * then post an error to application
-        */
-}
-
 static GstPadProbeReturn
 __mmplayer_gst_selector_blocked(GstPad* pad, GstPadProbeInfo *info, gpointer data)
 {
@@ -1443,7 +1184,7 @@ ERROR:
        return ret;
 }
 
-static void
+void
 __mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
 {
        mm_player_t* player = NULL;
@@ -1543,21 +1284,21 @@ __mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                        }
 
                        if (stype == MM_DISPLAY_SURFACE_REMOTE) {
-                               MMPLAYER_SIGNAL_CONNECT(player, sinkpad, MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
-                                               "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), player);
+                               __mmplayer_add_signal_connection(player, G_OBJECT(sinkpad), MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                                               "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), (gpointer)player);
                        }
 
                        if (player->set_mode.media_packet_video_stream) {
                                g_object_set(G_OBJECT(fakesink), "signal-handoffs", TRUE, NULL);
 
-                               MMPLAYER_SIGNAL_CONNECT(player,
+                               __mmplayer_add_signal_connection(player,
                                                                                G_OBJECT(fakesink),
                                                                                MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
                                                                                "handoff",
                                                                                G_CALLBACK(__mmplayer_video_stream_decoded_render_cb),
                                                                                (gpointer)player);
 
-                               MMPLAYER_SIGNAL_CONNECT(player,
+                               __mmplayer_add_signal_connection(player,
                                                                                G_OBJECT(fakesink),
                                                                                MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
                                                                                "preroll-handoff",
@@ -1675,7 +1416,7 @@ __mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                g_object_set(selector, "active-pad", sinkpad, NULL);
        }
 
-       _mmplayer_track_update_info(player, stream_type, sinkpad);
+       __mmplayer_track_update_info(player, stream_type, sinkpad);
 
 
 DONE:
@@ -2004,11 +1745,11 @@ __mmplayer_gst_build_deinterleave_path(GstElement *elem, GstPad *pad, gpointer d
 
        g_object_set(deinterleave, "keep-positions", TRUE, NULL);
 
-       MMPLAYER_SIGNAL_CONNECT(player, deinterleave, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
-                                                       G_CALLBACK(__mmplayer_gst_deinterleave_pad_added), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(deinterleave), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
+                                                       G_CALLBACK(__mmplayer_gst_deinterleave_pad_added), (gpointer)player);
 
-       MMPLAYER_SIGNAL_CONNECT(player, deinterleave, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
-                                                       G_CALLBACK(__mmplayer_gst_deinterleave_no_more_pads), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(deinterleave), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
+                                                       G_CALLBACK(__mmplayer_gst_deinterleave_no_more_pads), (gpointer)player);
 
        player->pipeline->mainbin[MMPLAYER_M_A_DEINTERLEAVE].id = MMPLAYER_M_A_DEINTERLEAVE;
        player->pipeline->mainbin[MMPLAYER_M_A_DEINTERLEAVE].gst = deinterleave;
@@ -3021,7 +2762,7 @@ _mmplayer_get_audio_only(MMHandleType hplayer, bool *paudio_only)
        return MM_ERROR_NONE;
 }
 
-static int
+int
 __mmplayer_gst_element_link_bucket(GList* element_bucket)
 {
        GList* bucket = element_bucket;
@@ -3040,13 +2781,6 @@ __mmplayer_gst_element_link_bucket(GList* element_bucket)
                element = (MMPlayerGstElement*)bucket->data;
 
                if (element && element->gst) {
-                       /* If next element is audio appsrc then make a separate audio pipeline */
-                       if (!strcmp(GST_ELEMENT_NAME(GST_ELEMENT(element->gst)), "audio_appsrc") ||
-                               !strcmp(GST_ELEMENT_NAME(GST_ELEMENT(element->gst)), "subtitle_appsrc")) {
-                               prv_element = element;
-                               continue;
-                       }
-
                        if (prv_element && prv_element->gst) {
                                if (gst_element_link(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst))) {
                                        LOGD("linking [%s] to [%s] success\n",
@@ -3070,7 +2804,7 @@ __mmplayer_gst_element_link_bucket(GList* element_bucket)
        return successful_link_count;
 }
 
-static int
+int
 __mmplayer_gst_element_add_bucket_to_bin(GstBin* bin, GList* element_bucket)
 {
        GList* bucket = element_bucket;
@@ -3388,7 +3122,7 @@ __mmplayer_gst_audio_deinterleave_pad_added(GstElement *elem, GstPad *pad, gpoin
        gst_element_set_state(sink, GST_STATE_PAUSED);
        gst_element_set_state(queue, GST_STATE_PAUSED);
 
-       MMPLAYER_SIGNAL_CONNECT(player,
+       __mmplayer_add_signal_connection(player,
                G_OBJECT(sink),
                MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
                "handoff",
@@ -3562,10 +3296,8 @@ __mmplayer_gst_create_audio_pipeline(mm_player_t* player)
 
                        g_object_set(G_OBJECT(audiobin[MMPLAYER_A_DEINTERLEAVE].gst), "keep-positions", TRUE, NULL);
                        /* raw pad handling signal */
-                       MMPLAYER_SIGNAL_CONNECT(player,
-                               (audiobin[MMPLAYER_A_DEINTERLEAVE].gst),
-                               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
-                                                                                               G_CALLBACK(__mmplayer_gst_audio_deinterleave_pad_added), player);
+                       __mmplayer_add_signal_connection(player, G_OBJECT(audiobin[MMPLAYER_A_DEINTERLEAVE].gst),
+                               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added", G_CALLBACK(__mmplayer_gst_audio_deinterleave_pad_added), (gpointer)player);
                } else {
                        int dst_samplerate = 0;
                        int dst_channels = 0;
@@ -3732,8 +3464,8 @@ __mmplayer_gst_create_audio_pipeline(mm_player_t* player)
        if (audiobin[MMPLAYER_A_SINK].gst) {
                GstPad *sink_pad = NULL;
                sink_pad = gst_element_get_static_pad(audiobin[MMPLAYER_A_SINK].gst, "sink");
-               MMPLAYER_SIGNAL_CONNECT(player, sink_pad, MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
-                                       "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), player);
+               __mmplayer_add_signal_connection(player, G_OBJECT(sink_pad), MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
+                                       "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), (gpointer)player);
                gst_object_unref(GST_OBJECT(sink_pad));
        }
 
@@ -4428,14 +4160,14 @@ __mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDispl
                        if (enable)
                                g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "signal-handoffs", TRUE, NULL);
 
-                       MMPLAYER_SIGNAL_CONNECT(player,
+                       __mmplayer_add_signal_connection(player,
                                                                        G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
                                                                        MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
                                                                        "handoff",
                                                                        G_CALLBACK(__mmplayer_video_stream_decoded_render_cb),
                                                                        (gpointer)player);
 
-                       MMPLAYER_SIGNAL_CONNECT(player,
+                       __mmplayer_add_signal_connection(player,
                                                                        G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
                                                                        MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
                                                                        "preroll-handoff",
@@ -4451,14 +4183,14 @@ __mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDispl
                        g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
                                                                                        "sync", TRUE, "signal-handoffs", TRUE, NULL);
 
-                       MMPLAYER_SIGNAL_CONNECT(player,
+                       __mmplayer_add_signal_connection(player,
                                                                        G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
                                                                        MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
                                                                        "handoff",
                                                                        G_CALLBACK(__mmplayer_video_stream_decoded_render_cb),
                                                                        (gpointer)player);
 
-                       MMPLAYER_SIGNAL_CONNECT(player,
+                       __mmplayer_add_signal_connection(player,
                                                                        G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
                                                                        MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
                                                                        "preroll-handoff",
@@ -4488,8 +4220,8 @@ __mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDispl
                GstPad *sink_pad = NULL;
                sink_pad = gst_element_get_static_pad(videobin[MMPLAYER_V_SINK].gst, "sink");
                if (sink_pad) {
-                       MMPLAYER_SIGNAL_CONNECT(player, sink_pad, MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
-                                       "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), player);
+                       __mmplayer_add_signal_connection(player, G_OBJECT(sink_pad), MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                                       "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), (gpointer)player);
                        gst_object_unref(GST_OBJECT(sink_pad));
                } else
                        LOGW("failed to get sink pad from videosink\n");
@@ -4572,7 +4304,7 @@ static int __mmplayer_gst_create_plain_text_elements(mm_player_t* player)
                                                        NULL);
 
        MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_FAKE_SINK, "fakesink", "text_fakesink", TRUE, player);
-       MMPLAYER_SIGNAL_CONNECT(player,
+       __mmplayer_add_signal_connection(player,
                                                        G_OBJECT(textbin[MMPLAYER_T_FAKE_SINK].gst),
                                                        MM_PLAYER_SIGNAL_TYPE_TEXTBIN,
                                                        "handoff",
@@ -4995,7 +4727,7 @@ __mmplayer_subtitle_adjust_position_probe(GstPad *pad, GstPadProbeInfo *info, gp
 
        return GST_PAD_PROBE_OK;
 }
-static int __gst_adjust_subtitle_position(mm_player_t* player, int format, int position)
+static int __mmplayer_gst_adjust_subtitle_position(mm_player_t* player, int format, int position)
 {
        MMPLAYER_FENTER();
 
@@ -5011,847 +4743,115 @@ static int __gst_adjust_subtitle_position(mm_player_t* player, int format, int p
 
        switch (format) {
        case MM_PLAYER_POS_FORMAT_TIME:
-               {
-                       /* check current postion */
-                       player->adjust_subtitle_pos = position;
-
-                       LOGD("save adjust_subtitle_pos in player") ;
-               }
-               break;
-
-       default:
-               {
-                       LOGW("invalid format.\n");
-                       MMPLAYER_FLEAVE();
-                       return MM_ERROR_INVALID_ARGUMENT;
-               }
-       }
-
-       MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
-}
-
-static void
-__gst_appsrc_feed_data_mem(GstElement *element, guint size, gpointer user_data)
-{
-       GstElement *appsrc = element;
-       MMPlayerInputBuffer *buf = (MMPlayerInputBuffer *)user_data;
-       GstBuffer *buffer = NULL;
-       GstFlowReturn ret = GST_FLOW_OK;
-       gint len = size;
-
-       MMPLAYER_RETURN_IF_FAIL(element);
-       MMPLAYER_RETURN_IF_FAIL(buf);
-
-       buffer = gst_buffer_new();
-
-       if (buf->offset >= buf->len) {
-               LOGD("call eos appsrc\n");
-               g_signal_emit_by_name(appsrc, "end-of-stream", &ret);
-               return;
-       }
-
-       if (buf->len - buf->offset < size)
-               len = buf->len - buf->offset;
-
-       gst_buffer_insert_memory(buffer, -1, gst_memory_new_wrapped(0, (guint8 *)(buf->buf + buf->offset), len, 0, len, NULL, NULL));
-       GST_BUFFER_OFFSET(buffer) = (guint64)buf->offset;
-       GST_BUFFER_OFFSET_END(buffer) = (guint64)(buf->offset + len);
-
-       //LOGD("feed buffer %p, offset %u-%u length %u", buffer, buf->offset, (buf->offset+len), len);
-       g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret);
-
-       buf->offset += len;
-}
-
-static gboolean
-__gst_appsrc_seek_data_mem(GstElement *element, guint64 size, gpointer user_data)
-{
-       MMPlayerInputBuffer *buf = (MMPlayerInputBuffer *)user_data;
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(buf, FALSE);
-
-       buf->offset  = (int)size;
-
-       return TRUE;
-}
-
-static gboolean
-__mmplayer_gst_create_decoder(mm_player_t *player,
-                                                               MMPlayerTrackType track,
-                                                               GstPad* srcpad,
-                                                               enum MainElementID elemId,
-                                                               const gchar* name)
-{
-       gboolean ret = TRUE;
-       GstPad *sinkpad = NULL;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player &&
-                                               player->pipeline &&
-                                               player->pipeline->mainbin, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL((track == MM_PLAYER_TRACK_TYPE_AUDIO || track == MM_PLAYER_TRACK_TYPE_VIDEO), FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL(srcpad, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL((player->pipeline->mainbin[elemId].gst == NULL), FALSE);
-
-       GstElement *decodebin = NULL;
-       GstCaps *dec_caps = NULL;
-
-       /* create decodebin */
-       decodebin = gst_element_factory_make("decodebin", name);
-
-       if (!decodebin) {
-               LOGE("error : fail to create decodebin for %d decoder\n", track);
-               ret = FALSE;
-               goto ERROR;
-       }
-
-       /* raw pad handling signal */
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
-                                                                               G_CALLBACK(__mmplayer_gst_decode_pad_added), player);
-
-       /* This signal is emitted whenever decodebin finds a new stream. It is emitted
-       before looking for any elements that can handle that stream.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select",
-                                                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_select), player);
-
-       /* This signal is emitted when a element is added to the bin.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added",
-                                                                               G_CALLBACK(__mmplayer_gst_element_added), player);
-
-       if (!gst_bin_add(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), decodebin)) {
-               LOGE("failed to add new decodebin\n");
-               ret = FALSE;
-               goto ERROR;
-       }
-
-       dec_caps = gst_pad_query_caps(srcpad, NULL);
-       if (dec_caps) {
-               //LOGD("got pad %s:%s , dec_caps %" GST_PTR_FORMAT, GST_DEBUG_PAD_NAME(srcpad), dec_caps);
-               g_object_set(G_OBJECT(decodebin), "sink-caps", dec_caps, NULL);
-               gst_caps_unref(dec_caps);
-       }
-
-       player->pipeline->mainbin[elemId].id = elemId;
-       player->pipeline->mainbin[elemId].gst = decodebin;
-
-       sinkpad = gst_element_get_static_pad(decodebin, "sink");
-
-       if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) {
-               LOGW("failed to link [%s:%s] to decoder\n", GST_DEBUG_PAD_NAME(srcpad));
-               gst_object_unref(GST_OBJECT(decodebin));
-       }
-
-       if (GST_STATE_CHANGE_FAILURE == gst_element_sync_state_with_parent(decodebin))
-               LOGE("failed to sync second level decodebin state with parent\n");
-
-       LOGD("Total num of %d tracks = %d \n", track, player->selector[track].total_track_num);
-
-ERROR:
-       if (sinkpad) {
-               gst_object_unref(GST_OBJECT(sinkpad));
-               sinkpad = NULL;
-       }
-       MMPLAYER_FLEAVE();
-
-       return ret;
-}
-
-/**
- * This function is to create  audio or video pipeline for playing.
- *
- * @param      player          [in]    handle of player
- *
- * @return     This function returns zero on success.
- * @remark
- * @see
- */
-static int
-__mmplayer_gst_create_pipeline(mm_player_t* player)
-{
-       GstBus  *bus = NULL;
-       MMPlayerGstElement *mainbin = NULL;
-       MMHandleType attrs = 0;
-       GstElement* element = NULL;
-       GstElement* elem_src_audio = NULL;
-       GstElement* elem_src_subtitle = NULL;
-       GstElement* es_video_queue = NULL;
-       GstElement* es_audio_queue = NULL;
-       GstElement* es_subtitle_queue = NULL;
-       GList* element_bucket = NULL;
-       gboolean need_state_holder = TRUE;
-       gint i = 0;
-#ifdef SW_CODEC_ONLY
-       int surface_type = 0;
-#endif
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       /* get profile attribute */
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if (!attrs) {
-               LOGE("cannot get content attribute\n");
-               goto INIT_ERROR;
-       }
-
-       /* create pipeline handles */
-       if (player->pipeline) {
-               LOGW("pipeline should be released before create new one\n");
-               goto INIT_ERROR;
-       }
-
-       player->video360_metadata.is_spherical = -1;
-       player->is_openal_plugin_used = FALSE;
-
-       player->pipeline = (MMPlayerGstPipelineInfo*) g_malloc0(sizeof(MMPlayerGstPipelineInfo));
-       if (player->pipeline == NULL)
-               goto INIT_ERROR;
-
-       memset(player->pipeline, 0, sizeof(MMPlayerGstPipelineInfo)); /* g_malloc0 did this job already */
-
-       /* create mainbin */
-       mainbin = (MMPlayerGstElement*) g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM);
-       if (mainbin == NULL)
-               goto INIT_ERROR;
-
-       memset(mainbin, 0, sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM); /* g_malloc0 did this job already */
-
-       /* create pipeline */
-       mainbin[MMPLAYER_M_PIPE].id = MMPLAYER_M_PIPE;
-       mainbin[MMPLAYER_M_PIPE].gst = gst_pipeline_new("player");
-       if (!mainbin[MMPLAYER_M_PIPE].gst) {
-               LOGE("failed to create pipeline\n");
-               goto INIT_ERROR;
-       }
-       player->demux_pad_index = 0;
-       player->subtitle_language_list = NULL;
-
-       player->is_subtitle_force_drop = FALSE;
-       player->last_multiwin_status = FALSE;
-
-       _mmplayer_track_initialize(player);
-       __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
-
-       /* create source element */
-       switch (player->profile.uri_type) {
-       /* rtsp streamming */
-       case MM_PLAYER_URI_TYPE_URL_RTSP:
-               {
-                       gchar *user_agent;
-
-                       element = gst_element_factory_make("rtspsrc", "rtsp source");
-
-                       if (!element) {
-                               LOGE("failed to create streaming source element\n");
-                               break;
-                       }
-
-                       /* make it zero */
-                       user_agent = NULL;
-
-                       /* get attribute */
-                       mm_attrs_get_string_by_name(attrs, "streaming_user_agent", &user_agent);
-
-                       SECURE_LOGD("user_agent : %s\n", user_agent);
-
-                       /* setting property to streaming source */
-                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-                       if (user_agent)
-                               g_object_set(G_OBJECT(element), "user-agent", user_agent, NULL);
-
-                       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(element), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
-                               G_CALLBACK(__mmplayer_gst_rtp_dynamic_pad), player);
-                       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(element), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
-                               G_CALLBACK(__mmplayer_gst_rtp_no_more_pads), player);
-               }
-               break;
-
-       /* http streaming*/
-       case MM_PLAYER_URI_TYPE_URL_HTTP:
-               {
-                       gchar *user_agent, *cookies, **cookie_list;
-                       gint http_timeout = DEFAULT_HTTP_TIMEOUT;
-                       user_agent = cookies = NULL;
-                       cookie_list = NULL;
-                       gint mode = MM_PLAYER_PD_MODE_NONE;
-
-                       mm_attrs_get_int_by_name(attrs, "pd_mode", &mode);
-
-                       player->pd_mode = mode;
-
-                       LOGD("http playback, PD mode : %d\n", player->pd_mode);
-
-                       if (!MMPLAYER_IS_HTTP_PD(player)) {
-                               element = gst_element_factory_make(player->ini.httpsrc_element, "http_streaming_source");
-                               if (!element) {
-                                       LOGE("failed to create http streaming source element[%s].\n", player->ini.httpsrc_element);
-                                       break;
-                               }
-                               LOGD("using http streamming source [%s].\n", player->ini.httpsrc_element);
-
-                               /* get attribute */
-                               mm_attrs_get_string_by_name(attrs, "streaming_cookie", &cookies);
-                               mm_attrs_get_string_by_name(attrs, "streaming_user_agent", &user_agent);
-
-                               if (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT) {
-                                       LOGD("get timeout from ini\n");
-                                       http_timeout = player->ini.http_timeout;
-                               }
-
-                               /* get attribute */
-                               SECURE_LOGD("location : %s\n", player->profile.uri);
-                               SECURE_LOGD("cookies : %s\n", cookies);
-                               SECURE_LOGD("user_agent :  %s\n",  user_agent);
-                               LOGD("timeout : %d\n",  http_timeout);
-
-                               /* setting property to streaming source */
-                               g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-                               g_object_set(G_OBJECT(element), "timeout", http_timeout, NULL);
-                               g_object_set(G_OBJECT(element), "blocksize", (unsigned long)(64*1024), NULL);
-
-                               /* parsing cookies */
-                               if ((cookie_list = util_get_cookie_list((const char*)cookies))) {
-                                       g_object_set(G_OBJECT(element), "cookies", cookie_list, NULL);
-                                       g_strfreev(cookie_list);
-                               }
-                               if (user_agent)
-                                       g_object_set(G_OBJECT(element), "user-agent", user_agent, NULL);
-
-                               if (MMPLAYER_URL_HAS_DASH_SUFFIX(player))
-                                       LOGW("it's dash. and it's still experimental feature.");
-                       } else {
-                               // progressive download
-                               gchar* location = NULL;
-
-                               if (player->pd_mode == MM_PLAYER_PD_MODE_URI) {
-                                       gchar *path = NULL;
-
-                                       mm_attrs_get_string_by_name(attrs, "pd_location", &path);
-
-                                       MMPLAYER_FREEIF(player->pd_file_save_path);
-
-                                       LOGD("PD Location : %s\n", path);
-
-                                       if (path) {
-                                               if (!util_get_storage_info(path, &player->storage_info[MMPLAYER_PATH_VOD])) {
-                                                       LOGE("failed to get storage info");
-                                                       break;
-                                               }
-                                               player->pd_file_save_path = g_strdup(path);
-                                       } else {
-                                               LOGE("can't find pd location so, it should be set \n");
-                                               break;
-                                       }
-                               }
-
-                               element = gst_element_factory_make("pdpushsrc", "PD pushsrc");
-                               if (!element) {
-                                       LOGE("failed to create PD push source element[%s].\n", "pdpushsrc");
-                                       break;
-                               }
-
-                               if (player->pd_mode == MM_PLAYER_PD_MODE_URI)
-                                       g_object_set(G_OBJECT(element), "location", player->pd_file_save_path, NULL);
-                               else
-                                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-                               g_object_get(element, "location", &location, NULL);
-                               LOGD("PD_LOCATION [%s].\n", location);
-                               if (location)
-                                       g_free(location);
-                       }
-               }
-               break;
-
-       /* file source */
-       case MM_PLAYER_URI_TYPE_FILE:
-               {
-                       LOGD("using filesrc for 'file://' handler.\n");
-                       if (!util_get_storage_info(player->profile.uri, &player->storage_info[MMPLAYER_PATH_VOD])) {
-                               LOGE("failed to get storage info");
-                               break;
-                       }
-
-                       element = gst_element_factory_make("filesrc", "source");
-                       if (!element) {
-                               LOGE("failed to create filesrc\n");
-                               break;
-                       }
-
-                       g_object_set(G_OBJECT(element), "location", (player->profile.uri)+7, NULL);     /* uri+7 -> remove "file:// */
-               }
-               break;
-
-       case MM_PLAYER_URI_TYPE_SS:
-               {
-                       gint http_timeout = DEFAULT_HTTP_TIMEOUT;
-                       element = gst_element_factory_make("souphttpsrc", "http streaming source");
-                       if (!element) {
-                               LOGE("failed to create http streaming source element[%s]", player->ini.httpsrc_element);
-                               break;
-                       }
-
-                       if (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT) {
-                               LOGD("get timeout from ini\n");
-                               http_timeout = player->ini.http_timeout;
-                       }
-
-                       /* setting property to streaming source */
-                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-                       g_object_set(G_OBJECT(element), "timeout", http_timeout, NULL);
-               }
-               break;
-       case MM_PLAYER_URI_TYPE_MS_BUFF:
-               {
-                       LOGD("MS buff src is selected\n");
-
-                       if (player->v_stream_caps) {
-                               element = gst_element_factory_make("appsrc", "video_appsrc");
-                               if (!element) {
-                                       LOGF("failed to create video app source element[appsrc].\n");
-                                       break;
-                               }
-
-                               if (player->a_stream_caps) {
-                                       elem_src_audio = gst_element_factory_make("appsrc", "audio_appsrc");
-                                       if (!elem_src_audio) {
-                                               LOGF("failed to create audio app source element[appsrc].\n");
-                                               break;
-                                       }
-                               }
-                       } else if (player->a_stream_caps) {
-                               /* no video, only audio pipeline*/
-                               element = gst_element_factory_make("appsrc", "audio_appsrc");
-                               if (!element) {
-                                       LOGF("failed to create audio app source element[appsrc].\n");
-                                       break;
-                               }
-                       }
-
-                       if (player->s_stream_caps) {
-                               elem_src_subtitle = gst_element_factory_make("appsrc", "subtitle_appsrc");
-                               if (!elem_src_subtitle) {
-                                       LOGF("failed to create subtitle app source element[appsrc].\n");
-                                       break;
-                               }
-                       }
-
-                       LOGD("setting app sources properties.\n");
-                       LOGD("location : %s\n", player->profile.uri);
-
-                       if (player->v_stream_caps && element) {
-                               g_object_set(G_OBJECT(element), "format", GST_FORMAT_TIME,
-                                                                                           "blocksize", (guint)1048576,        /* size of many video frames are larger than default blocksize as 4096 */
-                                                                                               "caps", player->v_stream_caps, NULL);
-
-                               if (player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_VIDEO] > 0)
-                                       g_object_set(G_OBJECT(element), "max-bytes", player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_VIDEO], NULL);
-                               if (player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_VIDEO] > 0)
-                                       g_object_set(G_OBJECT(element), "min-percent", player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_VIDEO], NULL);
-
-                               /*Fix Seek External Demuxer:  set audio and video appsrc as seekable */
-                               gst_app_src_set_stream_type((GstAppSrc*)G_OBJECT(element), GST_APP_STREAM_TYPE_SEEKABLE);
-                               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
-                                                                                                               G_CALLBACK(__gst_seek_video_data), player);
-
-                               if (player->a_stream_caps && elem_src_audio) {
-                                       g_object_set(G_OBJECT(elem_src_audio), "format", GST_FORMAT_TIME,
-                                                                                                                       "caps", player->a_stream_caps, NULL);
-
-                                       if (player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_AUDIO] > 0)
-                                               g_object_set(G_OBJECT(elem_src_audio), "max-bytes", player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_AUDIO], NULL);
-                                       if (player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_AUDIO] > 0)
-                                               g_object_set(G_OBJECT(elem_src_audio), "min-percent", player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_AUDIO], NULL);
-
-                                       /*Fix Seek External Demuxer:  set audio and video appsrc as seekable */
-                                       gst_app_src_set_stream_type((GstAppSrc*)G_OBJECT(elem_src_audio), GST_APP_STREAM_TYPE_SEEKABLE);
-                                       MMPLAYER_SIGNAL_CONNECT(player, elem_src_audio, MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
-                                                                                                               G_CALLBACK(__gst_seek_audio_data), player);
-                               }
-                       } else if (player->a_stream_caps && element) {
-                               g_object_set(G_OBJECT(element), "format", GST_FORMAT_TIME,
-                                                                                               "caps", player->a_stream_caps, NULL);
-
-                               if (player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_AUDIO] > 0)
-                                       g_object_set(G_OBJECT(element), "max-bytes", player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_AUDIO], NULL);
-                               if (player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_AUDIO] > 0)
-                                       g_object_set(G_OBJECT(element), "min-percent", player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_AUDIO], NULL);
-
-                               /*Fix Seek External Demuxer:  set audio and video appsrc as seekable */
-                               gst_app_src_set_stream_type((GstAppSrc*)G_OBJECT(element), GST_APP_STREAM_TYPE_SEEKABLE);
-                               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
-                                                                                                                       G_CALLBACK(__gst_seek_audio_data), player);
-                       }
-
-                       if (player->s_stream_caps && elem_src_subtitle) {
-                               g_object_set(G_OBJECT(elem_src_subtitle), "format", GST_FORMAT_TIME,
-                                                                                                                "caps", player->s_stream_caps, NULL);
-
-                               if (player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_TEXT] > 0)
-                                       g_object_set(G_OBJECT(elem_src_subtitle), "max-bytes", player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_TEXT], NULL);
-                               if (player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_TEXT] > 0)
-                                       g_object_set(G_OBJECT(elem_src_subtitle), "min-percent", player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_TEXT], NULL);
-
-                               gst_app_src_set_stream_type((GstAppSrc*)G_OBJECT(elem_src_subtitle), GST_APP_STREAM_TYPE_SEEKABLE);
-
-                               MMPLAYER_SIGNAL_CONNECT(player, elem_src_subtitle, MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
-                                                                                                                               G_CALLBACK(__gst_seek_subtitle_data), player);
-                       }
-
-                       if (player->v_stream_caps && element) {
-                               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_feed_video_data), player);
-                               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "enough-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_enough_video_data), player);
-
-                               if (player->a_stream_caps && elem_src_audio) {
-                                       MMPLAYER_SIGNAL_CONNECT(player, elem_src_audio, MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_feed_audio_data), player);
-                                       MMPLAYER_SIGNAL_CONNECT(player, elem_src_audio, MM_PLAYER_SIGNAL_TYPE_OTHERS, "enough-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_enough_audio_data), player);
-                               }
-                       } else if (player->a_stream_caps && element) {
-                               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_feed_audio_data), player);
-                               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "enough-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_enough_audio_data), player);
-                       }
-
-                       if (player->s_stream_caps && elem_src_subtitle)
-                               MMPLAYER_SIGNAL_CONNECT(player, elem_src_subtitle, MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_feed_subtitle_data), player);
-
-                       need_state_holder = FALSE;
-
-                       mm_attrs_set_int_by_name(attrs, "profile_prepare_async", TRUE);
-                       if (mmf_attrs_commit(attrs)) /* return -1 if error */
-                               LOGE("failed to commit\n");
-               }
-               break;
-       /* appsrc */
-       case MM_PLAYER_URI_TYPE_MEM:
-               {
-                       guint64 stream_type = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
-
-                       LOGD("mem src is selected\n");
-
-                       element = gst_element_factory_make("appsrc", "mem-source");
-                       if (!element) {
-                               LOGE("failed to create appsrc element\n");
-                               break;
-                       }
-
-                       g_object_set(element, "stream-type", stream_type, NULL);
-                       g_object_set(element, "size", player->profile.input_mem.len, NULL);
-                       g_object_set(element, "blocksize", (guint64)20480, NULL);
-
-                       MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
-                               G_CALLBACK(__gst_appsrc_seek_data_mem), &player->profile.input_mem);
-                       MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
-                               G_CALLBACK(__gst_appsrc_feed_data_mem), &player->profile.input_mem);
-               }
-               break;
-       case MM_PLAYER_URI_TYPE_URL:
-               break;
-
-       case MM_PLAYER_URI_TYPE_TEMP:
-               break;
-
-       case MM_PLAYER_URI_TYPE_NONE:
-       default:
-               break;
-       }
-
-       /* check source element is OK */
-       if (!element) {
-               LOGE("no source element was created.\n");
-               goto INIT_ERROR;
-       }
-
-       /* take source element */
-       mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC;
-       mainbin[MMPLAYER_M_SRC].gst = element;
-       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_SRC]);
-
-       if ((MMPLAYER_IS_STREAMING(player)) && (player->streamer == NULL)) {
-               player->streamer = __mm_player_streaming_create();
-               __mm_player_streaming_initialize(player->streamer);
-       }
-
-       if (MMPLAYER_IS_HTTP_PD(player)) {
-               gint pre_buffering_time = player->streamer->buffering_req.prebuffer_time;
-
-               LOGD("Picked queue2 element(pre buffer : %d ms)....\n", pre_buffering_time);
-               element = gst_element_factory_make("queue2", "queue2");
-               if (!element) {
-                       LOGE("failed to create http streaming buffer element\n");
-                       goto INIT_ERROR;
-               }
-
-               /* take it */
-               mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER;
-               mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = element;
-               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_MUXED_S_BUFFER]);
-
-               pre_buffering_time = (pre_buffering_time > 0) ? (pre_buffering_time) : (player->ini.http_buffering_time);
-
-               player->streamer->is_pd_mode = TRUE;
-
-               __mm_player_streaming_set_queue2(player->streamer,
-                               element,
-                               TRUE,
-                               player->ini.http_max_size_bytes, // + PLAYER_PD_EXT_MAX_SIZE_BYTE,
-                               pre_buffering_time,
-                               1.0,
-                               player->ini.http_buffering_limit,
-                               MUXED_BUFFER_TYPE_MEM_QUEUE,
-                               NULL,
-                               0);
-       }
-       if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
-               if (player->v_stream_caps) {
-                       es_video_queue = gst_element_factory_make("queue2", "video_queue");
-                       if (!es_video_queue) {
-                               LOGE("create es_video_queue for es player failed\n");
-                               goto INIT_ERROR;
-                       }
-                       g_object_set(G_OBJECT(es_video_queue), "max-size-buffers", 2, NULL);
-                       mainbin[MMPLAYER_M_V_BUFFER].id = MMPLAYER_M_V_BUFFER;
-                       mainbin[MMPLAYER_M_V_BUFFER].gst = es_video_queue;
-                       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_V_BUFFER]);
-
-                       /* Adding audio appsrc to bucket */
-                       if (player->a_stream_caps && elem_src_audio) {
-                               mainbin[MMPLAYER_M_2ND_SRC].id = MMPLAYER_M_2ND_SRC;
-                               mainbin[MMPLAYER_M_2ND_SRC].gst = elem_src_audio;
-                               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_2ND_SRC]);
-
-                               es_audio_queue = gst_element_factory_make("queue2", "audio_queue");
-                               if (!es_audio_queue) {
-                                       LOGE("create es_audio_queue for es player failed\n");
-                                       goto INIT_ERROR;
-                               }
-                               g_object_set(G_OBJECT(es_audio_queue), "max-size-buffers", 2, NULL);
+               {
+                       /* check current postion */
+                       player->adjust_subtitle_pos = position;
 
-                               mainbin[MMPLAYER_M_A_BUFFER].id = MMPLAYER_M_A_BUFFER;
-                               mainbin[MMPLAYER_M_A_BUFFER].gst = es_audio_queue;
-                               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_A_BUFFER]);
-                       }
-               } else if (player->a_stream_caps) {
-                       /* Only audio stream, no video */
-                       es_audio_queue = gst_element_factory_make("queue2", "audio_queue");
-                       if (!es_audio_queue) {
-                               LOGE("create es_audio_queue for es player failed\n");
-                               goto INIT_ERROR;
-                       }
-                       mainbin[MMPLAYER_M_A_BUFFER].id = MMPLAYER_M_A_BUFFER;
-                       mainbin[MMPLAYER_M_A_BUFFER].gst = es_audio_queue;
-                       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_A_BUFFER]);
+                       LOGD("save adjust_subtitle_pos in player") ;
                }
+               break;
 
-               if (player->s_stream_caps && elem_src_subtitle) {
-                       mainbin[MMPLAYER_M_SUBSRC].id = MMPLAYER_M_SUBSRC;
-                       mainbin[MMPLAYER_M_SUBSRC].gst = elem_src_subtitle;
-                       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_SUBSRC]);
-
-                       es_subtitle_queue = gst_element_factory_make("queue2", "subtitle_queue");
-                       if (!es_subtitle_queue) {
-                               LOGE("create es_subtitle_queue for es player failed\n");
-                               goto INIT_ERROR;
-                       }
-                       mainbin[MMPLAYER_M_S_BUFFER].id = MMPLAYER_M_V_BUFFER;
-                       mainbin[MMPLAYER_M_S_BUFFER].gst = es_subtitle_queue;
-                       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_S_BUFFER]);
+       default:
+               {
+                       LOGW("invalid format.\n");
+                       MMPLAYER_FLEAVE();
+                       return MM_ERROR_INVALID_ARGUMENT;
                }
        }
 
-       /* create autoplugging element if src element is not a rtsp src */
-       if ((player->profile.uri_type != MM_PLAYER_URI_TYPE_URL_RTSP) &&
-               (player->profile.uri_type != MM_PLAYER_URI_TYPE_MS_BUFF)) {
-               element = NULL;
-               enum MainElementID elemId = MMPLAYER_M_NUM;
-
-               if (((MMPLAYER_IS_HTTP_PD(player)) ||
-                       (!MMPLAYER_IS_HTTP_STREAMING(player)))) {
-                       elemId = MMPLAYER_M_AUTOPLUG;
-                       element = __mmplayer_create_decodebin(player);
-                       if (element) {
-                               /* default size of mq in decodebin is 2M
-                                * but it can cause blocking issue during seeking depends on content. */
-                               g_object_set(G_OBJECT(element), "max-size-bytes", (5*1024*1024), NULL);
-                       }
-                       need_state_holder = FALSE;
-               } else {
-                       elemId = MMPLAYER_M_TYPEFIND;
-                       element = gst_element_factory_make("typefind", "typefinder");
-                       MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type",
-                               G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player);
-               }
+       MMPLAYER_FLEAVE();
 
-               /* check autoplug element is OK */
-               if (!element) {
-                       LOGE("can not create element(%d)\n", elemId);
-                       goto INIT_ERROR;
-               }
+       return MM_ERROR_NONE;
+}
 
-               mainbin[elemId].id = elemId;
-               mainbin[elemId].gst = element;
+/**
+ * This function is to create  audio or video pipeline for playing.
+ *
+ * @param      player          [in]    handle of player
+ *
+ * @return     This function returns zero on success.
+ * @remark
+ * @see
+ */
+static int
+__mmplayer_gst_create_pipeline(mm_player_t* player)
+{
+       int ret = MM_ERROR_NONE;
+       MMPlayerGstElement *mainbin = NULL;
+       MMHandleType attrs = 0;
+       gint mode = MM_PLAYER_PD_MODE_NONE;
 
-               element_bucket = g_list_append(element_bucket, &mainbin[elemId]);
-       }
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       /* add elements to pipeline */
-       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element_bucket)) {
-               LOGE("Failed to add elements to pipeline\n");
+       /* get profile attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if (!attrs) {
+               LOGE("failed to get content attribute");
                goto INIT_ERROR;
        }
 
-
-       /* linking elements in the bucket by added order. */
-       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1) {
-               LOGE("Failed to link some elements\n");
+       /* create pipeline handles */
+       if (player->pipeline) {
+               LOGE("pipeline should be released before create new one");
                goto INIT_ERROR;
        }
 
+       player->pipeline = (MMPlayerGstPipelineInfo*) g_malloc0(sizeof(MMPlayerGstPipelineInfo));
+       if (player->pipeline == NULL)
+               goto INIT_ERROR;
 
-       /* create fakesink element for keeping the pipeline state PAUSED. if needed */
-       if (need_state_holder) {
-               /* create */
-               mainbin[MMPLAYER_M_SRC_FAKESINK].id = MMPLAYER_M_SRC_FAKESINK;
-               mainbin[MMPLAYER_M_SRC_FAKESINK].gst = gst_element_factory_make("fakesink", "state-holder");
-
-               if (!mainbin[MMPLAYER_M_SRC_FAKESINK].gst) {
-                       LOGE("fakesink element could not be created\n");
-                       goto INIT_ERROR;
-               }
-               GST_OBJECT_FLAG_UNSET(mainbin[MMPLAYER_M_SRC_FAKESINK].gst, GST_ELEMENT_FLAG_SINK);
-
-               /* take ownership of fakesink. we are reusing it */
-               gst_object_ref(mainbin[MMPLAYER_M_SRC_FAKESINK].gst);
+       /* create mainbin */
+       mainbin = (MMPlayerGstElement*) g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM);
+       if (mainbin == NULL)
+               goto INIT_ERROR;
 
-               /* add */
-               if (FALSE == gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst),
-                       mainbin[MMPLAYER_M_SRC_FAKESINK].gst)) {
-                       LOGE("failed to add fakesink to bin\n");
-                       goto INIT_ERROR;
-               }
+       /* create pipeline */
+       mainbin[MMPLAYER_M_PIPE].id = MMPLAYER_M_PIPE;
+       mainbin[MMPLAYER_M_PIPE].gst = gst_pipeline_new("player");
+       if (!mainbin[MMPLAYER_M_PIPE].gst) {
+               LOGE("failed to create pipeline");
+               goto INIT_ERROR;
        }
 
-       /* now we have completed mainbin. take it */
        player->pipeline->mainbin = mainbin;
 
-       if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
-               GstPad *srcpad = NULL;
-
-               if (mainbin[MMPLAYER_M_V_BUFFER].gst) {
-                       srcpad = gst_element_get_static_pad(mainbin[MMPLAYER_M_V_BUFFER].gst, "src");
-                       if (srcpad) {
-                               __mmplayer_gst_create_decoder(player,
-                                                                                               MM_PLAYER_TRACK_TYPE_VIDEO,
-                                                                                               srcpad,
-                                                                                               MMPLAYER_M_AUTOPLUG_V_DEC,
-                                                                                               "video_decodebin");
-
-                               gst_object_unref(GST_OBJECT(srcpad));
-                               srcpad = NULL;
-                       }
-               }
-
-               if ((player->a_stream_caps) && (mainbin[MMPLAYER_M_A_BUFFER].gst)) {
-                       srcpad = gst_element_get_static_pad(mainbin[MMPLAYER_M_A_BUFFER].gst, "src");
-                       if (srcpad) {
-                               __mmplayer_gst_create_decoder(player,
-                                                                                               MM_PLAYER_TRACK_TYPE_AUDIO,
-                                                                                               srcpad,
-                                                                                               MMPLAYER_M_AUTOPLUG_A_DEC,
-                                                                                               "audio_decodebin");
-
-                               gst_object_unref(GST_OBJECT(srcpad));
-                               srcpad = NULL;
-                       } // else error
-               } //  else error
-
-               if (mainbin[MMPLAYER_M_S_BUFFER].gst)
-                       __mmplayer_try_to_plug_decodebin(player, gst_element_get_static_pad(mainbin[MMPLAYER_M_S_BUFFER].gst, "src"), player->s_stream_caps);
-       }
+       /* check pd mode */
+       mm_attrs_get_int_by_name(attrs, "pd_mode", &mode);
+       player->pd_mode = mode;
 
-       /* Note : check whether subtitle atrribute uri is set. If uri is set, then try to play subtitle file */
-       if (__mmplayer_check_subtitle(player)) {
-               if (MM_ERROR_NONE != __mmplayer_gst_create_text_pipeline(player))
-                       LOGE("fail to create text pipeline");
+       /* create the source and decoder elements */
+       if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
+               ret = __mmplayer_gst_build_es_pipeline(player);
+       } else if (MMPLAYER_IS_HTTP_STREAMING(player) && MMPLAYER_IS_HTTP_PD(player)) {
+               ret = __mmplayer_gst_build_pd_pipeline(player);
+       } else {
+               ret = __mmplayer_gst_build_pipeline(player);
        }
 
-       /* connect bus callback */
-       bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[MMPLAYER_M_PIPE].gst));
-       if (!bus) {
-               LOGE("cannot get bus from pipeline.\n");
+       if (ret != MM_ERROR_NONE) {
+               LOGE("failed to create some elements");
                goto INIT_ERROR;
        }
 
-       player->bus_watcher = gst_bus_add_watch(bus, (GstBusFunc)__mmplayer_gst_msg_push, player);
-
-       player->context.thread_default = g_main_context_get_thread_default();
-
-       if (player->context.thread_default == NULL) {
-               player->context.thread_default = g_main_context_default();
-               LOGD("thread-default context is the global default context");
+       /* Note : check whether subtitle atrribute uri is set. If uri is set, then try to play subtitle file */
+       if (__mmplayer_check_subtitle(player)) {
+               if (__mmplayer_gst_create_text_pipeline(player) != MM_ERROR_NONE)
+                       LOGE("failed to create text pipeline");
        }
-       LOGW("bus watcher thread context = %p, watcher : %d", player->context.thread_default, player->bus_watcher);
-
-       /* set sync handler to get tag synchronously */
-       gst_bus_set_sync_handler(bus, __mmplayer_gst_bus_sync_callback, player, NULL);
-
-       /* finished */
-       gst_object_unref(GST_OBJECT(bus));
-       g_list_free(element_bucket);
 
-       /* create gst bus_msb_cb thread */
-       g_mutex_init(&player->bus_msg_thread_mutex);
-       g_cond_init(&player->bus_msg_thread_cond);
-       player->bus_msg_thread_exit = FALSE;
-       player->bus_msg_thread =
-               g_thread_try_new("gst_bus_msg_thread", __mmplayer_gst_bus_msg_thread, (gpointer)player, NULL);
-       if (!player->bus_msg_thread) {
-               LOGE("failed to create gst BUS msg thread");
-               g_mutex_clear(&player->bus_msg_thread_mutex);
-               g_cond_clear(&player->bus_msg_thread_cond);
+       /* add bus watch */
+       ret = __mmplayer_gst_add_bus_watch(player);
+       if (ret != MM_ERROR_NONE) {
+               LOGE("failed to add bus watch");
                goto INIT_ERROR;
        }
 
        MMPLAYER_FLEAVE();
-
        return MM_ERROR_NONE;
 
 INIT_ERROR:
        __mmplayer_gst_destroy_pipeline(player);
-       g_list_free(element_bucket);
-
-       if (mainbin) {
-               /* release element which are not added to bin */
-               for (i = 1; i < MMPLAYER_M_NUM; i++) {
-                       /* NOTE : skip pipeline */
-                       if (mainbin[i].gst) {
-                               GstObject* parent = NULL;
-                               parent = gst_element_get_parent(mainbin[i].gst);
-
-                               if (!parent) {
-                                       gst_object_unref(GST_OBJECT(mainbin[i].gst));
-                                       mainbin[i].gst = NULL;
-                               } else
-                                       gst_object_unref(GST_OBJECT(parent));
-                       }
-               }
-
-               /* release pipeline with it's childs */
-               if (mainbin[MMPLAYER_M_PIPE].gst)
-                       gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
-
-               MMPLAYER_FREEIF(mainbin);
-       }
-
-       MMPLAYER_FREEIF(player->pipeline);
        return MM_ERROR_PLAYER_INTERNAL;
 }
 
@@ -5973,7 +4973,7 @@ __mmplayer_gst_destroy_pipeline(mm_player_t* player)
                gst_caps_unref(player->s_stream_caps);
                player->s_stream_caps = NULL;
        }
-       _mmplayer_track_destroy(player);
+       __mmplayer_track_destroy(player);
 
        if (player->sink_elements)
                g_list_free(player->sink_elements);
@@ -5991,7 +4991,7 @@ __mmplayer_gst_destroy_pipeline(mm_player_t* player)
        return ret;
 }
 
-static int __gst_realize(mm_player_t* player)
+static int __mmplayer_gst_realize(mm_player_t* player)
 {
        gint timeout = 0;
        int ret = MM_ERROR_NONE;
@@ -6030,7 +5030,7 @@ static int __gst_realize(mm_player_t* player)
        return ret;
 }
 
-static int __gst_unrealize(mm_player_t* player)
+static int __mmplayer_gst_unrealize(mm_player_t* player)
 {
        int ret = MM_ERROR_NONE;
 
@@ -6063,7 +5063,7 @@ static int __gst_unrealize(mm_player_t* player)
 }
 
 static int
-__gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param)
+__mmplayer_gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param)
 {
        MMPLAYER_FENTER();
 
@@ -6880,11 +5880,24 @@ _mmplayer_realize(MMHandleType hplayer)
        player->textsink_linked = 0;
        player->is_external_subtitle_present = FALSE;
        player->is_external_subtitle_added_now = FALSE;
-       /* set the subtitle ON default */
-       player->is_subtitle_off = FALSE;
+       player->is_subtitle_off = FALSE; /* set the subtitle ON default */
+       player->video360_metadata.is_spherical = -1;
+       player->is_openal_plugin_used = FALSE;
+       player->demux_pad_index = 0;
+       player->subtitle_language_list = NULL;
+       player->is_subtitle_force_drop = FALSE;
+       player->last_multiwin_status = FALSE;
+
+       __mmplayer_track_initialize(player);
+       __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
+
+       if ((MMPLAYER_IS_STREAMING(player)) && (player->streamer == NULL)) {
+               player->streamer = __mm_player_streaming_create();
+               __mm_player_streaming_initialize(player->streamer);
+       }
 
        /* realize pipeline */
-       ret = __gst_realize(player);
+       ret = __mmplayer_gst_realize(player);
        if (ret != MM_ERROR_NONE)
                LOGE("fail to realize the player.\n");
        else
@@ -6936,7 +5949,7 @@ _mmplayer_unrealize(MMHandleType hplayer)
        __mmplayer_unrealize_streaming_ext(player);
 
        /* unrealize pipeline */
-       ret = __gst_unrealize(player);
+       ret = __mmplayer_gst_unrealize(player);
 
        /* set asm stop if success */
        if (MM_ERROR_NONE == ret) {
@@ -6978,7 +5991,7 @@ _mmplayer_set_message_callback(MMHandleType hplayer, MMMessageCallback callback,
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       return __gst_set_message_callback(player, callback, user_param);
+       return __mmplayer_gst_set_message_callback(player, callback, user_param);
 }
 
 int
@@ -7722,7 +6735,7 @@ _mmplayer_adjust_subtitle_postion(MMHandleType hplayer, int format, int position
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       ret = __gst_adjust_subtitle_position(player, format, position);
+       ret = __mmplayer_gst_adjust_subtitle_position(player, format, position);
 
        MMPLAYER_FLEAVE();
 
@@ -7807,7 +6820,7 @@ __mmplayer_update_content_type_info(mm_player_t* player)
        MMPLAYER_FLEAVE();
 }
 
-static void
+void
 __mmplayer_typefind_have_type(GstElement *tf, guint probability,
 GstCaps *caps, gpointer data)
 {
@@ -7871,7 +6884,7 @@ DONE:
        return;
 }
 
-static GstElement *
+GstElement *
 __mmplayer_create_decodebin(mm_player_t* player)
 {
        GstElement *decodebin = NULL;
@@ -7887,44 +6900,44 @@ __mmplayer_create_decodebin(mm_player_t* player)
        }
 
        /* raw pad handling signal */
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
-                                               G_CALLBACK(__mmplayer_gst_decode_pad_added), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
+                                               G_CALLBACK(__mmplayer_gst_decode_pad_added), (gpointer)player);
 
        /* no-more-pad pad handling signal */
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
-                                               G_CALLBACK(__mmplayer_gst_decode_no_more_pads), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
+                                               G_CALLBACK(__mmplayer_gst_decode_no_more_pads), (gpointer)player);
 
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-removed",
-                                               G_CALLBACK(__mmplayer_gst_decode_pad_removed), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-removed",
+                                               G_CALLBACK(__mmplayer_gst_decode_pad_removed), (gpointer)player);
 
        /* This signal is emitted when a pad for which there is no further possible
           decoding is added to the decodebin.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "unknown-type",
-                                               G_CALLBACK(__mmplayer_gst_decode_unknown_type), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "unknown-type",
+                                               G_CALLBACK(__mmplayer_gst_decode_unknown_type), (gpointer)player);
 
        /* This signal is emitted whenever decodebin finds a new stream. It is emitted
           before looking for any elements that can handle that stream.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue",
-                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_continue), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue",
+                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_continue), (gpointer)player);
 
        /* This signal is emitted whenever decodebin finds a new stream. It is emitted
           before looking for any elements that can handle that stream.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select",
-                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_select), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select",
+                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_select), (gpointer)player);
 
        /* This signal is emitted once decodebin has finished decoding all the data.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "drained",
-                                               G_CALLBACK(__mmplayer_gst_decode_drained), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "drained",
+                                               G_CALLBACK(__mmplayer_gst_decode_drained), (gpointer)player);
 
        /* This signal is emitted when a element is added to the bin.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added",
-                                               G_CALLBACK(__mmplayer_gst_element_added), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added",
+                                               G_CALLBACK(__mmplayer_gst_element_added), (gpointer)player);
 
 ERROR:
        return decodebin;
 }
 
-static gboolean
+gboolean
 __mmplayer_try_to_plug_decodebin(mm_player_t* player, GstPad *srcpad, const GstCaps *caps)
 {
        MMPlayerGstElement* mainbin = NULL;
@@ -8408,7 +7421,7 @@ __mmplayer_initialize_next_play(mm_player_t *player)
        player->total_bitrate = 0;
        player->total_maximum_bitrate = 0;
 
-       _mmplayer_track_initialize(player);
+       __mmplayer_track_initialize(player);
        __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
 
        for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++) {
@@ -8460,10 +7473,8 @@ __mmplayer_activate_next_source(mm_player_t *player, GstState target)
 
        MMPLAYER_FENTER();
 
-       if ((player == NULL) ||
-               (player->pipeline == NULL) ||
-               (player->pipeline->mainbin == NULL)) {
-               LOGE("player is null.\n");
+       if (!player || !player->pipeline || !player->pipeline->mainbin) {
+               LOGE("player is not initialized");
                goto ERROR;
        }
 
@@ -8472,7 +7483,7 @@ __mmplayer_activate_next_source(mm_player_t *player, GstState target)
 
        attrs = MMPLAYER_GET_ATTRS(player);
        if (!attrs) {
-               LOGE("fail to get attributes.\n");
+               LOGE("fail to get attributes");
                goto ERROR;
        }
 
@@ -8482,92 +7493,26 @@ __mmplayer_activate_next_source(mm_player_t *player, GstState target)
        mm_attrs_get_string_by_name(attrs, "profile_uri", &uri);
 
        if (__mmplayer_parse_profile((const char*)uri, NULL, &player->profile) != MM_ERROR_NONE) {
-               LOGE("failed to parse profile\n");
+               LOGE("failed to parse profile");
                msg_param.code = MM_ERROR_PLAYER_INVALID_URI;
                goto ERROR;
        }
 
        if ((MMPLAYER_URL_HAS_DASH_SUFFIX(player)) ||
                (MMPLAYER_URL_HAS_HLS_SUFFIX(player))) {
-               LOGE("it's dash or hls. not support.");
+               LOGE("dash or hls is not supportable");
                msg_param.code = MM_ERROR_PLAYER_INVALID_URI;
                goto ERROR;
        }
 
-       /* setup source */
-       switch (player->profile.uri_type) {
-       /* file source */
-       case MM_PLAYER_URI_TYPE_FILE:
-       {
-               LOGD("using filesrc for 'file://' handler.\n");
-               if (!util_get_storage_info(player->profile.uri, &player->storage_info[MMPLAYER_PATH_VOD])) {
-                       LOGE("failed to get storage info");
-                       break;
-               }
-
-               element = gst_element_factory_make("filesrc", "source");
-
-               if (!element) {
-                       LOGE("failed to create filesrc\n");
-                       break;
-               }
-
-               g_object_set(G_OBJECT(element), "location", (player->profile.uri)+7, NULL);     /* uri+7 -> remove "file:// */
-               break;
-       }
-       case MM_PLAYER_URI_TYPE_URL_HTTP:
-       {
-               gchar *user_agent, *cookies, **cookie_list;
-               gint http_timeout = DEFAULT_HTTP_TIMEOUT;
-               user_agent = cookies = NULL;
-               cookie_list = NULL;
-
-               element = gst_element_factory_make(player->ini.httpsrc_element, "http_streaming_source");
-               if (!element) {
-                       LOGE("failed to create http streaming source element[%s].\n", player->ini.httpsrc_element);
-                       break;
-               }
-               LOGD("using http streamming source [%s].\n", player->ini.httpsrc_element);
-
-               /* get attribute */
-               mm_attrs_get_string_by_name(attrs, "streaming_cookie", &cookies);
-               mm_attrs_get_string_by_name(attrs, "streaming_user_agent", &user_agent);
-
-               if (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT) {
-                       LOGD("get timeout from ini\n");
-                       http_timeout = player->ini.http_timeout;
-               }
-
-               /* get attribute */
-               SECURE_LOGD("location : %s\n", player->profile.uri);
-               SECURE_LOGD("cookies : %s\n", cookies);
-               SECURE_LOGD("user_agent :  %s\n", user_agent);
-               LOGD("timeout : %d\n", http_timeout);
-
-               /* setting property to streaming source */
-               g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-               g_object_set(G_OBJECT(element), "timeout", http_timeout, NULL);
-               g_object_set(G_OBJECT(element), "blocksize", (unsigned long)(64*1024), NULL);
-
-               /* parsing cookies */
-               if ((cookie_list = util_get_cookie_list((const char*)cookies)))
-                       g_object_set(G_OBJECT(element), "cookies", cookie_list, NULL);
-               if (user_agent)
-                       g_object_set(G_OBJECT(element), "user_agent", user_agent, NULL);
-               break;
-       }
-       default:
-               LOGE("not support uri type %d\n", player->profile.uri_type);
-               break;
-       }
-
+       element = __mmplayer_gst_build_source(player);
        if (!element) {
-               LOGE("no source element was created.\n");
+               LOGE("no source element was created");
                goto ERROR;
        }
 
        if (gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element) == FALSE) {
-               LOGE("failed to add source element to pipeline\n");
+               LOGE("failed to add source element to pipeline");
                gst_object_unref(GST_OBJECT(element));
                element = NULL;
                goto ERROR;
@@ -8587,8 +7532,8 @@ __mmplayer_activate_next_source(mm_player_t *player, GstState target)
 
                elemId = MMPLAYER_M_TYPEFIND;
                element = gst_element_factory_make("typefind", "typefinder");
-               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type",
-                       G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player);
+               __mmplayer_add_signal_connection(player, G_OBJECT(element),
+                       MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type", G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player);
        } else {
                elemId = MMPLAYER_M_AUTOPLUG;
                element = __mmplayer_create_decodebin(player);
@@ -8596,12 +7541,12 @@ __mmplayer_activate_next_source(mm_player_t *player, GstState target)
 
        /* check autoplug element is OK */
        if (!element) {
-               LOGE("can not create element(%d)\n", elemId);
+               LOGE("can not create element(%d)", elemId);
                goto ERROR;
        }
 
        if (gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element) == FALSE) {
-               LOGE("failed to add sinkbin to pipeline\n");
+               LOGE("failed to add sinkbin to pipeline");
                gst_object_unref(GST_OBJECT(element));
                element = NULL;
                goto ERROR;
@@ -8611,23 +7556,23 @@ __mmplayer_activate_next_source(mm_player_t *player, GstState target)
        mainbin[elemId].gst = element;
 
        if (gst_element_link(mainbin[MMPLAYER_M_SRC].gst, mainbin[elemId].gst) == FALSE) {
-               LOGE("Failed to link src - autoplug(or typefind)\n");
+               LOGE("Failed to link src - autoplug(or typefind)");
                goto ERROR;
        }
 
        if (gst_element_set_state(mainbin[MMPLAYER_M_SRC].gst, target) == GST_STATE_CHANGE_FAILURE) {
-               LOGE("Failed to change state of src element\n");
+               LOGE("Failed to change state of src element");
                goto ERROR;
        }
 
        if (!MMPLAYER_IS_HTTP_STREAMING(player)) {
                if (gst_element_set_state(mainbin[MMPLAYER_M_AUTOPLUG].gst, target) == GST_STATE_CHANGE_FAILURE) {
-                       LOGE("Failed to change state of decodebin\n");
+                       LOGE("Failed to change state of decodebin");
                        goto ERROR;
                }
        } else {
                if (gst_element_set_state(mainbin[MMPLAYER_M_TYPEFIND].gst, target) == GST_STATE_CHANGE_FAILURE) {
-                       LOGE("Failed to change state of src element\n");
+                       LOGE("Failed to change state of src element");
                        goto ERROR;
                }
        }
@@ -8752,7 +7697,7 @@ __mmplayer_deactivate_old_path(mm_player_t *player)
                goto ERROR;
        }
 
-       _mmplayer_track_destroy(player);
+       __mmplayer_track_destroy(player);
        __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG);
 
        if (player->streamer) {
@@ -9087,7 +8032,7 @@ DONE:
        return ret;
 }
 
-static gint
+gint
 __mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPad* pad,
 GstCaps* caps, GstElementFactory* factory, gpointer data)
 {
@@ -9316,7 +8261,7 @@ __mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
        MMPLAYER_FLEAVE();
 }
 
-static void
+void
 __mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data)
 {
        mm_player_t* player = (mm_player_t*)data;
@@ -9775,6 +8720,34 @@ __mmplayer_del_sink(mm_player_t* player, GstElement* sink)
        MMPLAYER_FLEAVE();
 }
 
+void
+__mmplayer_add_signal_connection(mm_player_t* player, GObject* object,
+                       MMPlayerSignalType type, const gchar* signal, GCallback cb_funct, gpointer u_data)
+{
+       MMPlayerSignalItem* item = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player);
+
+       if (type >= MM_PLAYER_SIGNAL_TYPE_MAX) {
+               LOGE("invalid signal type [%d]", type);
+               return;
+       }
+
+       item = (MMPlayerSignalItem*)g_malloc(sizeof(MMPlayerSignalItem));
+       if (!item) {
+               LOGE("cannot connect signal [%s]", signal);
+               return;
+       }
+
+       item->obj = object;
+       item->sig = g_signal_connect(object, signal, cb_funct, u_data);
+       player->signals[type] = g_list_append(player->signals[type], item);
+
+       MMPLAYER_FLEAVE();
+       return;
+}
+
 /* NOTE : be careful with calling this api. please refer to below glib comment
  * glib comment : Note that there is a bug in GObject that makes this function much
  * less useful than it might seem otherwise. Once gobject is disposed, the callback
@@ -11004,159 +9977,6 @@ void _mm_player_video_stream_internal_buffer_unref(void *buffer)
        MMPLAYER_FLEAVE();
 }
 
-void
-__gst_appsrc_feed_audio_data(GstElement *element, guint size, gpointer user_data)
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_AUDIO;
-       guint64 current_level_bytes = 0;
-
-       MMPLAYER_RETURN_IF_FAIL(player);
-
-       g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
-
-       LOGI("app-src: feed audio(%llu)", current_level_bytes);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-
-       if (player->media_stream_buffer_status_cb[type])
-               player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param[type]);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
-
-}
-
-void
-__gst_appsrc_feed_video_data(GstElement *element, guint size, gpointer user_data)
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_VIDEO;
-       guint64 current_level_bytes = 0;
-
-       MMPLAYER_RETURN_IF_FAIL(player);
-
-       g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
-
-       LOGI("app-src: feed video(%llu)", current_level_bytes);
-
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-       if (player->media_stream_buffer_status_cb[type])
-               player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param[type]);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
-}
-
-void
-__gst_appsrc_feed_subtitle_data(GstElement *element, guint size, gpointer user_data)
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_TEXT;
-       guint64 current_level_bytes = 0;
-
-       MMPLAYER_RETURN_IF_FAIL(player);
-
-       LOGI("app-src: feed subtitle");
-
-       g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
-
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-       if (player->media_stream_buffer_status_cb[type])
-               player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param[type]);
-
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
-}
-
-void
-__gst_appsrc_enough_audio_data(GstElement *element, gpointer user_data)
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_AUDIO;
-       guint64 current_level_bytes = 0;
-
-       MMPLAYER_RETURN_IF_FAIL(player);
-
-       LOGI("app-src: audio buffer is full");
-
-       g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
-
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-
-       if (player->media_stream_buffer_status_cb[type])
-               player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW, current_level_bytes, player->buffer_cb_user_param[type]);
-
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
-}
-
-void
-__gst_appsrc_enough_video_data(GstElement *element, gpointer user_data)
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_VIDEO;
-       guint64 current_level_bytes = 0;
-
-       MMPLAYER_RETURN_IF_FAIL(player);
-
-       LOGI("app-src: video buffer is full");
-
-       g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
-
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-       if (player->media_stream_buffer_status_cb[type])
-               player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW, current_level_bytes, player->buffer_cb_user_param[type]);
-
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
-}
-
-gboolean
-__gst_seek_audio_data(GstElement * appsrc, guint64 position, gpointer user_data)
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_AUDIO;
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-
-       LOGD("app-src: seek audio data %llu", position);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-
-       if (player->media_stream_seek_data_cb[type])
-               player->media_stream_seek_data_cb[type](type, position, player->seek_cb_user_param[type]);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
-
-       return TRUE;
-}
-
-gboolean
-__gst_seek_video_data(GstElement * appsrc, guint64 position, gpointer user_data)
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_VIDEO;
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-
-       LOGD("app-src: seek video data %llu", position);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-       if (player->media_stream_seek_data_cb[type])
-               player->media_stream_seek_data_cb[type](type, position, player->seek_cb_user_param[type]);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
-
-       return TRUE;
-}
-
-gboolean
-__gst_seek_subtitle_data(GstElement * appsrc, guint64 position, gpointer user_data)
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_TEXT;
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-
-       LOGD("app-src: seek subtitle data");
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-
-       if (player->media_stream_seek_data_cb[type])
-               player->media_stream_seek_data_cb[type](type, position, player->seek_cb_user_param[type]);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
-
-       return TRUE;
-}
-
 int
 _mmplayer_set_pcm_spec(MMHandleType hplayer, int samplerate, int channel)
 {
index 69553b2..627ad41 100644 (file)
@@ -326,7 +326,7 @@ EXIT:
        return ret;
 }
 
-void _mmplayer_track_initialize(mm_player_t* player)
+void __mmplayer_track_initialize(mm_player_t* player)
 {
        MMPlayerTrackType type = MM_PLAYER_TRACK_TYPE_AUDIO;
 
@@ -341,7 +341,7 @@ void _mmplayer_track_initialize(mm_player_t* player)
        }
 }
 
-void _mmplayer_track_destroy(mm_player_t* player)
+void __mmplayer_track_destroy(mm_player_t* player)
 {
        MMPlayerTrackType type = MM_PLAYER_TRACK_TYPE_AUDIO;
        MMHandleType attrs = 0;
@@ -366,7 +366,7 @@ void _mmplayer_track_destroy(mm_player_t* player)
        }
 }
 
-void _mmplayer_track_update_info(mm_player_t* player, MMPlayerTrackType type, GstPad *sinkpad)
+void __mmplayer_track_update_info(mm_player_t* player, MMPlayerTrackType type, GstPad *sinkpad)
 {
        MMPLAYER_FENTER();