apply 'use decodebin' option
[platform/core/multimedia/libmm-player.git] / src / mm_player_gst.c
index 56e9500..154e97e 100644 (file)
 ========================================================================================== */
 
 /*---------------------------------------------------------------------------
-|    GLOBAL CONSTANT DEFINITIONS:                                                                                      |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    IMPORTED VARIABLE DECLARATIONS:                                                                           |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    IMPORTED FUNCTION DECLARATIONS:                                                                           |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    LOCAL #defines:                                                                                                           |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
 |    LOCAL CONSTANT DEFINITIONS:                                                                                       |
 ---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    LOCAL DATA TYPE DEFINITIONS:                                                                                      |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    GLOBAL VARIABLE DEFINITIONS:                                                                                      |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    LOCAL VARIABLE DEFINITIONS:                                                                                       |
----------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|    LOCAL FUNCTION PROTOTYPES:                                                                                                |
----------------------------------------------------------------------------*/
+#define MMPLAYER_TAG_INDENT 3
 
 /*===========================================================================================
 |                                                                                                                                                                                      |
@@ -117,12 +86,12 @@ __mmplayer_check_error_posted_from_activated_track(mmplayer_t *player, gchar *sr
 {
        /* check whether the error is posted from not-activated track or not */
        int msg_src_pos = 0;
-       gint active_pad_index = 0;
+       gint active_index = 0;
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->mainbin[MMPLAYER_M_A_INPUT_SELECTOR].gst, TRUE);
 
-       active_pad_index = player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index;
-       LOGD("current  active pad index  -%d", active_pad_index);
+       active_index = player->track[MM_PLAYER_TRACK_TYPE_AUDIO].active_track_index;
+       LOGD("current  active pad index  -%d", active_index);
 
        if  (src_element_name) {
                int idx = 0;
@@ -140,10 +109,10 @@ __mmplayer_check_error_posted_from_activated_track(mmplayer_t *player, gchar *sr
                                idx++;
                        }
                }
-               LOGD("active pad = %d, error src index = %d", active_pad_index,  msg_src_pos);
+               LOGD("active pad = %d, error src index = %d", active_index,  msg_src_pos);
        }
 
-       if (active_pad_index != msg_src_pos) {
+       if (active_index != msg_src_pos) {
                LOGD("skip error because error is posted from no activated track");
                return FALSE;
        }
@@ -258,7 +227,8 @@ __mmplayer_gst_transform_gsterror(mmplayer_t *player, GstMessage *message, GErro
        LOGD("error code=%d, msg=%s, src element=%s, class=%s",
                        error->code, error->message, src_element_name, klass);
 
-       if (!__mmplayer_check_error_posted_from_activated_track(player, src_element_name))
+       if (MMPLAYER_USE_DECODEBIN(player) &&
+               !__mmplayer_check_error_posted_from_activated_track(player, src_element_name))
                return MM_ERROR_NONE;
 
        switch (error->code) {
@@ -1003,7 +973,7 @@ __mmplayer_gst_check_useful_message(mmplayer_t *player, GstMessage *message)
        }
        case GST_MESSAGE_STREAMS_SELECTED:
        {
-               if (!MMPLAYER_USE_URIDECODEBIN3(player))
+               if (MMPLAYER_USE_DECODEBIN(player))
                        break; /* drop msg */
 
                if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
@@ -1929,7 +1899,7 @@ __mmplayer_print_tag_foreach(const GstTagList *tags, const gchar *tag, gpointer
 {
        GValue val = { 0, };
        gchar *str = NULL;
-       gint depth = GPOINTER_TO_INT(user_data);
+       guint indent = GPOINTER_TO_UINT(user_data);
 
        if (!gst_tag_list_copy_value(&val, tags, tag))
                return;
@@ -1939,7 +1909,7 @@ __mmplayer_print_tag_foreach(const GstTagList *tags, const gchar *tag, gpointer
        else
                str = gst_value_serialize(&val);
 
-       LOGD("%*s%s: %s\n", 2 * depth, " ", gst_tag_get_nick(tag), str);
+       LOGD("%*s%s: %s\n", 2 * indent, " ", gst_tag_get_nick(tag), str);
        g_free(str);
        g_value_unset(&val);
 }
@@ -1969,7 +1939,7 @@ __mmplayer_dump_collection(GstStreamCollection * collection)
                tags = gst_stream_get_tags(stream);
                if (tags) {
                        LOGD ("  tags:\n");
-                       gst_tag_list_foreach(tags, __mmplayer_print_tag_foreach, GUINT_TO_POINTER(3));
+                       gst_tag_list_foreach(tags, __mmplayer_print_tag_foreach, GUINT_TO_POINTER(MMPLAYER_TAG_INDENT));
                        gst_tag_list_unref(tags);
                }
        }
@@ -1979,9 +1949,8 @@ static void
 __mmplayer_stream_notify_cb(GstStreamCollection *collection,
                        GstStream *stream, GParamSpec *pspec, gpointer data)
 {
-
        LOGD ("Got stream-notify from stream %s for %s (collection %p)\n",
-                               stream->stream_id, pspec->name, collection);
+                               gst_stream_get_stream_id(stream), pspec->name, collection);
        if (g_str_equal(pspec->name, "caps")) {
                GstCaps *caps = gst_stream_get_caps(stream);
                gchar *caps_str = gst_caps_to_string(caps);
@@ -1989,6 +1958,15 @@ __mmplayer_stream_notify_cb(GstStreamCollection *collection,
                g_free(caps_str);
                gst_caps_unref(caps);
        }
+
+       if (g_str_equal (pspec->name, "tags")) {
+               GstTagList *tags = gst_stream_get_tags(stream);
+               if (tags) {
+                       LOGD ("  tags:\n");
+                       gst_tag_list_foreach(tags, __mmplayer_print_tag_foreach, GUINT_TO_POINTER(MMPLAYER_TAG_INDENT));
+                       gst_tag_list_unref(tags);
+               }
+       }
 }
 
 static void
@@ -2822,7 +2800,7 @@ __mmplayer_gst_make_rtsp_src(mmplayer_t *player)
        return element;
 }
 
-void __mmplayer_http_src_setup(GstElement *element, GstElement *source, gpointer data)
+void __mmplayer_http_src_setup(GstElement *source, gpointer data)
 {
 #define HTTP_SOURCE_BLOCK_SIZE (64 * 1024)
 
@@ -2874,37 +2852,184 @@ void __mmplayer_http_src_setup(GstElement *element, GstElement *source, gpointer
 }
 
 static void
-__mmplayer_source_setup_cb(GstElement *element, GstElement *source, gpointer data)
+__mmplayer_gst_found_source(GObject *object, GObject *orig, GParamSpec *pspec, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
-       LOGD("%s >> %s", GST_ELEMENT_NAME(element), GST_ELEMENT_NAME(source));
+       GstElement *source = NULL;
+
+       MMPLAYER_FENTER();
+       LOGD("%s >> %s", GST_ELEMENT_NAME(object), pspec->name);
+
+       g_object_get(orig, pspec->name, &source, NULL);
 
        player->pipeline->mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC;
        player->pipeline->mainbin[MMPLAYER_M_SRC].gst = source;
 
        if (MMPLAYER_IS_HTTP_STREAMING(player)) {
-               __mmplayer_http_src_setup(element, source, data);
+               __mmplayer_http_src_setup(source, data);
+       } else if (MMPLAYER_IS_RTSP_STREAMING(player)) {
+               gchar *user_agent = NULL;
+
+               /* get attribute */
+               mm_attrs_get_string_by_name(player->attrs, "streaming_user_agent", &user_agent);
+
+               SECURE_LOGD("user_agent : %s", user_agent);
+
+               /* setting property to streaming source */
+               if (user_agent)
+                       g_object_set(G_OBJECT(source), "user-agent", user_agent, NULL);
        } else if (MMPLAYER_IS_SMOOTH_STREAMING(player)) {
                g_object_set(G_OBJECT(source), "timeout", DEFAULT_HTTP_TIMEOUT, NULL);
+       } else if (player->profile.uri_type == MM_PLAYER_URI_TYPE_MEM) {
+               g_object_set(source, "stream-type", GST_APP_STREAM_TYPE_RANDOM_ACCESS,
+                       "size", (gint64)player->profile.input_mem.len, "blocksize", 20480, NULL);
+
+               _mmplayer_add_signal_connection(player, G_OBJECT(source), 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(source), MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
+                                                                               G_CALLBACK(__mmplayer_gst_appsrc_feed_data_mem), (gpointer)&player->profile.input_mem);
+       }
+       MMPLAYER_FLEAVE();
+}
+
+static gint
+__mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * collection,
+    GstStream * stream, gpointer data)
+{
+       gint ret = 0; /* 1: select, 0: skip, -1: depends on decodebin */
+       GstStreamType stype = gst_stream_get_stream_type(stream);
+       mmplayer_t *player = (mmplayer_t *)data;
+       mmplayer_track_type_e type = MM_PLAYER_TRACK_TYPE_MAX;
+       GstCaps *caps = gst_stream_get_caps(stream);
+       gchar *caps_str = NULL;
+
+       LOGD("Stream type %s flags 0x%x",
+                       gst_stream_type_get_name(stype),
+                       gst_stream_get_stream_flags(stream));
+       LOGD("  ID: %s", gst_stream_get_stream_id(stream));
+
+       if (caps) {
+               caps_str = gst_caps_to_string(caps);
+               LOGD("  caps: %s", caps_str);
+       }
+
+       switch (stype) {
+       case GST_STREAM_TYPE_AUDIO:
+       {
+               GstStructure *caps_structure = NULL;
+               gint samplerate = 0;
+               gint channels = 0;
+
+               type = MM_PLAYER_TRACK_TYPE_AUDIO;
+
+               if (caps) {
+                       caps_structure = gst_caps_get_structure(caps, 0);
+                       gst_structure_get_int(caps_structure, "rate", &samplerate);
+                       gst_structure_get_int(caps_structure, "channels", &channels);
+
+                       if (channels > 0 && samplerate == 0) {
+                               LOGW("Skip corrupted audio stream");
+                               goto EXIT;
+                       }
+
+                       if (g_strrstr(caps_str, "mobile-xmf"))
+                               mm_player_set_attribute((MMHandleType)player, NULL,
+                                       "content_audio_codec", "mobile-xmf", strlen("mobile-xmf"), NULL);
+               }
+               break;
+       }
+       case GST_STREAM_TYPE_VIDEO:
+       {
+               GstStructure *caps_structure = NULL;
+               gint stype = 0;
+               gint width = 0;
+
+               type = MM_PLAYER_TRACK_TYPE_VIDEO;
+
+               /* do not support multi track video */
+               if (player->track[MM_PLAYER_TRACK_TYPE_VIDEO].total_track_num >= 1)
+                       goto EXIT;
+
+               mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype);
+
+               /* don't make video because of not required */
+               if ((stype == MM_DISPLAY_SURFACE_NULL) &&
+                       (!player->set_mode.video_export)) {
+                       LOGD("no need video decoding, skip video stream");
+                       goto EXIT;
+               }
+
+               if (caps) {
+                       caps_structure = gst_caps_get_structure(caps, 0);
+                       gst_structure_get_int(caps_structure, "width", &width);
+
+                       if (width != 0) {
+                               if (player->v_stream_caps) {
+                                       gst_caps_unref(player->v_stream_caps);
+                                       player->v_stream_caps = NULL;
+                               }
+
+                               player->v_stream_caps = gst_caps_copy(caps);
+                               MMPLAYER_LOG_GST_CAPS_TYPE(player->v_stream_caps);
+                       }
+               }
+               break;
+       }
+       case GST_STREAM_TYPE_TEXT:
+               type = MM_PLAYER_TRACK_TYPE_TEXT;
+               break;
+       default:
+               LOGW("Skip not supported stream type");
+               goto EXIT;
        }
+
+       _mmplayer_track_update_stream(player, type, stream);
+
+       if (player->track[type].active_track_index == (player->track[type].total_track_num - 1)) {
+               LOGD("select this stream, active idx : %d", player->track[type].active_track_index);
+               if (type == MM_PLAYER_TRACK_TYPE_AUDIO)
+                       _mmplayer_set_audio_attrs(player, caps);
+               ret = 1;
+       }
+
+EXIT:
+       g_free(caps_str);
+       if (caps)
+               gst_caps_unref(caps);
+
+       LOGD("ret %d", ret);
+       return ret;
 }
 
-gint __mmplayer_gst_select_stream (GstElement * uridecodebin, GstStreamCollection * collection,
+static gboolean
+__mmplayer_gst_decode_request_resource(GstElement * uridecodebin, GstStreamCollection * collection,
     GstStream * stream, gpointer data)
 {
-       GstStreamType stype = gst_stream_get_stream_type (stream);
+       mmplayer_t *player = (mmplayer_t *)data;
+       GstStreamType stype = gst_stream_get_stream_type(stream);
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
 
-       if (stype & GST_STREAM_TYPE_AUDIO)
-               LOGW("AUDIO type 0x%X", stype);
-       else if (stype & GST_STREAM_TYPE_VIDEO)
-               LOGW("VIDEO type 0x%X", stype);
-       else if (stype & GST_STREAM_TYPE_TEXT)
-               LOGW("TEXT type 0x%X", stype);
+       LOGD("stream type %s", gst_stream_type_get_name(stype));
 
-       return 1;
+       /* public does not support audio hw decoder at the moment */
+
+       if (player->hw_resource[MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER] != NULL) {
+               LOGW("video decoder resource is already acquired, skip it.");
+               return TRUE;
+       }
+
+       if (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
+               LOGE("failed to acquire video decoder resource");
+               return FALSE;
+       }
+       player->interrupted_by_resource = FALSE;
+       MMPLAYER_FLEAVE();
+       return TRUE;
 }
 
-void
+static void
 __mmplayer_gst_deep_element_added(GstElement *bin, GstBin *child, GstElement *element, gpointer data)
 {
        gchar *factory_name = NULL;
@@ -2931,41 +3056,40 @@ __mmplayer_gst_deep_element_added(GstElement *bin, GstBin *child, GstElement *el
                return;
        }
 
-       if (!mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst && g_strrstr(factory_name, "queue2")) { // fix me :streaming only..
-
-               gint64 dur_bytes = 0L;
-               muxed_buffer_type_e type = MUXED_BUFFER_TYPE_MEM_QUEUE;
-
-               mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER;
-               mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = element;
+       if ((MMPLAYER_IS_STREAMING(player)) && (!MMPLAYER_IS_RTSP_STREAMING(player))) {
+               /* update queue2 setting */
+               if (g_strrstr(factory_name, "queue2") && (!mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst)) {
+                       gint64 dur_bytes = 0L;
+                       muxed_buffer_type_e type = MUXED_BUFFER_TYPE_MEM_QUEUE;
 
-               if (!gst_element_query_duration(mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
-                       LOGW("failed to get duration from source %s", GST_ELEMENT_NAME(mainbin[MMPLAYER_M_SRC].gst));
+                       mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER;
+                       mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = element;
 
-               LOGD("type %s, dur_bytes = %"G_GINT64_FORMAT, player->type, dur_bytes);
+                       if (!gst_element_query_duration(mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
+                               LOGW("failed to get duration from source %s", GST_ELEMENT_NAME(mainbin[MMPLAYER_M_SRC].gst));
 
-               /* NOTE : in case of ts streaming, player could not get the correct duration info *
-                *                skip the pull mode(file or ring buffering) setting. */
-               if (dur_bytes > 0) {
-                       if ((!g_strrstr(player->type, "video/mpegts")) && (!g_strrstr(player->type, "application/x-hls"))) {
-                               type = MUXED_BUFFER_TYPE_MEM_RING_BUFFER;
-                               player->streamer->ring_buffer_size = player->ini.http_ring_buffer_size;
+                       LOGD("type %s, dur_bytes = %"G_GINT64_FORMAT, player->type, dur_bytes);
+                       /* NOTE : in case of ts streaming, player could not get the correct duration info *
+                        *                skip the pull mode(file or ring buffering) setting. */
+                       if (dur_bytes > 0) {
+                               if ((!g_strrstr(player->type, "video/mpegts")) && (!g_strrstr(player->type, "application/x-hls"))) {
+                                       type = MUXED_BUFFER_TYPE_MEM_RING_BUFFER;
+                                       player->streamer->ring_buffer_size = player->ini.http_ring_buffer_size;
+                               }
+                       } else {
+                               dur_bytes = 0;
                        }
-               } else {
-                       dur_bytes = 0;
-               }
 
-               _mm_player_streaming_set_queue2(player->streamer,
-                                                                               element,
-                                                                               FALSE,
-                                                                               type,
-                                                                               (guint64)dur_bytes); /* no meaning at the moment */
-
-               return;
-       }
+                       _mm_player_streaming_set_queue2(player->streamer,
+                                                                                       element,
+                                                                                       FALSE,
+                                                                                       type,
+                                                                                       (guint64)dur_bytes); /* no meaning at the moment */
+                       return;
+               }
 
-       if (g_strrstr(factory_name, "parsebin")) {
-               if (!mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst) {
+               /* update mq setting */
+               if (g_strrstr(factory_name, "parsebin") && (!mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst)) {
                        GstIterator *iter = NULL;
                        GValue item = {0, };
                        GstElement *ch_element = NULL;
@@ -2976,16 +3100,14 @@ __mmplayer_gst_deep_element_added(GstElement *bin, GstBin *child, GstElement *el
                                while (gst_iterator_next(iter, &item) == GST_ITERATOR_OK) {
                                        ch_element = g_value_get_object(&item);
                                        ch_factory = gst_element_get_factory(ch_element);
-
+                                       LOGD("children factory %s", GST_OBJECT_NAME(ch_factory));
                                        if (g_strrstr(GST_OBJECT_NAME(ch_factory), "multiqueue")) {
+                                               LOGD("get multiqueue");
                                                player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].id = MMPLAYER_M_DEMUXED_S_BUFFER;
                                                player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst = ch_element;
 
-                                               if ((MMPLAYER_IS_HTTP_STREAMING(player)) ||
-                                                       (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) ||
-                                                       (MMPLAYER_IS_DASH_STREAMING(player))) {
-                                                       _mm_player_streaming_set_multiqueue(player->streamer, ch_element);
-                                               }
+                                               /* in case of multiqueue, max bytes size is defined with fixed value in mm_player_streaming.h */
+                                               _mm_player_streaming_set_multiqueue(player->streamer, ch_element);
                                                g_value_reset(&item);
                                                break;
                                        }
@@ -2997,10 +3119,23 @@ __mmplayer_gst_deep_element_added(GstElement *bin, GstBin *child, GstElement *el
        }
 
        if (g_strrstr(factory_name, "parsebin")) {
+               int video_codec_type = 0;
+               int audio_codec_type = 0;
 
                g_object_set(G_OBJECT(child), "message-forward", TRUE, NULL);
                g_object_set(G_OBJECT(element), "message-forward", TRUE, NULL);
 
+               mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_VIDEO_CODEC_TYPE, &video_codec_type);
+               mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_AUDIO_CODEC_TYPE, &audio_codec_type);
+
+               /* CAUTION: if there is hw decoder, the rank value has to be higher than sw decoder
+                  and codec default type in ini has to be hw.
+                */
+               if (video_codec_type == MM_PLAYER_CODEC_TYPE_SW)
+                       g_object_set(G_OBJECT(child), "force-sw-decoder-for-video", TRUE, NULL);
+               if (audio_codec_type == MM_PLAYER_CODEC_TYPE_SW)
+                       g_object_set(G_OBJECT(child), "force-sw-decoder-for-audio", TRUE, NULL);
+
                mainbin[MMPLAYER_M_AUTOPLUG_PARSEBIN].id = MMPLAYER_M_AUTOPLUG_PARSEBIN;
                mainbin[MMPLAYER_M_AUTOPLUG_PARSEBIN].gst = element;
                _mmplayer_add_signal_connection(player, G_OBJECT(element),
@@ -3009,13 +3144,12 @@ __mmplayer_gst_deep_element_added(GstElement *bin, GstBin *child, GstElement *el
                _mmplayer_add_signal_connection(player, G_OBJECT(element),
                        MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue", G_CALLBACK(_mmplayer_gst_decode_autoplug_continue), (gpointer)player);
 
-               if (player->need_video_dec_sorting || player->need_audio_dec_sorting)
-                       _mmplayer_add_signal_connection(player, G_OBJECT(element),
-                       MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-sort", G_CALLBACK(_mmplayer_gst_decode_autoplug_sort), (gpointer)player);
-
                _mmplayer_add_signal_connection(player, G_OBJECT(element),
                        MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select", G_CALLBACK(_mmplayer_gst_decode_autoplug_select), (gpointer)player);
 
+               _mmplayer_add_signal_connection(player, G_OBJECT(child),
+                       MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "request-resource", G_CALLBACK(__mmplayer_gst_decode_request_resource), (gpointer)player);
+
        } else {
                _mmplayer_gst_element_added((GstElement *)child, element, data);
        }
@@ -3052,7 +3186,7 @@ __mmplayer_gst_make_uridecodebin(mmplayer_t *player)
                        "buffer-size", DEFAULT_BUFFER_SIZE_BYTES, NULL);
 
        _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3),
-               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "source-setup", G_CALLBACK(__mmplayer_source_setup_cb), (gpointer)player);
+               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "deep-notify::source", G_CALLBACK(__mmplayer_gst_found_source), (gpointer)player);
 
        _mmplayer_add_signal_connection(player, G_OBJECT(uridecodebin3),
                MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added", G_CALLBACK(_mmplayer_gst_decode_pad_added), (gpointer)player);
@@ -3181,7 +3315,6 @@ __mmplayer_gst_msg_push(GstBus *bus, GstMessage *msg, gpointer 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);
@@ -3198,7 +3331,6 @@ static gpointer __mmplayer_gst_bus_msg_thread(gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)(data);
        GstMessage *msg = NULL;
-       GstBus *bus = NULL;
 
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_VAL_IF_FAIL(player &&
@@ -3207,12 +3339,6 @@ static gpointer __mmplayer_gst_bus_msg_thread(gpointer data)
                                                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);
@@ -3232,9 +3358,8 @@ static gpointer __mmplayer_gst_bus_msg_thread(gpointer data)
        }
 
        MMPLAYER_BUS_MSG_THREAD_UNLOCK(player);
-       gst_object_unref(GST_OBJECT(bus));
-
        MMPLAYER_FLEAVE();
+
        return NULL;
 }
 
@@ -3581,7 +3706,7 @@ _mmplayer_gst_pause(mmplayer_t *player, gboolean async)
                return ret;
        }
 
-       if (!MMPLAYER_USE_URIDECODEBIN3(player)) {
+       if (MMPLAYER_USE_DECODEBIN(player)) {
                if ((!MMPLAYER_IS_RTSP_STREAMING(player)) && (!player->video_decoded_cb) &&
                        (!player->pipeline->videobin) && (!player->pipeline->audiobin))
                        return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
@@ -4105,8 +4230,8 @@ _mmplayer_gst_build_es_pipeline(mmplayer_t *player)
        return MM_ERROR_NONE;
 }
 
-static int
-__mmplayer_gst_build_pipeline_with_src(mmplayer_t *player)
+int
+_mmplayer_gst_build_pipeline_with_src(mmplayer_t *player)
 {
        mmplayer_gst_element_t *mainbin = NULL;
        GstElement *autoplug_elem = NULL;
@@ -4119,6 +4244,15 @@ __mmplayer_gst_build_pipeline_with_src(mmplayer_t *player)
 
        LOGD("uri type %d", player->profile.uri_type);
 
+       if ((player->profile.uri_type == MM_PLAYER_URI_TYPE_FILE) &&
+               (!_mmplayer_get_storage_info(player->profile.uri, &player->storage_info[MMPLAYER_PATH_VOD]))) {
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       if (player->profile.uri_type == MM_PLAYER_URI_TYPE_MEM) {
+               g_strlcpy(player->profile.uri, "appsrc://", MM_MAX_URL_LEN);
+       }
+
        autoplug_elem = __mmplayer_gst_make_uridecodebin(player);
        if (!autoplug_elem) {
                LOGE("failed to create uridecodebin3 element");
@@ -4192,31 +4326,14 @@ _mmplayer_gst_build_pipeline(mmplayer_t *player)
                src_elem = __mmplayer_gst_make_rtsp_src(player);
                break;
        case MM_PLAYER_URI_TYPE_URL_HTTP:
-               if (player->ini.use_uridecodebin3) {
-                       LOGD("uridecodebin include src element.");
-                       return __mmplayer_gst_build_pipeline_with_src(player);
-               }
                src_elem = __mmplayer_gst_make_http_src(player);
                break;
        case MM_PLAYER_URI_TYPE_FILE:
-               if (player->ini.use_uridecodebin3) {
-                       if (!_mmplayer_get_storage_info(player->profile.uri, &player->storage_info[MMPLAYER_PATH_VOD])) {
-                               LOGE("failed to get storage info");
-                               break;
-                       }
-                       LOGD("uridecodebin include src element.");
-                       return __mmplayer_gst_build_pipeline_with_src(player);
-               }
                src_elem = __mmplayer_gst_make_file_src(player);
                break;
        case MM_PLAYER_URI_TYPE_SS:
                {
                        gint http_timeout = DEFAULT_HTTP_TIMEOUT;
-                       if (player->ini.use_uridecodebin3) {
-                               LOGD("uridecodebin include src element.");
-                               return __mmplayer_gst_build_pipeline_with_src(player);
-                       }
-
                        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);
@@ -4380,7 +4497,17 @@ _mmplayer_gst_add_bus_watch(mmplayer_t *player)
                return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       player->bus_watcher = gst_bus_add_watch(bus, (GstBusFunc)__mmplayer_gst_msg_push, player);
+       player->bus_watcher = gst_bus_add_watch_full(bus, G_PRIORITY_DEFAULT,
+                                                       (GstBusFunc)__mmplayer_gst_msg_push, player,
+                                                       (GDestroyNotify)_mmplayer_watcher_removed_notify);
+       if (player->bus_watcher == 0) {
+               LOGE("failed to add bus watch");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       g_mutex_init(&player->bus_watcher_mutex);
+       g_cond_init(&player->bus_watcher_cond);
+
        player->context.thread_default = g_main_context_get_thread_default();
        if (player->context.thread_default == NULL) {
                player->context.thread_default = g_main_context_default();