[0.6.289] Fix not-linked error during prepare
[platform/core/multimedia/libmm-player.git] / src / mm_player_priv.c
index a148f06..1004e50 100644 (file)
@@ -83,7 +83,7 @@
 #define MM_VOLUME_FACTOR_MAX                   1.0
 
 /* Don't need to sleep for sound fadeout
- * fadeout related fucntion will be deleted(Deprecated)
+ * fadeout related function will be deleted(Deprecated)
  */
 #define MM_PLAYER_FADEOUT_TIME_DEFAULT 0
 
 #define DEFAULT_PCM_OUT_SAMPLERATE     44100
 #define DEFAULT_PCM_OUT_CHANNEL        2
 
+#define MQ_UNLINKED_CACHE_TIME         (500 * GST_MSECOND)
+
 /*---------------------------------------------------------------------------
 |    LOCAL CONSTANT DEFINITIONS:                                                                                       |
 ---------------------------------------------------------------------------*/
@@ -156,8 +158,7 @@ static int __mmplayer_change_selector_pad(mmplayer_t *player, mmplayer_track_typ
 
 static gboolean __mmplayer_check_subtitle(mmplayer_t *player);
 static int             __mmplayer_handle_missed_plugin(mmplayer_t *player);
-static int             __mmplayer_check_not_supported_codec(mmplayer_t *player, const gchar *factory_class, const gchar *mime);
-static void            __mmplayer_add_sink(mmplayer_t *player, GstElement *sink);
+static void            __mmplayer_add_sink(mmplayer_t *player, GstElement *sink, gboolean first);
 static void            __mmplayer_del_sink(mmplayer_t *player, GstElement *sink);
 static void            __mmplayer_release_signal_connection(mmplayer_t *player, mmplayer_signal_type_e type);
 static gpointer __mmplayer_gapless_play_thread(gpointer data);
@@ -196,6 +197,7 @@ static gboolean __mmplayer_swcodec_set_bo(mmplayer_t *player, mmplayer_video_dec
 
 static void __mmplayer_set_pause_state(mmplayer_t *player);
 static void __mmplayer_set_playing_state(mmplayer_t *player);
+static int __mmplayer_switch_stream(mmplayer_t *player, mmplayer_track_type_e type, int index);
 /*===========================================================================================
 |                                                                                                                                                                                      |
 |  FUNCTION DEFINITIONS                                                                                                                                                |
@@ -310,7 +312,7 @@ _mmplayer_get_stream_service_type(mmplayer_t *player)
 }
 
 /* this function sets the player state and also report
- * it to applicaton by calling callback function
+ * it to application by calling callback function
  */
 void
 _mmplayer_set_state(mmplayer_t *player, int state)
@@ -390,7 +392,7 @@ _mmplayer_check_state(mmplayer_t *player, mmplayer_command_state_e command)
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 #ifdef __DEBUG__
-       LOGD("incomming command : %d ", command);
+       LOGD("incoming command : %d ", command);
 #endif
        current_state = MMPLAYER_CURRENT_STATE(player);
        pending_state = MMPLAYER_PENDING_STATE(player);
@@ -491,7 +493,7 @@ _mmplayer_check_state(mmplayer_t *player, mmplayer_command_state_e command)
                if (pending_state == MM_PLAYER_STATE_NONE) {
                        if (current_state == MM_PLAYER_STATE_PAUSED)
                                goto NO_OP;
-                       else if (current_state != MM_PLAYER_STATE_PLAYING && current_state != MM_PLAYER_STATE_READY) // support loading state of broswer
+                       else if (current_state != MM_PLAYER_STATE_PLAYING && current_state != MM_PLAYER_STATE_READY) // support loading state of browser
                                goto INVALID_STATE;
                } else if (pending_state == MM_PLAYER_STATE_PAUSED) {
                        goto ALREADY_GOING;
@@ -584,6 +586,7 @@ int _mmplayer_acquire_hw_resource(mmplayer_t *player, mmplayer_resource_type_e t
                return MM_ERROR_PLAYER_INTERNAL;
        }
 
+       LOGD("commit [%d type] resource", type);
        rm_ret = mm_resource_manager_commit(player->resource_manager);
        if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
                LOGE("failed to commit of resource, ret(0x%x)", rm_ret);
@@ -594,6 +597,36 @@ int _mmplayer_acquire_hw_resource(mmplayer_t *player, mmplayer_resource_type_e t
        return MM_ERROR_NONE;
 }
 
+static void __mmplayer_destroy_hw_resource(mmplayer_t *player)
+{
+       int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
+
+       MMPLAYER_RETURN_IF_FAIL(player);
+       MMPLAYER_RETURN_IF_FAIL(player->resource_manager);
+
+       rm_ret = mm_resource_manager_mark_all_for_release(player->resource_manager);
+       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+               LOGW("failed to mark all for release of resource, ret(0x%x)", rm_ret);
+               goto rm_destroy;
+       }
+
+       rm_ret = mm_resource_manager_commit(player->resource_manager);
+       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE)
+               LOGW("failed to commit resource, ret(0x%x)", rm_ret);
+
+rm_destroy:
+       /* de-initialize resource manager */
+       rm_ret = mm_resource_manager_destroy(player->resource_manager);
+       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+               LOGW("failed to destroy resource manager, ret(0x%x)", rm_ret);
+               return;
+       }
+
+       player->resource_manager = NULL;
+
+       LOGD("resource manager is destroyed");
+}
+
 static int __mmplayer_release_hw_resource(mmplayer_t *player, mmplayer_resource_type_e type)
 {
        int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
@@ -614,9 +647,10 @@ static int __mmplayer_release_hw_resource(mmplayer_t *player, mmplayer_resource_
 
        player->hw_resource[type] = NULL;
 
+       LOGD("commit [%d type] resource", type);
        rm_ret = mm_resource_manager_commit(player->resource_manager);
        if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-               LOGE("failed to commit of resource, ret(0x%x)", rm_ret);
+               LOGE("failed to commit resource, ret(0x%x)", rm_ret);
                return MM_ERROR_PLAYER_INTERNAL;
        }
 
@@ -712,11 +746,16 @@ __mmplayer_gapless_play_thread(gpointer data)
 
                mainbin = player->pipeline->mainbin;
 
-               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_MUXED_S_BUFFER);
-               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_ID3DEMUX);
-               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_AUTOPLUG);
-               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_TYPEFIND);
-               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_SRC);
+               if (MMPLAYER_USE_DECODEBIN(player)) {
+                       MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_MUXED_S_BUFFER);
+                       MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_AUTOPLUG); /* decodebin */
+                       MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_TYPEFIND);
+                       MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_SRC);
+               } else {
+                       MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_AUTOPLUG); /* uridecodebin */
+                       mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = NULL;
+                       mainbin[MMPLAYER_M_SRC].gst = NULL;
+               }
 
                /* Initialize Player values */
                __mmplayer_initialize_gapless_play(player);
@@ -769,10 +808,14 @@ _mmplayer_bus_watcher_remove(MMHandleType hplayer)
                __mmplayer_remove_g_source_from_context(player->context.thread_default, player->bus_watcher);
                MMPLAYER_BUS_WATCHER_LOCK(player);
                end_time = g_get_monotonic_time () + 2 * G_TIME_SPAN_SECOND;
-               while (player->bus_watcher > 0)
-                       MMPLAYER_BUS_WATCHER_WAIT_UNTIL(player, end_time);
+               while (player->bus_watcher > 0) {
+                       if (!MMPLAYER_BUS_WATCHER_WAIT_UNTIL(player, end_time)) {
+                               LOGW("MMPLAYER_BUS_WATCHER_WAIT_UNTIL() timeout has passed - bus_watcher (%d)",
+                                               player->bus_watcher);
+                               break;
+                       }
+               }
                MMPLAYER_BUS_WATCHER_UNLOCK(player);
-
                g_mutex_clear(&player->bus_watcher_mutex);
                g_cond_clear(&player->bus_watcher_cond);
        }
@@ -842,7 +885,7 @@ _mmplayer_gst_remove_fakesink(mmplayer_t *player, mmplayer_gst_element_t *fakesi
        gst_element_set_locked_state(fakesink->gst, TRUE);
 
        /* setting the state to NULL never returns async
-        * so no need to wait for completion of state transiton
+        * so no need to wait for completion of state transition
         */
        if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(fakesink->gst, GST_STATE_NULL))
                LOGE("fakesink state change failure!");
@@ -876,7 +919,7 @@ ERROR:
 }
 
 static GstPadProbeReturn
-__mmplayer_gst_selector_blocked(GstPad *pad, GstPadProbeInfo *info, gpointer data)
+__mmplayer_gst_combiner_blocked(GstPad *pad, GstPadProbeInfo *info, gpointer data)
 {
        LOGD("pad(%s:%s) is blocked", GST_DEBUG_PAD_NAME(pad));
        return GST_PAD_PROBE_OK;
@@ -945,7 +988,7 @@ __mmplayer_gst_selector_update_start_time(mmplayer_t *player, mmplayer_track_typ
 }
 
 static GstPadProbeReturn
-__mmplayer_gst_selector_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer data)
+__mmplayer_gst_combiner_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer data)
 {
        GstPadProbeReturn ret = GST_PAD_PROBE_OK;
        GstEvent *event = GST_PAD_PROBE_INFO_DATA(info);
@@ -964,7 +1007,23 @@ __mmplayer_gst_selector_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer
                return ret;
 
        MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD(pad, caps, str, name, caps_ret);
-       if (!caps_ret)
+       if (!caps_ret) {
+               GstStream *stream = NULL;
+
+               if (GST_EVENT_TYPE(event) != GST_EVENT_STREAM_START)
+                       goto ERROR;
+
+               gst_event_parse_stream (event, &stream);
+               if (stream == NULL) {
+                       LOGW ("Got a STREAM_START event without a GstStream");
+                       goto ERROR;
+               }
+
+               name = gst_stream_type_get_name(gst_stream_get_stream_type(stream));
+               gst_object_unref (stream);
+       }
+
+       if (!name)
                goto ERROR;
 
        if (strstr(name, "audio")) {
@@ -1090,7 +1149,7 @@ ERROR:
        return ret;
 }
 
-/* create fakesink for audio or video path witout audiobin or videobin */
+/* create fakesink for audio or video path without audiobin or videobin */
 static void
 __mmplayer_gst_make_fakesink(mmplayer_t *player, GstPad *pad, const gchar *name)
 {
@@ -1107,13 +1166,13 @@ __mmplayer_gst_make_fakesink(mmplayer_t *player, GstPad *pad, const gchar *name)
        fakesink = gst_element_factory_make("fakesink", NULL);
        if (fakesink == NULL) {
                LOGE("failed to create fakesink");
-               goto EXIT;
+               return;
        }
 
-       /* store it as it's sink element */
-       __mmplayer_add_sink(player, fakesink);
-
-       gst_bin_add(GST_BIN(pipeline), fakesink);
+       if (!gst_bin_add(GST_BIN(pipeline), fakesink)) {
+               LOGE("failed to add fakesink to pipeline");
+               goto ERROR;
+       }
 
        /* link */
        sinkpad = gst_element_get_static_pad(fakesink, "sink");
@@ -1122,8 +1181,7 @@ __mmplayer_gst_make_fakesink(mmplayer_t *player, GstPad *pad, const gchar *name)
 
        if (gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) {
                LOGE("failed to link fakesink");
-               gst_object_unref(GST_OBJECT(fakesink));
-               goto EXIT;
+               goto ERROR;
        }
 
        if (strstr(name, "video")) {
@@ -1138,19 +1196,36 @@ __mmplayer_gst_make_fakesink(mmplayer_t *player, GstPad *pad, const gchar *name)
        g_object_set(G_OBJECT(fakesink), "sync", TRUE, NULL);
        gst_element_set_state(fakesink, GST_STATE_PAUSED);
 
-EXIT:
+       /* store it as it's sink element */
+       __mmplayer_add_sink(player, fakesink, FALSE);
+
        if (sinkpad)
                gst_object_unref(GST_OBJECT(sinkpad));
 
        MMPLAYER_FLEAVE();
        return;
+
+ERROR:
+
+       if (sinkpad)
+               gst_object_unref(GST_OBJECT(sinkpad));
+
+       if (fakesink) {
+               gst_element_set_state(fakesink, GST_STATE_NULL);
+
+               if (!gst_bin_remove(GST_BIN(pipeline), fakesink))
+                       gst_object_unref(GST_OBJECT(fakesink));
+       }
+
+       return;
 }
 
 static GstElement *
-__mmplayer_gst_make_concat(mmplayer_t *player, main_element_id_e elem_idx)
+__mmplayer_gst_make_concat(mmplayer_t *player, main_element_id_e elem_idx, mmplayer_track_type_e stream_type)
 {
        GstElement *pipeline = NULL;
-       GstElement *concat = NULL;
+       g_autoptr(GstElement) concat = NULL;
+       g_autoptr(GstPad) srcpad = NULL;
 
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, NULL);
@@ -1161,18 +1236,31 @@ __mmplayer_gst_make_concat(mmplayer_t *player, main_element_id_e elem_idx)
                return NULL;
        }
 
-       LOGD("Create concat [%d] element", elem_idx);
+       srcpad = gst_element_get_static_pad(concat, "src");
+
+       LOGD("blocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
+       player->track[stream_type].block_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
+                       __mmplayer_gst_combiner_blocked, NULL, NULL);
+       player->track[stream_type].event_probe_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH|GST_PAD_PROBE_TYPE_EVENT_FLUSH,
+                       __mmplayer_gst_combiner_event_probe, player, NULL);
 
-       player->pipeline->mainbin[elem_idx].id = elem_idx;
-       player->pipeline->mainbin[elem_idx].gst = concat;
 
        gst_element_set_state(concat, GST_STATE_PAUSED);
 
        pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
-       gst_bin_add(GST_BIN(pipeline), concat);
+       if (!gst_bin_add(GST_BIN(pipeline), concat)) {
+               LOGE("failed to add concat to pipeline");
+               gst_element_set_state(concat, GST_STATE_NULL);
+               return NULL;
+       }
+
+       LOGD("Create concat [%d] element", elem_idx);
+
+       player->pipeline->mainbin[elem_idx].id = elem_idx;
+       player->pipeline->mainbin[elem_idx].gst = concat;
 
        MMPLAYER_FLEAVE();
-       return concat;
+       return g_steal_pointer(&concat);
 }
 
 static GstElement *
@@ -1192,26 +1280,40 @@ __mmplayer_gst_make_selector(mmplayer_t *player, main_element_id_e elem_idx, mmp
        }
        g_object_set(selector, "sync-streams", TRUE, NULL);
 
-       player->pipeline->mainbin[elem_idx].id = elem_idx;
-       player->pipeline->mainbin[elem_idx].gst = selector;
-
-       /* player->track[stream_type].active_track_index = DEFAULT_TRACK; */
-
        srcpad = gst_element_get_static_pad(selector, "src");
 
        LOGD("blocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
        player->track[stream_type].block_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
-               __mmplayer_gst_selector_blocked, NULL, NULL);
+               __mmplayer_gst_combiner_blocked, NULL, NULL);
        player->track[stream_type].event_probe_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH|GST_PAD_PROBE_TYPE_EVENT_FLUSH,
-               __mmplayer_gst_selector_event_probe, player, NULL);
+               __mmplayer_gst_combiner_event_probe, player, NULL);
 
        gst_element_set_state(selector, GST_STATE_PAUSED);
 
        pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
-       gst_bin_add(GST_BIN(pipeline), selector);
+       if (!gst_bin_add(GST_BIN(pipeline), selector)) {
+               LOGE("failed to add selector to pipeline");
+
+               if (player->track[stream_type].block_id != 0)
+                 gst_pad_remove_probe (srcpad, player->track[stream_type].block_id);
+               player->track[stream_type].block_id = 0;
+
+               if (player->track[stream_type].event_probe_id != 0)
+                 gst_pad_remove_probe (srcpad, player->track[stream_type].event_probe_id);
+               player->track[stream_type].event_probe_id = 0;
+
+               gst_object_unref(GST_OBJECT(srcpad));
+
+               gst_element_set_state(selector, GST_STATE_NULL);
+               gst_object_unref(GST_OBJECT(selector));
+               return NULL;
+       }
 
        gst_object_unref(GST_OBJECT(srcpad));
 
+       player->pipeline->mainbin[elem_idx].id = elem_idx;
+       player->pipeline->mainbin[elem_idx].gst = selector;
+
        MMPLAYER_FLEAVE();
        return selector;
 }
@@ -1329,7 +1431,7 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                if (MMPLAYER_USE_DECODEBIN(player))
                        combiner = __mmplayer_gst_make_selector(player, elem_idx, stream_type);
                else
-                       combiner = __mmplayer_gst_make_concat(player, elem_idx);
+                       combiner = __mmplayer_gst_make_concat(player, elem_idx, stream_type);
 
                if (!combiner)
                        goto ERROR;
@@ -1339,7 +1441,7 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
        }
 
        /* link */
-       sinkpad = gst_element_get_request_pad(combiner, "sink_%u");
+       sinkpad = gst_element_request_pad_simple(combiner, "sink_%u");
 
        LOGD("pad link: %s:%s - %s:%s", GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(sinkpad));
 
@@ -1356,10 +1458,16 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                }
        }
 
-       if (MMPLAYER_USE_DECODEBIN(player))
+       if (MMPLAYER_USE_DECODEBIN(player)) {
                _mmplayer_track_update_stream(player, stream_type, sinkpad);
-       else
+       } else {
+               /* apply the text track information */
+               if (stream_type == MM_PLAYER_TRACK_TYPE_TEXT)
+                       mm_player_set_attribute((MMHandleType)player, NULL,
+                                       "content_text_track_num", player->track[stream_type].total_track_num,
+                                       "current_text_track_index", player->track[stream_type].active_track_index, NULL);
                __mmplayer_create_sink_path(player, combiner, stream_type, caps);
+       }
 
 DONE:
 ERROR:
@@ -1372,6 +1480,7 @@ ERROR:
                sinkpad = NULL;
        }
 
+       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-pad-added");
        return;
 }
 
@@ -1427,10 +1536,10 @@ __mmplayer_set_decode_track_info(mmplayer_t *player, mmplayer_track_type_e type)
 
        /* change track to active pad */
        active_index = player->track[type].active_track_index;
-       if ((active_index != DEFAULT_TRACK) &&
+       if ((active_index != DEFAULT_TRACK_INDEX) &&
                (__mmplayer_change_selector_pad(player, type, active_index) != MM_ERROR_NONE)) {
                LOGW("failed to change %d type track to %d", type, active_index);
-               player->track[type].active_track_index = DEFAULT_TRACK;
+               player->track[type].active_track_index = DEFAULT_TRACK_INDEX;
                return;
        }
 
@@ -1490,7 +1599,7 @@ __mmplayer_create_text_sink_path(mmplayer_t *player, GstElement *text_selector)
        MMPLAYER_RETURN_VAL_IF_FAIL(player && text_selector, FALSE);
 
        if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
-               LOGD("text path is not supproted");
+               LOGD("text path is not supported");
                return TRUE;
        }
 
@@ -1682,7 +1791,8 @@ __mmplayer_gst_create_sink_bin(GstElement *elem, GstPad *pad, GstCaps *ref_caps,
                MMPLAYER_GST_GET_CAPS_INFO(ref_caps, str, name, caps_ret);
                if (!caps_ret)
                        goto ERROR;
-
+               if (caps)
+                       gst_caps_unref(caps);
                caps = gst_caps_ref(ref_caps);
        }
 
@@ -1721,7 +1831,7 @@ __mmplayer_gst_create_sink_bin(GstElement *elem, GstPad *pad, GstCaps *ref_caps,
                        mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
                        LOGD("display_surface_type (%d)", surface_type);
 
-                       if ((surface_type == MM_DISPLAY_SURFACE_OVERLAY) &&
+                       if ((surface_type == MM_DISPLAY_SURFACE_OVERLAY || surface_type == MM_DISPLAY_SURFACE_OVERLAY_SYNC_UI) &&
                                (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE)) {
                                LOGE("failed to acquire video overlay resource");
                                goto ERROR;
@@ -1760,7 +1870,7 @@ __mmplayer_gst_create_sink_bin(GstElement *elem, GstPad *pad, GstCaps *ref_caps,
                                player->textsink_linked  = 1;
                        } else {
                                /* linked textbin exist which means that the external subtitle path exist already */
-                               LOGW("ignoring internal subtutle since external subtitle is available");
+                               LOGW("ignoring internal subtitle since external subtitle is available");
                        }
                }
                sink_pad_name = "text_sink";
@@ -1826,7 +1936,7 @@ __mmplayer_get_property_value_for_rotation(mmplayer_t *player, int display_angle
        if (rotation_angle >= 360)
                rotation_angle -= 360;
 
-       /* chech if supported or not */
+       /* check if supported or not */
        if (rotation_angle % 90) {
                LOGD("not supported rotation angle = %d", rotation_angle);
                return FALSE;
@@ -1865,7 +1975,7 @@ _mmplayer_get_video_angle(mmplayer_t *player, int *display_angle, int *orientati
        }
 
        if (display_angle) {
-               /* update user roation */
+               /* update user rotation */
                mm_attrs_get_int_by_name(attrs, "display_rotation", &display_rotation);
 
                /* Counter clockwise */
@@ -1938,7 +2048,8 @@ static void __mmplayer_video_param_set_display_visible(mmplayer_t *player)
        MMPLAYER_FENTER();
 
        /* check video sinkbin is created */
-       if (!_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_OVERLAY))
+       if (!(_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_OVERLAY) ||
+               _mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_OVERLAY_SYNC_UI)))
                return;
 
        attrs = MMPLAYER_GET_ATTRS(player);
@@ -2026,6 +2137,28 @@ static void __mmplayer_video_param_set_roi_area(mmplayer_t *player)
                win_roi_x, win_roi_y, win_roi_width, win_roi_height);
 }
 
+static void __mmplayer_video_param_set_display_overlay_sync_ui(mmplayer_t *player)
+{
+       MMHandleType attrs = 0;
+       gchar *handle = NULL;
+
+       /* check video sinkbin is created */
+       if (!_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_OVERLAY_SYNC_UI))
+               return;
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       MMPLAYER_RETURN_IF_FAIL(attrs);
+
+       /* common case if using overlay surface */
+       mm_attrs_get_string_by_name(attrs, "exported_shell_handle", &handle);
+       MMPLAYER_RETURN_IF_FAIL(handle);
+
+       gst_video_overlay_set_wl_window_exported_shell_handle(
+                       GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
+                       handle);
+       LOGD("set video param: exported_shell_handle (%s)", handle);
+}
+
 static void __mmplayer_video_param_set_display_overlay(mmplayer_t *player)
 {
        MMHandleType attrs = 0;
@@ -2053,14 +2186,24 @@ int
 _mmplayer_update_video_overlay_param(mmplayer_t *player, const char *param_name)
 {
        gboolean update_all_param = FALSE;
+       int curr_type = MM_DISPLAY_SURFACE_NUM;
 
        MMPLAYER_FENTER();
 
-       if (!_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_OVERLAY)) {
+       if (!player || !player->pipeline || !player->pipeline->mainbin || !player->pipeline->videobin ||
+               !player->pipeline->videobin[MMPLAYER_V_BIN].gst ||
+               !player->pipeline->videobin[MMPLAYER_V_SINK].gst) {
                LOGW("videosink is not ready yet");
                return MM_ERROR_PLAYER_NOT_INITIALIZED;
        }
 
+       mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &curr_type);
+
+       if (curr_type != MM_DISPLAY_SURFACE_OVERLAY && curr_type != MM_DISPLAY_SURFACE_OVERLAY_SYNC_UI) {
+               LOGE("current type(%d) is wrong", curr_type);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
        if (strcmp(player->ini.videosink_element_overlay, "tizenwlsink")) {
                LOGE("invalid videosink [%s]", player->ini.videosink_element_overlay);
                return MM_ERROR_PLAYER_INTERNAL;
@@ -2070,6 +2213,11 @@ _mmplayer_update_video_overlay_param(mmplayer_t *player, const char *param_name)
        if (!g_strcmp0(param_name, "update_all_param"))
                update_all_param = TRUE;
 
+       if (curr_type == MM_DISPLAY_SURFACE_OVERLAY_SYNC_UI) {
+               __mmplayer_video_param_set_display_overlay_sync_ui(player);
+               MMPLAYER_FLEAVE();
+               return MM_ERROR_NONE;
+       }
        if (update_all_param || !g_strcmp0(param_name, "display_overlay"))
                __mmplayer_video_param_set_display_overlay(player);
        if (update_all_param || !g_strcmp0(param_name, "display_method"))
@@ -2083,19 +2231,15 @@ _mmplayer_update_video_overlay_param(mmplayer_t *player, const char *param_name)
        if (update_all_param)
                __mmplayer_video_param_set_video_roi_area(player);
 
-
        MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
 }
 
-int
-_mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
+static int __mmplayer_set_disable_overlay_option(mmplayer_t *player, bool disable)
 {
        gboolean disable_overlay = FALSE;
-       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
        MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin &&
                                                                player->pipeline->videobin[MMPLAYER_V_SINK].gst,
                                                                MM_ERROR_PLAYER_NO_OP); /* invalid op */
@@ -2107,65 +2251,75 @@ _mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
 
        g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", &disable_overlay, NULL);
 
-       if (audio_only == (bool)disable_overlay) {
-               LOGE("It's the same with current setting: (%d)", audio_only);
+       if (disable == (bool)disable_overlay) {
+               LOGE("It's the same with current setting: (%d)", disable);
                return MM_ERROR_NONE;
        }
 
-       if (audio_only) {
+       if (disable) {
                LOGE("disable overlay");
                g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", TRUE, NULL);
 
                /* release overlay resource */
                if (__mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
                        LOGE("failed to release overlay resource");
-                       goto ERROR;
+                       return MM_ERROR_PLAYER_INTERNAL;
                }
        } else {
                if (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
                        LOGE("failed to acquire video overlay resource");
-                       goto ERROR;
+                       return MM_ERROR_PLAYER_INTERNAL;
                }
                player->interrupted_by_resource = FALSE;
 
                LOGD("enable overlay");
                __mmplayer_video_param_set_display_overlay(player);
+               __mmplayer_video_param_set_display_overlay_sync_ui(player);
                g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", FALSE, NULL);
        }
 
-ERROR:
        MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
 }
 
 int
-_mmplayer_get_audio_only(MMHandleType hplayer, bool *paudio_only)
+_mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
 {
+       int ret = MM_ERROR_NONE;
        mmplayer_t *player = (mmplayer_t *)hplayer;
-       gboolean disable_overlay = FALSE;
 
        MMPLAYER_FENTER();
-
        MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(paudio_only, MM_ERROR_INVALID_ARGUMENT);
-       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin &&
-                                                               player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-                                                               MM_ERROR_PLAYER_NO_OP); /* invalid op */
 
-       if (!g_object_class_find_property(G_OBJECT_GET_CLASS(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "disable-overlay")) {
-               LOGW("Display control is not supported");
-               return MM_ERROR_PLAYER_INTERNAL;
+       if (MMPLAYER_USE_DECODEBIN(player)) {
+               ret = __mmplayer_set_disable_overlay_option(player, audio_only);
+               goto EXIT;
        }
 
-       g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", &disable_overlay, NULL);
+       if (audio_only) {
+               MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin &&
+                                                                       player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                                                       MM_ERROR_PLAYER_NO_OP); /* invalid op */
 
-       *paudio_only = (bool)disable_overlay;
+               __mmplayer_del_sink(player, player->pipeline->videobin[MMPLAYER_V_SINK].gst);
 
-       LOGD("audio_only : %d", *paudio_only);
+               __mmplayer_switch_stream(player, MM_PLAYER_TRACK_TYPE_VIDEO, INVALID_TRACK_INDEX);
 
-       MMPLAYER_FLEAVE();
+               /* release decoder resource */
+               if (__mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
+                       LOGE("failed to release video decoder resources");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+               player->can_support_codec &= ~FOUND_PLUGIN_VIDEO;
+       } else {
+               __mmplayer_switch_stream(player, MM_PLAYER_TRACK_TYPE_VIDEO, DEFAULT_TRACK_INDEX);
+       }
 
-       return MM_ERROR_NONE;
+EXIT:
+       mm_player_set_attribute(hplayer, NULL, MM_PLAYER_AUDIO_ONLY, (int)audio_only, (char *)NULL);
+
+       MMPLAYER_FLEAVE();
+       return ret;
 }
 
 int
@@ -2271,10 +2425,6 @@ __mmplayer_gst_caps_notify_cb(GstPad *pad, GParamSpec *unused, gpointer data)
        MMPLAYER_RETURN_IF_FAIL(unused);
        MMPLAYER_RETURN_IF_FAIL(data);
 
-       caps = gst_pad_get_current_caps(pad);
-       if (!caps)
-               return;
-
        MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD(pad, caps, str, name, caps_ret);
        if (!caps_ret)
                goto ERROR;
@@ -2523,7 +2673,7 @@ __mmplayer_gst_audio_deinterleave_pad_added(GstElement *elem, GstPad *pad, gpoin
                G_CALLBACK(__mmplayer_audio_stream_decoded_render_cb),
                (gpointer)player);
 
-       __mmplayer_add_sink(player, sink);
+       __mmplayer_add_sink(player, sink, FALSE);
 
        if (gst_element_sync_state_with_parent(queue) == GST_STATE_CHANGE_FAILURE) {
                LOGE("failed to sync state");
@@ -2827,7 +2977,7 @@ __mmplayer_gst_make_audio_playback_sink(mmplayer_t *player, GList **bucket)
                                "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), (gpointer)player);
        gst_object_unref(GST_OBJECT(sink_pad));
 
-       __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst);
+       __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst, FALSE);
 
        MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
@@ -2969,7 +3119,7 @@ __mmplayer_gst_make_audio_extract_sink(mmplayer_t *player, GList **bucket)
                                MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads", G_CALLBACK(__mmplayer_gst_audio_deinterleave_no_more_pads), (gpointer)player);
                player->no_more_pad = FALSE;
        } else {
-       /* 4-2. create fakesink to extract interlevaed pcm */
+       /* 4-2. create fakesink to extract interleaved pcm */
                LOGD("add audio fakesink for interleaved audio");
                MMPLAYER_CREATE_ELEMENT(audiobin, extract_sink_id, "fakesink", "fakeaudiosink", *bucket, player);
                if (!(player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK))
@@ -2983,7 +3133,7 @@ __mmplayer_gst_make_audio_extract_sink(mmplayer_t *player, GList **bucket)
                        G_CALLBACK(__mmplayer_audio_stream_decoded_render_cb),
                        (gpointer)player);
 
-               __mmplayer_add_sink(player, audiobin[extract_sink_id].gst);
+               __mmplayer_add_sink(player, audiobin[extract_sink_id].gst, FALSE);
        }
 
        MMPLAYER_FLEAVE();
@@ -3014,7 +3164,7 @@ __mmplayer_gst_make_audio_bin_element(mmplayer_t *player, GList **bucket)
                g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "sync", TRUE,
                                "volume", player->sound.volume, "mute", player->sound.mute, NULL);
 
-               __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst);
+               __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst, FALSE);
                goto DONE;
        }
 
@@ -3145,7 +3295,7 @@ ERROR:
                }
        }
 
-       /* release audiobin with it's childs */
+       /* release audiobin with it's children */
        if (audiobin[MMPLAYER_A_BIN].gst)
                gst_object_unref(GST_OBJECT(audiobin[MMPLAYER_A_BIN].gst));
 
@@ -3229,6 +3379,7 @@ __mmplayer_video_stream_get_bo(mmplayer_t *player, int size)
        GList *l = NULL;
        MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
        gboolean ret = TRUE;
+       gint64 end_time = 0;
 
        /* check DRC, if it is, destroy the prev bo list to create again */
        if (player->video_bo_size != size) {
@@ -3281,6 +3432,9 @@ __mmplayer_video_stream_get_bo(mmplayer_t *player, int size)
                }
        }
 
+       if (player->ini.video_bo_timeout > 0)
+               end_time = g_get_monotonic_time() + player->ini.video_bo_timeout * G_TIME_SPAN_SECOND;
+
        while (TRUE) {
                /* get bo from list*/
                for (l = g_list_first(player->video_bo_list); l; l = g_list_next(l)) {
@@ -3292,20 +3446,20 @@ __mmplayer_video_stream_get_bo(mmplayer_t *player, int size)
                                return tbm_bo_ref(tmp->bo);
                        }
                }
-               if (!ret) {
-                       LOGE("failed to get bo in %d timeout", player->ini.video_bo_timeout);
-                       MMPLAYER_VIDEO_BO_UNLOCK(player);
-                       return NULL;
-               }
 
                if (player->ini.video_bo_timeout <= 0) {
                        MMPLAYER_VIDEO_BO_WAIT(player);
                } else {
-                       gint64 timeout = g_get_monotonic_time() + player->ini.video_bo_timeout * G_TIME_SPAN_SECOND;
-                       ret = MMPLAYER_VIDEO_BO_WAIT_UNTIL(player, timeout);
+                       ret = MMPLAYER_VIDEO_BO_WAIT_UNTIL(player, end_time);
+                       if (!ret) {
+                               LOGE("failed to get bo in %d timeout", player->ini.video_bo_timeout);
+                               break;
+                       }
                }
-               continue;
        }
+
+       MMPLAYER_VIDEO_BO_UNLOCK(player);
+       return NULL;
 }
 
 static void
@@ -3353,7 +3507,7 @@ __mmplayer_video_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer,
        /* set size and timestamp */
        mem = gst_buffer_peek_memory(buffer, 0);
        stream->length_total = gst_memory_get_sizes(mem, NULL, NULL);
-       stream->timestamp = (unsigned int)(GST_TIME_AS_MSECONDS(GST_BUFFER_PTS(buffer))); /* nano sec -> mili sec */
+       stream->timestamp = (unsigned int)(GST_TIME_AS_MSECONDS(GST_BUFFER_PTS(buffer))); /* nano sec -> milli sec */
 
        /* check zero-copy */
        if (player->set_mode.video_zc &&
@@ -3476,7 +3630,9 @@ __mmplayer_gst_create_video_filters(mmplayer_t *player, MMDisplaySurfaceType sur
                goto EXIT;
        }
 
-       if (surface_type != MM_DISPLAY_SURFACE_OVERLAY || player->set_mode.video_zc) {
+       if ((surface_type != MM_DISPLAY_SURFACE_OVERLAY &&
+               surface_type != MM_DISPLAY_SURFACE_OVERLAY_SYNC_UI) ||
+               player->set_mode.video_zc) {
                LOGD("skip creating the videoconv and rotator");
                return MM_ERROR_NONE;
        }
@@ -3506,10 +3662,13 @@ __mmplayer_get_videosink_factory_name(mmplayer_t *player, MMDisplaySurfaceType s
 
        switch (surface_type) {
        case MM_DISPLAY_SURFACE_OVERLAY:
+       /* fall through */
+       case MM_DISPLAY_SURFACE_OVERLAY_SYNC_UI:
                if (strlen(player->ini.videosink_element_overlay) > 0)
                        factory_name = player->ini.videosink_element_overlay;
                break;
        case MM_DISPLAY_SURFACE_REMOTE:
+       /* fall through */
        case MM_DISPLAY_SURFACE_NULL:
                if (strlen(player->ini.videosink_element_fake) > 0)
                        factory_name = player->ini.videosink_element_fake;
@@ -3543,7 +3702,7 @@ __mmplayer_gst_set_videosink_property(mmplayer_t *player, MMDisplaySurfaceType s
                return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       if (surface_type == MM_DISPLAY_SURFACE_OVERLAY) {
+       if (surface_type == MM_DISPLAY_SURFACE_OVERLAY || surface_type == MM_DISPLAY_SURFACE_OVERLAY_SYNC_UI) {
                bool use_tbm = (player->set_mode.video_zc || (player->is_360_feature_enabled && player->is_content_spherical));
                if (strncmp(factory_name, "tizenwlsink", strlen(factory_name)) == 0) {
                        g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
@@ -3646,7 +3805,7 @@ __mmplayer_gst_create_video_sink_bin(mmplayer_t *player, GstCaps *caps, MMDispla
        }
 
        /* store it as it's sink element */
-       __mmplayer_add_sink(player, videobin[MMPLAYER_V_SINK].gst);
+       __mmplayer_add_sink(player, videobin[MMPLAYER_V_SINK].gst, TRUE);
 
        /* adding created elements to bin */
        if (!_mmplayer_gst_element_add_bucket_to_bin(GST_BIN(videobin[MMPLAYER_V_BIN].gst), element_bucket)) {
@@ -3695,7 +3854,7 @@ ERROR:
        if (pad)
                gst_object_unref(GST_OBJECT(pad));
 
-       /* release videobin with it's childs */
+       /* release videobin with it's children */
        if (videobin[MMPLAYER_V_BIN].gst)
                gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst));
 
@@ -3730,7 +3889,7 @@ __mmplayer_gst_create_plain_text_elements(mmplayer_t *player)
 
        if (!player->play_subtitle) {
                LOGD("add textbin sink as sink element of whole pipeline.");
-               __mmplayer_add_sink(player, GST_ELEMENT(textbin[MMPLAYER_T_FAKE_SINK].gst));
+               __mmplayer_add_sink(player, GST_ELEMENT(textbin[MMPLAYER_T_FAKE_SINK].gst), FALSE);
        }
 
        /* adding created elements to bin */
@@ -3751,9 +3910,6 @@ __mmplayer_gst_create_plain_text_elements(mmplayer_t *player)
                goto ERROR;
        }
 
-       /* done. free allocated variables */
-       g_list_free(element_bucket);
-
        if (textbin[MMPLAYER_T_QUEUE].gst) {
                GstPad *pad = NULL;
                GstPad *ghostpad = NULL;
@@ -3779,9 +3935,12 @@ __mmplayer_gst_create_plain_text_elements(mmplayer_t *player)
                }
        }
 
+       g_list_free(element_bucket);
+
        return MM_ERROR_NONE;
 
 ERROR:
+
        g_list_free(element_bucket);
 
        if (!player->play_subtitle && textbin[MMPLAYER_T_FAKE_SINK].gst) {
@@ -3797,7 +3956,6 @@ static int
 __mmplayer_gst_create_text_sink_bin(mmplayer_t *player)
 {
        mmplayer_gst_element_t *textbin = NULL;
-       GList *element_bucket = NULL;
        int surface_type = 0;
        gint i = 0;
 
@@ -3848,8 +4006,6 @@ ERROR:
 
        LOGD("ERROR : releasing textbin");
 
-       g_list_free(element_bucket);
-
        /* release signal */
        __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
 
@@ -3869,7 +4025,7 @@ ERROR:
                }
        }
 
-       /* release textbin with it's childs */
+       /* release textbin with it's children */
        if (textbin[MMPLAYER_T_BIN].gst)
                gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
 
@@ -3991,7 +4147,7 @@ __mmplayer_gst_create_text_pipeline(mmplayer_t *player)
                        /* release signal */
                        __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
 
-                       /* release textbin with it's childs */
+                       /* release textbin with it's children */
                        gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
                        MMPLAYER_FREEIF(player->pipeline->textbin);
                        player->pipeline->textbin = textbin = NULL;
@@ -4042,7 +4198,7 @@ ERROR:
        if (player->pipeline->textbin) {
                LOGE("remove textbin");
 
-               /* release textbin with it's childs */
+               /* release textbin with it's children */
                MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->textbin, MMPLAYER_T_BIN);
                MMPLAYER_FREEIF(player->pipeline->textbin);
                player->pipeline->textbin = NULL;
@@ -4167,7 +4323,7 @@ __mmplayer_gst_adjust_subtitle_position(mmplayer_t *player, int position)
                return MM_ERROR_NONE;
        }
 
-       /* check current postion */
+       /* check current position */
        player->adjust_subtitle_pos = position;
 
        LOGD("save adjust_subtitle_pos in player");
@@ -4242,7 +4398,7 @@ __mmplayer_gst_create_pipeline(mmplayer_t *player)
                goto INIT_ERROR;
        }
 
-       /* Note : check whether subtitle atrribute uri is set. If uri is set, then try to play subtitle file */
+       /* Note : check whether subtitle attribute uri is set. If uri is set, then try to play subtitle file */
        if (__mmplayer_check_subtitle(player)
                && (__mmplayer_gst_create_text_pipeline(player) != MM_ERROR_NONE))
                LOGE("failed to create text pipeline");
@@ -4289,7 +4445,7 @@ __mmplayer_gst_destroy_pipeline(mmplayer_t *player)
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_INVALID_HANDLE);
 
        /* cleanup stuffs */
-       MMPLAYER_FREEIF(player->type);
+       MMPLAYER_FREEIF(player->type_caps_str);
        player->no_more_pad = FALSE;
        player->num_dynamic_pad = 0;
 
@@ -4324,9 +4480,6 @@ __mmplayer_gst_destroy_pipeline(mmplayer_t *player)
                __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_ALL);
 
                if (mainbin) {
-                       mmplayer_gst_element_t *audiobin = player->pipeline->audiobin;
-                       mmplayer_gst_element_t *videobin = player->pipeline->videobin;
-                       mmplayer_gst_element_t *textbin = player->pipeline->textbin;
                        GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[MMPLAYER_M_PIPE].gst));
                        gst_bus_set_sync_handler(bus, NULL, NULL, NULL);
                        gst_object_unref(bus);
@@ -4346,13 +4499,9 @@ __mmplayer_gst_destroy_pipeline(mmplayer_t *player)
                        if (mainbin[MMPLAYER_M_SRC_FAKESINK].gst)
                                gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC_FAKESINK].gst));
 
-                       /* free avsysaudiosink
-                          avsysaudiosink should be unref when destory pipeline just after start play with BT.
-                          Because audiosink is created but never added to bin, and therefore it will not be unref when pipeline is destroyed.
-                       */
-                       MMPLAYER_FREEIF(audiobin);
-                       MMPLAYER_FREEIF(videobin);
-                       MMPLAYER_FREEIF(textbin);
+                       MMPLAYER_FREEIF(player->pipeline->audiobin);
+                       MMPLAYER_FREEIF(player->pipeline->videobin);
+                       MMPLAYER_FREEIF(player->pipeline->textbin);
                        MMPLAYER_FREEIF(mainbin);
                }
 
@@ -4363,11 +4512,6 @@ __mmplayer_gst_destroy_pipeline(mmplayer_t *player)
        }
        MMPLAYER_FREEIF(player->album_art);
 
-       if (player->type_caps) {
-               gst_caps_unref(player->type_caps);
-               player->type_caps = NULL;
-       }
-
        if (player->v_stream_caps) {
                gst_caps_unref(player->v_stream_caps);
                player->v_stream_caps = NULL;
@@ -4458,7 +4602,7 @@ __mmplayer_gst_unrealize(mmplayer_t *player)
        /* destroy pipeline */
        ret = __mmplayer_gst_destroy_pipeline(player);
        if (ret != MM_ERROR_NONE) {
-               LOGE("failed to destory pipeline");
+               LOGE("failed to destroy pipeline");
                return ret;
        }
 
@@ -4542,55 +4686,6 @@ _mmplayer_parse_profile(const char *uri, void *param, mmplayer_parse_profile_t *
        return ret;
 }
 
-static gboolean
-__mmplayer_can_do_interrupt(mmplayer_t *player)
-{
-       if (!player || !player->pipeline || !player->attrs) {
-               LOGW("not initialized");
-               goto FAILED;
-       }
-
-       if (player->audio_decoded_cb) {
-               LOGW("not support in pcm extraction mode");
-               goto FAILED;
-       }
-
-       /* check if seeking */
-       if (player->seek_state != MMPLAYER_SEEK_NONE) {
-               MMMessageParamType msg_param;
-               memset(&msg_param, 0, sizeof(MMMessageParamType));
-               msg_param.code = MM_ERROR_PLAYER_SEEK;
-               player->seek_state = MMPLAYER_SEEK_NONE;
-               MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
-               goto FAILED;
-       }
-
-       /* check other thread */
-       if (!MMPLAYER_CMD_TRYLOCK(player)) {
-               LOGW("locked already, cmd state : %d", player->cmd);
-
-               /* check application command */
-               if (player->cmd == MMPLAYER_COMMAND_START || player->cmd == MMPLAYER_COMMAND_RESUME) {
-                       LOGW("playing.. should wait cmd lock then, will be interrupted");
-
-                       /* lock will be released at mrp_resource_release_cb() */
-                       MMPLAYER_CMD_LOCK(player);
-                       goto INTERRUPT;
-               }
-               LOGW("nothing to do");
-               goto FAILED;
-       } else {
-               LOGW("can interrupt immediately");
-               goto INTERRUPT;
-       }
-
-FAILED:    /* with CMD UNLOCKED */
-       return FALSE;
-
-INTERRUPT: /* with CMD LOCKED, will do UNLOCK at __resource_release_cb() */
-       return TRUE;
-}
-
 static int
 __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
                void *user_data)
@@ -4604,18 +4699,31 @@ __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
 
        if (!user_data) {
                LOGE("user_data is null");
-               return FALSE;
+               return TRUE;
        }
+
        player = (mmplayer_t *)user_data;
 
-       if (!__mmplayer_can_do_interrupt(player)) {
-               LOGW("no need to interrupt, so leave");
-               /* FIXME: there is no way to avoid releasing resource. */
-               return FALSE;
+       if (!player->pipeline || !player->attrs) {
+               LOGW("not initialized");
+               return TRUE;
+       }
+
+       LOGD("cmd lock player, cmd state : %d", player->cmd);
+       MMPLAYER_CMD_LOCK(player);
+       LOGD("cmd locked player");
+
+       if (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_NULL
+               || MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_NONE) {
+               LOGW("player already destroyed");
+               MMPLAYER_CMD_UNLOCK(player);
+               return TRUE;
        }
 
        player->interrupted_by_resource = TRUE;
 
+       MMPLAYER_POST_MSG(player, MM_MESSAGE_INTERRUPT_STARTED, NULL);
+
        /* get last play position */
        if (_mmplayer_gst_get_position(player, &pos) == MM_ERROR_NONE) {
                msg.union_type = MM_MSG_UNION_TIME;
@@ -4629,7 +4737,6 @@ __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
        if (_mmplayer_unrealize((MMHandleType)player) != MM_ERROR_NONE)
                LOGE("failed to unrealize");
 
-       /* lock is called in __mmplayer_can_do_interrupt() */
        MMPLAYER_CMD_UNLOCK(player);
 
        for (res_idx = MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER; res_idx < MMPLAYER_RESOURCE_TYPE_MAX; res_idx++) {
@@ -4717,15 +4824,15 @@ _mmplayer_create_player(MMHandleType handle)
 
        ret = _mmplayer_initialize_video_capture(player);
        if (ret != MM_ERROR_NONE) {
-               LOGE("failed to initialize video capture");
-               goto ERROR;
+               LOGW("video capture is not supported");
+               /* do not handle as error for headless profile */
        }
 
        /* initialize resource manager */
        if (mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
                __resource_release_cb, player, &player->resource_manager)
                != MM_RESOURCE_MANAGER_ERROR_NONE) {
-               LOGE("failed to initialize resource manager");
+               LOGE("failed to create resource manager");
                ret = MM_ERROR_PLAYER_INTERNAL;
                goto ERROR;
        }
@@ -4992,7 +5099,7 @@ _mmplayer_destroy(MMHandleType handle)
                MMPLAYER_GAPLESS_PLAY_THREAD_SIGNAL(player);
                MMPLAYER_GAPLESS_PLAY_THREAD_UNLOCK(player);
 
-               LOGD("waitting for gapless play thread exit");
+               LOGD("waiting for gapless play thread exit");
                g_thread_join(player->gapless_play_thread);
                g_mutex_clear(&player->gapless_play_thread_mutex);
                g_cond_clear(&player->gapless_play_thread_cond);
@@ -5001,20 +5108,17 @@ _mmplayer_destroy(MMHandleType handle)
 
        _mmplayer_release_video_capture(player);
 
-       /* de-initialize resource manager */
-       if (MM_RESOURCE_MANAGER_ERROR_NONE != mm_resource_manager_destroy(
-                       player->resource_manager))
-               LOGE("failed to deinitialize resource manager");
-
        /* release miscellaneous information */
        __mmplayer_release_misc(player);
 
        /* release pipeline */
-       if (MM_ERROR_NONE != __mmplayer_gst_destroy_pipeline(player)) {
-               LOGE("failed to destory pipeline");
+       if (__mmplayer_gst_destroy_pipeline(player) != MM_ERROR_NONE) {
+               LOGE("failed to destroy pipeline");
                return MM_ERROR_PLAYER_INTERNAL;
        }
 
+       __mmplayer_destroy_hw_resource(player);
+
        g_queue_free(player->bus_msg_q);
 
        /* release subtitle info lock and cond */
@@ -5158,6 +5262,8 @@ _mmplayer_unrealize(MMHandleType hplayer)
 {
        mmplayer_t *player = (mmplayer_t *)hplayer;
        int ret = MM_ERROR_NONE;
+       int rm_ret = MM_ERROR_NONE;
+       mmplayer_resource_type_e res_idx = MMPLAYER_RESOURCE_TYPE_MAX;
 
        MMPLAYER_FENTER();
 
@@ -5179,17 +5285,14 @@ _mmplayer_unrealize(MMHandleType hplayer)
        /* unrealize pipeline */
        ret = __mmplayer_gst_unrealize(player);
 
-       if (!player->interrupted_by_resource) {
-               int rm_ret = MM_ERROR_NONE;
-               mmplayer_resource_type_e res_idx = MMPLAYER_RESOURCE_TYPE_MAX;
-
-               for (res_idx = MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER; res_idx < MMPLAYER_RESOURCE_TYPE_MAX; res_idx++) {
-                       rm_ret = __mmplayer_release_hw_resource(player, res_idx);
-                       if (rm_ret != MM_ERROR_NONE)
-                               LOGE("failed to release [%d] resources", res_idx);
-               }
+       for (res_idx = MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER; res_idx < MMPLAYER_RESOURCE_TYPE_MAX; res_idx++) {
+               rm_ret = __mmplayer_release_hw_resource(player, res_idx);
+               if (rm_ret != MM_ERROR_NONE)
+                       LOGE("failed to release [%d] resources", res_idx);
        }
 
+       player->interrupted_by_resource = FALSE;
+
        MMPLAYER_FLEAVE();
        return ret;
 }
@@ -5597,14 +5700,14 @@ _mmplayer_pause(MMHandleType hplayer)
        /* check current state */
        MMPLAYER_CHECK_STATE(player, MMPLAYER_COMMAND_PAUSE);
 
-       /* check pipline reconfigure state */
+       /* check pipeline reconfigure state */
        __mmplayer_check_pipeline_reconfigure_state(player);
 
        switch (MMPLAYER_CURRENT_STATE(player)) {
        case MM_PLAYER_STATE_READY:
                {
                        /* check prepare async or not.
-                        * In the case of streaming playback, it's recommned to avoid blocking wait.
+                        * In the case of streaming playback, it's recommended to avoid blocking wait.
                         */
                        mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
                        LOGD("prepare working mode : %s", (async ? "async" : "sync"));
@@ -5647,9 +5750,11 @@ _mmplayer_pause(MMHandleType hplayer)
 
        /* pause pipeline */
        ret = _mmplayer_gst_pause(player, async);
-
-       if (ret != MM_ERROR_NONE)
+       if (ret != MM_ERROR_NONE) {
                LOGE("failed to pause player. ret : 0x%x", ret);
+               MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-pause-err");
+               return ret;
+       }
 
        if (MMPLAYER_PREV_STATE(player) == MM_PLAYER_STATE_READY && MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PAUSED) {
                if (_mmplayer_update_video_overlay_param(player, "display_rotation") != MM_ERROR_NONE)
@@ -5657,8 +5762,7 @@ _mmplayer_pause(MMHandleType hplayer)
        }
 
        MMPLAYER_FLEAVE();
-
-       return ret;
+       return MM_ERROR_NONE;
 }
 
 /* in case of streaming, pause could take long time.*/
@@ -5675,11 +5779,24 @@ _mmplayer_abort_pause(MMHandleType hplayer)
                                                player->pipeline->mainbin,
                                                MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       LOGD("set the pipeline state to READY");
+       if (player->pipeline->videobin && player->pipeline->videobin[MMPLAYER_V_BIN].gst) {
+               LOGD("set the videobin state to READY");
+               ret = _mmplayer_gst_set_state(player, player->pipeline->videobin[MMPLAYER_V_BIN].gst,
+                                                       GST_STATE_READY, TRUE, MMPLAYER_STATE_CHANGE_TIMEOUT(player));
+
+       }
+
+       if (player->pipeline->audiobin && player->pipeline->audiobin[MMPLAYER_A_BIN].gst) {
+               LOGD("set the audiobin state to READY");
+               ret = _mmplayer_gst_set_state(player, player->pipeline->audiobin[MMPLAYER_A_BIN].gst,
+                                                       GST_STATE_READY, TRUE, MMPLAYER_STATE_CHANGE_TIMEOUT(player));
+
+       }
 
-       /* set state to READY */
+       LOGD("set the pipeline state to READY");
        ret = _mmplayer_gst_set_state(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
                                                GST_STATE_READY, FALSE, MMPLAYER_STATE_CHANGE_TIMEOUT(player));
+
        if (ret != MM_ERROR_NONE) {
                LOGE("fail to change state to READY");
                return MM_ERROR_PLAYER_INTERNAL;
@@ -5805,7 +5922,7 @@ _mmplayer_set_position(MMHandleType hplayer, gint64 position)
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       /* check pipline reconfigure state */
+       /* check pipeline reconfigure state */
        __mmplayer_check_pipeline_reconfigure_state(player);
 
        ret = _mmplayer_gst_set_position(player, position, FALSE);
@@ -5824,7 +5941,7 @@ _mmplayer_get_duration(MMHandleType hplayer, gint64 *duration)
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
        MMPLAYER_RETURN_VAL_IF_FAIL(duration, MM_ERROR_COMMON_INVALID_ARGUMENT);
 
-       if (g_strrstr(player->type, "video/mpegts"))
+       if (g_strrstr(player->type_caps_str, "video/mpegts"))
                __mmplayer_update_duration_value(player);
 
        *duration = player->duration;
@@ -5845,7 +5962,7 @@ _mmplayer_get_buffer_position(MMHandleType hplayer, int *start_pos, int *end_pos
 }
 
 int
-_mmplayer_adjust_subtitle_postion(MMHandleType hplayer, int position)
+_mmplayer_adjust_subtitle_position(MMHandleType hplayer, int position)
 {
        mmplayer_t *player = (mmplayer_t *)hplayer;
        int ret = MM_ERROR_NONE;
@@ -5914,9 +6031,9 @@ static void
 __mmplayer_update_content_type_info(mmplayer_t *player)
 {
        MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player && player->type);
+       MMPLAYER_RETURN_IF_FAIL(player && player->type_caps_str);
 
-       if (__mmplayer_is_midi_type(player->type)) {
+       if (__mmplayer_is_midi_type(player->type_caps_str)) {
                player->bypass_audio_effect = TRUE;
                return;
        }
@@ -5926,19 +6043,19 @@ __mmplayer_update_content_type_info(mmplayer_t *player)
                return;
        }
 
-       if (g_strrstr(player->type, "application/x-hls")) {
+       if (g_strrstr(player->type_caps_str, "application/x-hls")) {
                /* If it can't know exact type when it parses uri because of redirection case,
                 * it will be fixed by typefinder or when doing autoplugging.
                 */
                player->profile.uri_type = MM_PLAYER_URI_TYPE_HLS;
                player->streamer->is_adaptive_streaming = TRUE;
-       } else if (g_strrstr(player->type, "application/dash+xml")) {
+       } else if (g_strrstr(player->type_caps_str, "application/dash+xml")) {
                player->profile.uri_type = MM_PLAYER_URI_TYPE_DASH;
                player->streamer->is_adaptive_streaming = TRUE;
        }
 
        /* in case of TS, fixed buffering mode should be used because player can not get exact duration time */
-       if ((player->streamer->is_adaptive_streaming) || (g_strrstr(player->type, "video/mpegts"))) {
+       if ((player->streamer->is_adaptive_streaming) || (g_strrstr(player->type_caps_str, "video/mpegts"))) {
                player->streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_FIXED;
 
                if (player->streamer->buffering_req.rebuffer_time <= MIN_BUFFERING_TIME) { /* if user did not set the rebuffer value */
@@ -5963,23 +6080,13 @@ _mmplayer_typefind_have_type(GstElement *tf, guint probability,
 
        MMPLAYER_RETURN_IF_FAIL(player && tf && caps);
 
-       /* store type string */
-       if (player->type_caps) {
-               gst_caps_unref(player->type_caps);
-               player->type_caps = NULL;
-       }
-
-       player->type_caps = gst_caps_copy(caps);
-       MMPLAYER_LOG_GST_CAPS_TYPE(player->type_caps);
-
-       MMPLAYER_FREEIF(player->type);
-       player->type = gst_caps_to_string(caps);
-       if (player->type)
-               LOGD("[handle: %p] media type %s found, probability %d%% / %d",
-                               player, player->type, probability, gst_caps_get_size(caps));
+       MMPLAYER_FREEIF(player->type_caps_str);
+       player->type_caps_str = gst_caps_to_string(caps);
+       LOGD("[handle: %p] media type %s found, probability %d%% / %d",
+                       player, player->type_caps_str, probability, gst_caps_get_size(caps));
 
        if ((!MMPLAYER_IS_RTSP_STREAMING(player)) &&
-               (g_strrstr(player->type, "audio/x-raw-int"))) {
+               (g_strrstr(player->type_caps_str, "audio/x-raw-int"))) {
                LOGE("not support media format");
 
                if (player->msg_posted == FALSE) {
@@ -6008,7 +6115,7 @@ _mmplayer_typefind_have_type(GstElement *tf, guint probability,
 
                if (!_mmplayer_gst_create_decoder(player, pad, caps)) {
                        gboolean async = FALSE;
-                       LOGE("failed to autoplug %s", player->type);
+                       LOGE("failed to autoplug %s", player->type_caps_str);
 
                        mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
 
@@ -6105,7 +6212,7 @@ __mmplayer_gst_make_queue2(mmplayer_t *player)
        /* 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")) {
+               if (!g_strrstr(player->type_caps_str, "video/mpegts")) {
                        type = MUXED_BUFFER_TYPE_MEM_RING_BUFFER;
                        player->streamer->ring_buffer_size = player->ini.http_ring_buffer_size;
                }
@@ -6257,8 +6364,10 @@ ERROR:
                /* And, it still has a parent "player".
                 * You need to let the parent manage the object instead of unreffing the object directly.
                 */
-               gst_bin_remove(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue2);
-               gst_object_unref(queue2);
+               if (!gst_bin_remove(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue2)) {
+                       LOGE("failed to remove queue2");
+                       gst_object_unref(queue2);
+               }
                queue2 = NULL;
        }
 
@@ -6273,16 +6382,18 @@ ERROR:
                 * You need to let the parent manage the object instead of unreffing the object directly.
                 */
 
-               gst_bin_remove(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), decodebin);
-               gst_object_unref(decodebin);
+               if (!gst_bin_remove(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), decodebin)) {
+                       LOGE("failed to remove decodebin");
+                       gst_object_unref(decodebin);
+               }
                decodebin = NULL;
        }
 
        return FALSE;
 }
 
-static int
-__mmplayer_check_not_supported_codec(mmplayer_t *player, const gchar *factory_class, const gchar *mime)
+int
+_mmplayer_update_not_supported_codec_info(mmplayer_t *player, const gchar *factory_class, const gchar *mime)
 {
        MMPLAYER_FENTER();
 
@@ -6435,6 +6546,12 @@ __mmplayer_get_next_uri(mmplayer_t *player)
                return FALSE;
        }
 
+       if (!MMPLAYER_USE_DECODEBIN(player)) {
+               if (player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst)
+                       g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst),
+                               "uri", profile.uri, NULL);
+       }
+
        SECURE_LOGD("next playback uri: %s", uri);
        return TRUE;
 }
@@ -6493,6 +6610,8 @@ __mmplayer_verify_gapless_play_path(mmplayer_t *player)
        }
 
        num_of_uri = g_list_length(player->uri_info.uri_list);
+       if (!MMPLAYER_USE_DECODEBIN(player))
+               player->gapless.running = TRUE;
 
        LOGD("repeat count = %d, num_of_list = %d", count, num_of_uri);
 
@@ -6507,6 +6626,13 @@ __mmplayer_verify_gapless_play_path(mmplayer_t *player)
                        LOGD("there is no next uri and no repeat");
                        goto ERROR;
                }
+
+               if (!MMPLAYER_USE_DECODEBIN(player)) {
+                       if (player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst)
+                               g_object_set(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst),
+                                       "uri", player->profile.uri, NULL);
+               }
+
                LOGD("looping cnt %d", count);
        } else {
                /* gapless playback path */
@@ -6527,6 +6653,11 @@ __mmplayer_remove_sinkpad (const GValue *item, gpointer user_data)
 {
        GstPad *sinkpad = g_value_get_object (item);
        GstElement *element = GST_ELEMENT(user_data);
+       if (!sinkpad || !element) {
+               LOGE("invalid parameter");
+               return;
+       }
+
        LOGD("(%s)element release request pad(%s)", GST_ELEMENT_NAME(element), GST_PAD_NAME(sinkpad));
        gst_element_release_request_pad(element, GST_PAD(sinkpad));
 }
@@ -6685,7 +6816,11 @@ __mmplayer_deactivate_selector(mmplayer_t *player, mmplayer_track_type_e type)
                g_ptr_array_set_size(selector->streams, 0);
 
                gst_element_set_state(player->pipeline->mainbin[selectorId].gst, GST_STATE_NULL);
-               gst_bin_remove(GST_BIN_CAST(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), player->pipeline->mainbin[selectorId].gst);
+               if (!gst_bin_remove(GST_BIN_CAST(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst),
+                                                       player->pipeline->mainbin[selectorId].gst)) {
+                       LOGE("failed to remove selector");
+                       gst_object_unref(player->pipeline->mainbin[selectorId].gst);
+               }
 
                player->pipeline->mainbin[selectorId].gst = NULL;
                selector = NULL;
@@ -6790,9 +6925,9 @@ _mmplayer_set_next_uri(MMHandleType hplayer, const char *uri, bool is_first_path
                        player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(uri));
                        SECURE_LOGD("add original path : %s", uri);
                } else {
-                       player->uri_info.uri_list = g_list_delete_link(player->uri_info.uri_list, g_list_nth(player->uri_info.uri_list, 0));
-                       player->uri_info.uri_list = g_list_insert(player->uri_info.uri_list, g_strdup(uri), 0);
-
+                       g_free(g_list_nth_data(player->uri_info.uri_list, 0));
+                       player->uri_info.uri_list = g_list_prepend(
+                               g_list_delete_link(player->uri_info.uri_list, player->uri_info.uri_list), g_strdup(uri));
                        SECURE_LOGD("change original path : %s", uri);
                }
        } else {
@@ -6874,7 +7009,7 @@ _mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad,
        MMPLAYER_FREEIF(caps_str);
 
        /* There is no available codec. */
-       __mmplayer_check_not_supported_codec(player, klass, mime);
+       _mmplayer_update_not_supported_codec_info(player, klass, mime);
 }
 
 gboolean
@@ -6911,8 +7046,13 @@ _mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad *pad,
 
                MMPLAYER_FREEIF(caps_str);
        } else if (g_str_has_prefix(mime, "video") && player->videodec_linked) {
-               LOGD("already video linked");
-               ret = FALSE;
+               if((MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) || (MMPLAYER_IS_DASH_STREAMING(player))) {
+                       LOGD("video is already linked, allow the stream switch");
+                       ret = TRUE;
+               } else {
+                       LOGD("video is already linked");
+                       ret = FALSE;
+               }
        } else {
                LOGD("found new stream");
        }
@@ -7089,7 +7229,7 @@ __mmplayer_is_offload_supported_type(mmplayer_t *player)
           this function need to be updated according to the supported media format
           @see player->ini.audio_offload_media_format */
 
-       if (__mmplayer_is_only_mp3_type(player->type)) {
+       if (__mmplayer_is_only_mp3_type(player->type_caps_str)) {
                LOGD("offload supportable media format type");
                return TRUE;
        }
@@ -7106,7 +7246,7 @@ __mmplayer_can_build_audio_offload_path(mmplayer_t *player)
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_VAL_IF_FAIL(player && player->attrs, FALSE);
 
-       LOGD("current stream : %s, sink: %s", player->type, player->ini.audio_offload_sink_element);
+       LOGD("current stream : %s, sink: %s", player->type_caps_str, player->ini.audio_offload_sink_element);
        if (!__mmplayer_is_offload_supported_type(player))
                goto DONE;
 
@@ -7357,15 +7497,15 @@ _mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPad *pad,
        LOGD("[handle: %p] found new element [%s] to link", player, factory_name);
 
        /* store type string */
-       if (player->type == NULL) {
-               player->type = gst_caps_to_string(caps);
+       if (player->type_caps_str == NULL) {
+               player->type_caps_str = gst_caps_to_string(caps);
                __mmplayer_update_content_type_info(player);
        }
 
        /* filtering exclude keyword */
        for (idx = 0; player->ini.exclude_element_keyword[idx][0] != '\0'; idx++) {
                if (strstr(factory_name, player->ini.exclude_element_keyword[idx])) {
-                       LOGW("skipping [%s] by exculde keyword [%s]",
+                       LOGW("skipping [%s] by exclude keyword [%s]",
                                        factory_name, player->ini.exclude_element_keyword[idx]);
 
                        result = GST_AUTOPLUG_SELECT_SKIP;
@@ -7427,14 +7567,19 @@ _mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPad *pad,
                gint stype = 0;
                gint width = 0;
                GstStructure *str = NULL;
-               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, expose pad");
-                       result = GST_AUTOPLUG_SELECT_EXPOSE;
-                       goto DONE;
+               /* parsebin in adaptivedemux get error if there is no parser */
+               if ((!g_strrstr(GST_ELEMENT_NAME(bin), "parsebin")) ||
+                       ((!MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) && (!MMPLAYER_IS_DASH_STREAMING(player)))) {
+                       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, expose pad");
+                               result = GST_AUTOPLUG_SELECT_EXPOSE;
+                               goto DONE;
+                       }
                }
 
                /* get w/h for omx state-tune */
@@ -7469,27 +7614,68 @@ DONE:
 }
 
 void
-_mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *new_pad,
+_mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *pad,
        gpointer data)
 {
-       //mmplayer_t *player = (mmplayer_t *)data;
-       GstCaps *caps = NULL;
+       int ret = MM_ERROR_NONE;
+       mmplayer_t *player = (mmplayer_t *)data;
+       mmplayer_gst_element_t *mainbin = player->pipeline->mainbin;
+       mmplayer_gst_element_t *videobin = player->pipeline->videobin;
+       gint timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
 
-       LOGD("[Decodebin2] pad-removed signal");
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && mainbin);
 
-       caps = gst_pad_query_caps(new_pad, NULL);
-       if (!caps) {
-               LOGW("query caps is NULL");
+       LOGD("decoded pad %s:%s removed", GST_DEBUG_PAD_NAME(pad));
+
+       if (MMPLAYER_USE_DECODEBIN(player))
+               return;
+
+       if (!videobin || !g_str_has_prefix(GST_PAD_NAME (pad), "video"))
+               return;
+
+       __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_VIDEOBIN);
+
+       __mmplayer_del_sink(player, videobin[MMPLAYER_V_SINK].gst);
+
+       LOGD("remove videobin");
+       ret = _mmplayer_gst_set_state(player, videobin[MMPLAYER_V_BIN].gst,
+                               GST_STATE_NULL, FALSE, timeout);
+       if (ret != MM_ERROR_NONE) {
+               LOGE("fail to change state of videobin to NULL");
                return;
        }
 
-       gchar *caps_str = NULL;
-       caps_str = gst_caps_to_string(caps);
+       if (!gst_bin_remove(GST_BIN_CAST(mainbin[MMPLAYER_M_PIPE].gst), videobin[MMPLAYER_V_BIN].gst)) {
+               LOGE("failed to remove videobin");
+               gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst));
+       }
 
-       LOGD("pad removed caps : %s from %s", caps_str, GST_ELEMENT_NAME(elem));
+       LOGD("remove concat");
+       ret = _mmplayer_gst_set_state(player, mainbin[MMPLAYER_M_V_CONCAT].gst,
+                               GST_STATE_NULL, FALSE, timeout);
+       if (ret != MM_ERROR_NONE) {
+               LOGE("fail to change state of concat to NULL");
+               return;
+       }
 
-       MMPLAYER_FREEIF(caps_str);
-       gst_caps_unref(caps);
+       if (!gst_bin_remove(GST_BIN_CAST(mainbin[MMPLAYER_M_PIPE].gst), mainbin[MMPLAYER_M_V_CONCAT].gst)) {
+               LOGE("failed to remove video concat");
+               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_V_CONCAT].gst));
+       }
+
+       mainbin[MMPLAYER_M_V_CONCAT].gst = NULL;
+       mainbin[MMPLAYER_M_V_CONCAT].id = 0;
+       MMPLAYER_FREEIF(player->pipeline->videobin);
+
+       ret = __mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY);
+       if (ret != MM_ERROR_NONE)
+               LOGE("failed to release overlay resources");
+
+       player->videodec_linked = 0;
+
+       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-pad-removed");
+       MMPLAYER_FLEAVE();
 }
 
 void
@@ -7509,15 +7695,22 @@ _mmplayer_gst_about_to_finish(GstElement *bin, gpointer data)
 
        if (!__mmplayer_verify_gapless_play_path(player)) {
                LOGD("decoding is finished.");
-               MMPLAYER_CMD_UNLOCK(player);
-               return;
+               if (MMPLAYER_USE_DECODEBIN(player)) {
+                       MMPLAYER_CMD_UNLOCK(player);
+                       return;
+               }
        }
 
-       _mmplayer_set_reconfigure_state(player, TRUE);
-       MMPLAYER_CMD_UNLOCK(player);
-
-       MMPLAYER_POST_MSG(player, MM_MESSAGE_GAPLESS_CONSTRUCTION, NULL);
-       __mmplayer_deactivate_old_path(player);
+       if (MMPLAYER_USE_DECODEBIN(player)) {
+               _mmplayer_set_reconfigure_state(player, TRUE);
+               MMPLAYER_CMD_UNLOCK(player);
+               MMPLAYER_POST_MSG(player, MM_MESSAGE_FLUSH_BUFFER, NULL);
+               __mmplayer_deactivate_old_path(player);
+       } else {
+               player->gapless.update_segment[MM_PLAYER_TRACK_TYPE_AUDIO] = FALSE;
+               player->gapless.update_segment[MM_PLAYER_TRACK_TYPE_VIDEO] = FALSE;
+               MMPLAYER_CMD_UNLOCK(player);
+       }
 
        MMPLAYER_FLEAVE();
 }
@@ -7587,14 +7780,14 @@ _mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
        player->gapless.update_segment[MM_PLAYER_TRACK_TYPE_VIDEO] = FALSE;
 
        /* deactivate pipeline except sinkbins to set up the new pipeline of next uri*/
-       MMPLAYER_POST_MSG(player, MM_MESSAGE_GAPLESS_CONSTRUCTION, NULL); /* post message for gapless */
+       MMPLAYER_POST_MSG(player, MM_MESSAGE_FLUSH_BUFFER, NULL); /* post message for gapless */
        __mmplayer_deactivate_old_path(player);
 
        MMPLAYER_FLEAVE();
 }
 
 void
-_mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data)
+_mmplayer_gst_element_added(GstBin *bin, GstElement *element, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
        const gchar *klass = NULL;
@@ -7608,80 +7801,115 @@ _mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data)
        if (__mmplayer_add_dump_buffer_probe(player, element))
                LOGD("add buffer probe");
 
-       if (g_strrstr(klass, "Codec/Decoder/Audio")) {
-               gchar *selected = NULL;
-               selected = g_strdup(GST_ELEMENT_NAME(element));
-               player->audio_decoders = g_list_append(player->audio_decoders, selected);
-
-               /* update codec info */
-               player->not_supported_codec &= MISSING_PLUGIN_VIDEO;
-               player->can_support_codec |= FOUND_PLUGIN_AUDIO;
-               player->audiodec_linked = 1;
-       } else if (g_strrstr(klass, "Codec/Decoder/Video")) {
-               /* update codec info */
-               player->not_supported_codec &= MISSING_PLUGIN_AUDIO;
-               player->can_support_codec |= FOUND_PLUGIN_VIDEO;
-               player->videodec_linked = 1;
-       }
-
-       if (g_strrstr(klass, "Demuxer/Adaptive")) {
-               player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].id = MMPLAYER_M_ADAPTIVE_DEMUX;
-               player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst = element;
-
-               LOGD("set max variant limit: %d, %d %d", player->adaptive_info.limit.bandwidth,
-                                               player->adaptive_info.limit.width, player->adaptive_info.limit.height);
-
-               g_object_set(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst,
-                                               "max-bandwidth", player->adaptive_info.limit.bandwidth,
-                                               "max-video-width", player->adaptive_info.limit.width,
-                                               "max-video-height", player->adaptive_info.limit.height, NULL);
+       if (g_strrstr(klass, "Decoder")) {
+               if (g_strrstr(klass, "Audio")) {
+                       player->audio_decoders = g_list_append(player->audio_decoders,
+                                                                                                                                       g_strdup(GST_ELEMENT_NAME(element)));
 
+                       /* update codec info */
+                       player->not_supported_codec &= MISSING_PLUGIN_VIDEO;
+                       player->can_support_codec |= FOUND_PLUGIN_AUDIO;
+                       player->audiodec_linked = 1;
+               } else if (g_strrstr(klass, "Video")) {
+                       GstElement *video_parse = player->pipeline->mainbin[MMPLAYER_M_V_PARSE].gst;
+                       /* update codec info */
+                       player->not_supported_codec &= MISSING_PLUGIN_AUDIO;
+                       player->can_support_codec |= FOUND_PLUGIN_VIDEO;
+                       player->videodec_linked = 1;
+
+                       if (video_parse) {
+                               GstPad *srcpad = gst_element_get_static_pad (video_parse, "src");
+                               if (srcpad) {
+                                       GstCaps *caps = NULL;
+                                       GstStructure *str = NULL;
+                                       const gchar *name = NULL;
+                                       gboolean caps_ret = TRUE;
+
+                                       MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD (srcpad, caps, str, name, caps_ret);
+                                       if (caps_ret && str) {
+                                               const gchar *stream_format = gst_structure_get_string (str, "stream-format");
+                                               if (stream_format && g_strrstr(stream_format, "byte-stream")) {
+                                                       if ((g_object_class_find_property(G_OBJECT_GET_CLASS(video_parse), "config-interval"))) {
+                                                               g_object_set(G_OBJECT(video_parse), "config-interval", -1, NULL);
+                                                               LOGD("Send SPS and PPS Insertion every IDR frame");
+                                                       }
+                                               }
+                                       }
+                                       gst_object_unref(GST_OBJECT(srcpad));
+                               }
+                       }
+               }
        } else if (g_strrstr(klass, "Demuxer")) {
+               if (g_strrstr(klass, "Adaptive")) {
+                       player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].id = MMPLAYER_M_ADAPTIVE_DEMUX;
+                       player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst = element;
+
+                       MMPLAYER_FREEIF(player->type_caps_str);
+
+                       if (g_strrstr(factory_name, "hlsdemux")) {
+                               player->type_caps_str = g_strdup("application/x-hls");
+                               player->profile.uri_type = MM_PLAYER_URI_TYPE_HLS;
+                       } else if (g_strrstr(factory_name, "dashdemux")) {
+                               player->type_caps_str = g_strdup("application/dash+xml");
+                               player->profile.uri_type = MM_PLAYER_URI_TYPE_DASH;
+                       } else {
+                               LOGE("not supported type");
+                               return;
+                       }
+                       player->streamer->is_adaptive_streaming = TRUE;
+
+                       if (player->streamer->buffering_req.prebuffer_time <= MIN_BUFFERING_TIME)
+                               player->streamer->buffering_req.prebuffer_time = DEFAULT_PREBUFFERING_TIME;
+
+                       LOGD("max variant limit: %d, %d, %d, prebuffer time: %d ms",
+                               player->adaptive_info.limit.bandwidth,
+                               player->adaptive_info.limit.width,
+                               player->adaptive_info.limit.height,
+                               player->streamer->buffering_req.prebuffer_time);
+
+                       g_object_set(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst,
+                               "max-bitrate", player->adaptive_info.limit.bandwidth,
+                               "max-video-width", player->adaptive_info.limit.width,
+                               "max-video-height", player->adaptive_info.limit.height,
+                               "low-watermark-time", (guint64)(player->streamer->buffering_req.prebuffer_time * GST_MSECOND),
+                               NULL);
+               } else {
 #ifdef __DEBUG__
-               LOGD("plugged element is demuxer. take it");
+                       LOGD("plugged element is demuxer. take it");
 #endif
-               player->pipeline->mainbin[MMPLAYER_M_DEMUX].id = MMPLAYER_M_DEMUX;
-               player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst = element;
-       }
-
-       if (g_strrstr(factory_name, "asfdemux") || g_strrstr(factory_name, "qtdemux") || g_strrstr(factory_name, "avidemux")) {
-               int surface_type = 0;
-
-               mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
+                       player->pipeline->mainbin[MMPLAYER_M_DEMUX].id = MMPLAYER_M_DEMUX;
+                       player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst = element;
+               }
+       } else if (g_strrstr(klass, "Parser") && (g_strrstr(klass, "Video"))) {
+               player->pipeline->mainbin[MMPLAYER_M_V_PARSE].id = MMPLAYER_M_V_PARSE;
+               player->pipeline->mainbin[MMPLAYER_M_V_PARSE].gst = element;
        }
 
-       // to support trust-zone only
-       if (g_strrstr(factory_name, "asfdemux")) {
-               LOGD("set file-location %s", player->profile.uri);
-               g_object_set(G_OBJECT(element), "file-location", player->profile.uri, NULL);
-       } else if (g_strrstr(factory_name, "legacyh264parse")) {
-               LOGD("[%s] output-format to legacyh264parse", "mssdemux");
-               g_object_set(G_OBJECT(element), "output-format", 1, NULL); /* NALU/Byte Stream format */
-       } else if (g_strrstr(factory_name, "mpegaudioparse")) {
+       if (g_strrstr(factory_name, "mpegaudioparse")) {
                if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
-                       (__mmplayer_is_only_mp3_type(player->type))) {
+                       (__mmplayer_is_only_mp3_type(player->type_caps_str))) {
                        LOGD("[mpegaudioparse] set streaming pull mode.");
                        g_object_set(G_OBJECT(element), "http-pull-mp3dec", TRUE, NULL);
                }
-       } else if (g_strrstr(factory_name, player->ini.videocodec_element_hw)) {
-               player->pipeline->mainbin[MMPLAYER_M_DEC1].gst = element;
-       }
-
-       if ((player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst) &&
+       } else if ((player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst) &&
                (g_strrstr(GST_ELEMENT_NAME(element), "multiqueue"))) {
+
                LOGD("plugged element is multiqueue. take it %s", GST_ELEMENT_NAME(element));
 
+               /* set mq unlinked cache size to avoid not-linked error */
+               gboolean sync_by_running_time = FALSE;
+               g_object_get(G_OBJECT(element), "sync-by-running-time", &sync_by_running_time, NULL);
+               if (sync_by_running_time)
+                       g_object_set(G_OBJECT(element), "unlinked-cache-time", MQ_UNLINKED_CACHE_TIME, NULL);
+
                player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].id = MMPLAYER_M_DEMUXED_S_BUFFER;
                player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst = element;
 
-               if ((MMPLAYER_IS_HTTP_STREAMING(player)) ||
-                       (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) ||
-                       (MMPLAYER_IS_DASH_STREAMING(player))) {
+               if (MMPLAYER_IS_HTTP_STREAMING(player)) {
                        /* in case of multiqueue, max bytes size is defined with fixed value in mm_player_streaming.h*/
                        _mm_player_streaming_set_multiqueue(player->streamer, element);
                        _mm_player_streaming_sync_property(player->streamer, player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst);
                }
-
        }
 
        return;
@@ -7772,7 +8000,7 @@ __mmplayer_release_misc(mmplayer_t *player)
 static void
 __mmplayer_release_misc_post(mmplayer_t *player)
 {
-       char *original_uri = NULL;
+       gchar *original_uri = NULL;
        MMPLAYER_FENTER();
 
        /* player->pipeline is already released before. */
@@ -7789,7 +8017,8 @@ __mmplayer_release_misc_post(mmplayer_t *player)
        player->audio_stream_changed_cb = NULL;
        player->audio_stream_changed_cb_user_param = NULL;
 
-       mm_player_set_attribute((MMHandleType)player, NULL, "content_video_found", 0, NULL);
+       mm_player_set_attribute((MMHandleType)player, NULL,
+               "content_video_found", 0, MM_PLAYER_AUDIO_ONLY, 0, NULL);
 
        /* clean found audio decoders */
        if (player->audio_decoders) {
@@ -7809,7 +8038,7 @@ __mmplayer_release_misc_post(mmplayer_t *player)
 
                mm_player_set_attribute((MMHandleType)player, NULL, "profile_uri",
                                original_uri, (original_uri) ? strlen(original_uri) : (0), NULL);
-
+               MMPLAYER_FREEIF(original_uri);
        }
 
        /* clear the audio stream buffer list */
@@ -7872,14 +8101,17 @@ _mmplayer_cancel_eos_timer(mmplayer_t *player)
 }
 
 static void
-__mmplayer_add_sink(mmplayer_t *player, GstElement *sink)
+__mmplayer_add_sink(mmplayer_t *player, GstElement *sink, gboolean first)
 {
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_IF_FAIL(player);
        MMPLAYER_RETURN_IF_FAIL(sink);
 
-       player->sink_elements = g_list_append(player->sink_elements, sink);
+       if (first)
+               player->sink_elements = g_list_prepend(player->sink_elements, sink);
+       else
+               player->sink_elements = g_list_append(player->sink_elements, sink);
 
        MMPLAYER_FLEAVE();
 }
@@ -7968,7 +8200,7 @@ __mmplayer_release_signal_connection(mmplayer_t *player, mmplayer_signal_type_e
        for (; sig_list; sig_list = sig_list->next) {
                item = sig_list->data;
 
-               if (item && item->obj && GST_IS_ELEMENT(item->obj)) {
+               if (item && item->obj) {
                        if (g_signal_handler_is_connected(item->obj, item->sig))
                                g_signal_handler_disconnect(item->obj, item->sig);
                }
@@ -8085,7 +8317,7 @@ _mmplayer_sync_subtitle_pipeline(mmplayer_t *player)
        current_state = GST_STATE(mainbin[MMPLAYER_M_PIPE].gst);
 
        // sync clock with current pipeline
-       curr_clock = GST_ELEMENT_CLOCK(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
+       curr_clock = gst_element_get_clock(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
        curr_time = gst_clock_get_time(curr_clock);
 
        base_time = gst_element_get_base_time(GST_ELEMENT_CAST(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
@@ -8104,6 +8336,8 @@ _mmplayer_sync_subtitle_pipeline(mmplayer_t *player)
                if (GST_STATE_CHANGE_FAILURE == ret) {
                        LOGE("fail to state change.");
                        result = MM_ERROR_PLAYER_INTERNAL;
+                       if (curr_clock)
+                               gst_object_unref(curr_clock);
                        goto ERROR;
                }
        }
@@ -8146,7 +8380,7 @@ ERROR:
        /* release signal */
        __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
 
-       /* release textbin with it's childs */
+       /* release textbin with it's children */
        MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->textbin, MMPLAYER_T_BIN);
        MMPLAYER_FREEIF(player->pipeline->textbin);
        player->pipeline->textbin = NULL;
@@ -8346,16 +8580,19 @@ __mmplayer_switch_stream(mmplayer_t *player, mmplayer_track_type_e type, int ind
        guint active_idx = 0;
        GstStream *stream = NULL;
        GList *streams = NULL;
-       GstEvent *ev = NULL;
        GstCaps *caps = NULL;
 
+       MMPLAYER_FENTER();
        LOGD("Switching Streams... type: %d, index: %d", type, index);
 
        player->track[type].active_track_index = index;
 
        for (int i = 0; i < MM_PLAYER_TRACK_TYPE_MAX; i++) {
                /* FIXME: need to consider the non display type or audio only in case of MM_PLAYER_TRACK_TYPE_VIDEO */
-               if (player->track[i].total_track_num > 0) {
+               LOGD("track type:%d, total: %d, active: %d", i,
+                               player->track[i].total_track_num, player->track[i].active_track_index);
+               if (player->track[i].total_track_num > 0 &&
+                       player->track[i].active_track_index > INVALID_TRACK_INDEX) {
                        active_idx = player->track[i].active_track_index;
                        stream = g_ptr_array_index(player->track[i].streams, active_idx);
                        streams = g_list_append (streams, (gchar *)gst_stream_get_stream_id(stream));
@@ -8371,10 +8608,32 @@ __mmplayer_switch_stream(mmplayer_t *player, mmplayer_track_type_e type, int ind
                }
        }
 
-       ev = gst_event_new_select_streams(streams);
-       gst_element_send_event(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, ev);
-       g_list_free(streams);
+       if (streams) {
+               LOGD("send select stream event");
+               gst_element_send_event(player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst,
+                               gst_event_new_select_streams(streams));
+               g_list_free(streams);
+       }
+
+       /* in paused state, seek to current pos to flush mq buffer and release waiting task */
+       if (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PAUSED) {
+               gint64 pos_nsec = GST_CLOCK_TIME_NONE;
+
+               if (!gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_nsec))
+                       pos_nsec = player->last_position;
 
+               LOGD("current pos %" GST_TIME_FORMAT ", rate = %f", GST_TIME_ARGS(pos_nsec), player->playback_rate);
+
+               if (!_mmplayer_gst_seek(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+                                       player->playback_rate, GST_FORMAT_TIME,
+                                       (GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE),
+                                       GST_SEEK_TYPE_SET, pos_nsec, GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE)) {
+                       LOGW("failed to seek");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
+       }
+
+       MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
 }
 
@@ -8480,6 +8739,7 @@ _mmplayer_change_track_language(MMHandleType hplayer, mmplayer_track_type_e type
 
        player = (mmplayer_t *)hplayer;
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(type < MM_PLAYER_TRACK_TYPE_MAX, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
        if (!player->pipeline) {
                LOGE("Track %d pre setting -> %d", type, index);
@@ -8504,7 +8764,7 @@ _mmplayer_change_track_language(MMHandleType hplayer, mmplayer_track_type_e type
        current_state = GST_STATE(mainbin[MMPLAYER_M_PIPE].gst);
        if (current_state < GST_STATE_PAUSED) {
                result = MM_ERROR_PLAYER_INVALID_STATE;
-               LOGW("Pipeline not in porper state");
+               LOGW("Pipeline not in proper state");
                goto EXIT;
        }
 
@@ -8737,7 +8997,7 @@ _mmplayer_manage_external_storage_state(MMHandleType hplayer, int id, int state)
        if (state != STORAGE_STATE_UNMOUNTABLE && state != STORAGE_STATE_REMOVED)
                return MM_ERROR_NONE;
 
-       /* FIXME: text path should be handled seperately. */
+       /* FIXME: text path should be handled separately. */
        if (((player->storage_info[MMPLAYER_PATH_VOD].type == STORAGE_TYPE_EXTERNAL)
                && (player->storage_info[MMPLAYER_PATH_VOD].id == id)) ||
                ((player->storage_info[MMPLAYER_PATH_TEXT].type == STORAGE_TYPE_EXTERNAL)
@@ -8822,7 +9082,7 @@ _mmplayer_set_max_adaptive_variant_limit(MMHandleType hplayer, int bandwidth, in
        if (player->pipeline && player->pipeline->mainbin && player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst) {
                LOGD("update max limit of %s", GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst));
                g_object_set(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst,
-                                               "max-bandwidth", bandwidth, "max-video-width", width, "max-video-height", height, NULL);
+                                               "max-bitrate", bandwidth, "max-video-width", width, "max-video-height", height, NULL);
 
                /* FIXME: seek to current position for applying new variant limitation */
        }
@@ -9237,9 +9497,6 @@ __mmplayer_update_audio_attrs(mmplayer_t *player, MMHandleType attrs)
        }
 
        p = gst_caps_get_structure(caps_a, 0);
-
-       mm_attrs_get_int_by_name(attrs, "content_audio_samplerate", &samplerate);
-
        gst_structure_get_int(p, "rate", &samplerate);
        gst_structure_get_int(p, "channels", &channels);
 
@@ -9283,7 +9540,7 @@ __mmplayer_update_video_attrs(mmplayer_t *player, MMHandleType attrs)
        }
 
        if (!caps_v) {
-               LOGD("no negitiated caps from videosink");
+               LOGD("no negotiated caps from videosink");
                gst_object_unref(pad);
                return FALSE;
        }
@@ -9319,7 +9576,7 @@ __mmplayer_update_bitrate_attrs(mmplayer_t *player, MMHandleType attrs)
        gchar *path = NULL;
        struct stat sb;
 
-       /* FIXIT : please make it clear the dependancy with duration/codec/uritype */
+       /* FIXIT : please make it clear the dependency with duration/codec/uritype */
        if (!player->duration)
                return FALSE;
 
@@ -9713,7 +9970,7 @@ __mmplayer_set_playing_state(mmplayer_t *player)
        /* try to get content metadata */
 
        /* NOTE : giving ATTR_MISSING_ONLY may have dependency with
-        * c-api since c-api doesn't use _start() anymore. It may not work propery with
+        * c-api since c-api doesn't use _start() anymore. It may not work properly with
         * legacy mmfw-player api
         */
        _mmplayer_update_content_attrs(player, ATTR_MISSING_ONLY);
@@ -9733,12 +9990,12 @@ __mmplayer_set_playing_state(mmplayer_t *player)
         * So, if it's not set yet, fill it with found data.
         */
        if (!audio_codec) {
-               if (g_strrstr(player->type, "audio/midi"))
+               if (g_strrstr(player->type_caps_str, "audio/midi"))
                        audio_codec = "MIDI";
-               else if (g_strrstr(player->type, "audio/x-amr"))
+               else if (g_strrstr(player->type_caps_str, "audio/x-amr"))
                        audio_codec = "AMR";
-               else if (g_strrstr(player->type, "audio/mpeg")
-                               && !g_strrstr(player->type, "mpegversion=(int)1"))
+               else if (g_strrstr(player->type_caps_str, "audio/mpeg")
+                               && !g_strrstr(player->type_caps_str, "mpegversion=(int)1"))
                        audio_codec = "AAC";
                else
                        audio_codec = "unknown";