[0.6.222] support codec type setting with u3
[platform/core/multimedia/libmm-player.git] / src / mm_player_priv.c
index c9c440e..a15b493 100644 (file)
@@ -43,7 +43,6 @@
 
 #include "mm_player_priv.h"
 #include "mm_player_ini.h"
-#include "mm_player_attrs.h"
 #include "mm_player_capture.h"
 #include "mm_player_utils.h"
 #include "mm_player_tracks.h"
@@ -89,7 +88,6 @@
 #define MM_PLAYER_FADEOUT_TIME_DEFAULT 0
 
 #define DEFAULT_PLAYBACK_RATE                  1.0
-#define DEFAULT_NUM_OF_V_OUT_BUFFER            3
 
 #define PLAYER_DISPLAY_MODE_DST_ROI            5
 
 
 #define FAKE_SINK_MAX_LATENESS         G_GINT64_CONSTANT(20000000) /* set 20ms as waylandsink */
 
+#define DEFAULT_PCM_OUT_FORMAT         "F32LE"
+#define DEFAULT_PCM_OUT_SAMPLERATE     44100
+#define DEFAULT_PCM_OUT_CHANNEL        2
+
 /*---------------------------------------------------------------------------
 |    LOCAL CONSTANT DEFINITIONS:                                                                                       |
 ---------------------------------------------------------------------------*/
@@ -138,18 +140,10 @@ static int                __mmplayer_gst_create_text_pipeline(mmplayer_t *player);
 static int             __mmplayer_gst_create_video_sink_bin(mmplayer_t *player, GstCaps *caps, MMDisplaySurfaceType surface_type);
 static int             __mmplayer_gst_create_audio_sink_bin(mmplayer_t *player);
 static int             __mmplayer_gst_create_text_sink_bin(mmplayer_t *player);
-
-static GstPadProbeReturn       __mmplayer_gst_selector_blocked(GstPad *pad, GstPadProbeInfo *info, gpointer data);
-static void            __mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data);
-static void            __mmplayer_gst_create_sinkbin(GstElement *decodebin, GstPad *pad, gpointer data);
-static void            __mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPad *pad, GstCaps *caps, gpointer data);
-static gboolean __mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPad *pad, GstCaps *caps,  gpointer data);
-static void __mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPad *new_pad, gpointer data);
-static void __mmplayer_gst_decode_drained(GstElement *bin, gpointer data);
-static void    __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data);
+static void            __mmplayer_gst_create_sink_bin(GstElement *decodebin, GstPad *pad, GstCaps *ref_caps, gpointer data);
+static gboolean __mmplayer_create_sink_path(mmplayer_t *player, GstElement *combiner, mmplayer_track_type_e type, GstCaps *caps);
 static gboolean __mmplayer_is_midi_type(gchar *str_caps);
 static gboolean __mmplayer_is_only_mp3_type(gchar *str_caps);
-static void    __mmplayer_set_audio_attrs(mmplayer_t *player, GstCaps *caps);
 
 static gboolean        __mmplayer_update_subtitle(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data);
 static void            __mmplayer_release_misc(mmplayer_t *player);
@@ -177,16 +171,15 @@ static int                __mmplayer_gst_set_message_callback(mmplayer_t *player, MMMessageCal
 
 /* util */
 static gboolean __mmplayer_verify_gapless_play_path(mmplayer_t *player);
-static void __mmplayer_activate_next_source(mmplayer_t *player, GstState target);
-static void __mmplayer_check_pipeline(mmplayer_t *player);
+static void __mmplayer_check_pipeline_reconfigure_state(mmplayer_t *player);
 static gboolean __mmplayer_deactivate_selector(mmplayer_t *player, mmplayer_track_type_e type);
+static gboolean __mmplayer_deactivate_combiner(mmplayer_t *player, mmplayer_track_type_e type);
 static void __mmplayer_deactivate_old_path(mmplayer_t *player);
 static int __mmplayer_gst_create_plain_text_elements(mmplayer_t *player);
 static guint32 _mmplayer_convert_fourcc_string_to_value(const gchar *format_name);
 static void            __mmplayer_gst_caps_notify_cb(GstPad *pad, GParamSpec *unused, gpointer data);
 static void            __mmplayer_audio_stream_send_data(mmplayer_t *player, mmplayer_audio_stream_buff_t *a_buffer);
 static void            __mmplayer_initialize_storage_info(mmplayer_t *player, mmplayer_path_type_e path_type);
-static int             __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res, void *user_data);
 static gboolean __mmplayer_update_duration_value(mmplayer_t *player);
 static gboolean __mmplayer_update_audio_attrs(mmplayer_t *player, MMHandleType attrs);
 static gboolean __mmplayer_update_video_attrs(mmplayer_t *player, MMHandleType attrs);
@@ -209,40 +202,10 @@ static void __mmplayer_set_playing_state(mmplayer_t *player);
 |                                                                                                                                                                                      |
 ========================================================================================== */
 
-#if 0 //debug
-static void
-print_tag(const GstTagList *list, const gchar *tag, gpointer unused)
-{
-       gint i, count;
-
-       count = gst_tag_list_get_tag_size(list, tag);
-
-       LOGD("count = %d", count);
-
-       for (i = 0; i < count; i++) {
-               gchar *str;
-
-               if (gst_tag_get_type(tag) == G_TYPE_STRING) {
-                       if (!gst_tag_list_get_string_index(list, tag, i, &str))
-                               g_assert_not_reached();
-               } else {
-                       str = g_strdup_value_contents(gst_tag_list_get_value_index(list, tag, i));
-               }
-
-               if (i == 0)
-                       g_print("  %15s: %s", gst_tag_get_nick(tag), str);
-               else
-                       g_print("                 : %s", str);
-
-               g_free(str);
-       }
-}
-#endif
-
 /* This function should be called after the pipeline goes PAUSED or higher
 state. */
 gboolean
-__mmplayer_update_content_attrs(mmplayer_t *player, enum content_attr_flag flag)
+_mmplayer_update_content_attrs(mmplayer_t *player, enum content_attr_flag flag)
 {
        static gboolean has_duration = FALSE;
        static gboolean has_video_attrs = FALSE;
@@ -304,19 +267,13 @@ __mmplayer_update_content_attrs(mmplayer_t *player, enum content_attr_flag flag)
        if ((flag & ATTR_BITRATE) || (!has_bitrate && missing_only) || all)
                has_bitrate = __mmplayer_update_bitrate_attrs(player, attrs);
 
-       /* validate all */
-       if (mm_attrs_commit_all(attrs)) {
-               LOGE("failed to update attributes");
-               return FALSE;
-       }
-
        MMPLAYER_FLEAVE();
 
        return TRUE;
 }
 
 MMStreamingType
-__mmplayer_get_stream_service_type(mmplayer_t *player)
+_mmplayer_get_stream_service_type(mmplayer_t *player)
 {
        MMStreamingType streaming_type = STREAMING_SERVICE_NONE;
 
@@ -356,7 +313,7 @@ __mmplayer_get_stream_service_type(mmplayer_t *player)
  * it to applicaton by calling callback function
  */
 void
-__mmplayer_set_state(mmplayer_t *player, int state)
+_mmplayer_set_state(mmplayer_t *player, int state)
 {
        MMMessageParamType msg = {0, };
 
@@ -426,15 +383,15 @@ __mmplayer_set_state(mmplayer_t *player, int state)
 }
 
 int
-__mmplayer_check_state(mmplayer_t *player, mmplayer_command_state_e command)
+_mmplayer_check_state(mmplayer_t *player, mmplayer_command_state_e command)
 {
        mmplayer_state_e current_state = MM_PLAYER_STATE_NUM;
        mmplayer_state_e pending_state = MM_PLAYER_STATE_NUM;
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       //LOGD("incomming command : %d ", command);
-
+#ifdef __DEBUG__
+       LOGD("incomming command : %d ", command);
+#endif
        current_state = MMPLAYER_CURRENT_STATE(player);
        pending_state = MMPLAYER_PENDING_STATE(player);
 
@@ -594,6 +551,144 @@ ALREADY_GOING:
        return MM_ERROR_PLAYER_NO_OP;
 }
 
+int _mmplayer_acquire_hw_resource(mmplayer_t *player, mmplayer_resource_type_e type)
+{
+       int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
+       mm_resource_manager_res_type_e rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_MAX;
+
+       switch (type) {
+               case MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER:
+                       rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER;
+                       break;
+               case MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY:
+                       rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY;
+                       break;
+               case MMPLAYER_RESOURCE_TYPE_AUDIO_OFFLOAD:
+                       rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_AUDIO_OFFLOAD;
+                       break;
+               default:
+                       LOGE("invalid mmplayer resource type %d", type);
+                       return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       if (player->hw_resource[type] != NULL) {
+               LOGD("[%d type] resource was already acquired", type);
+               return MM_ERROR_NONE;
+       }
+
+       LOGD("mark for acquire [%d type] resource", type);
+       rm_ret = mm_resource_manager_mark_for_acquire(player->resource_manager,
+                       rm_res_type, MM_RESOURCE_MANAGER_RES_VOLUME_FULL, &player->hw_resource[type]);
+       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+               LOGE("failed to mark resource for acquire, ret(0x%x)", rm_ret);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       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);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+}
+
+static int __mmplayer_release_hw_resource(mmplayer_t *player, mmplayer_resource_type_e type)
+{
+       int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
+
+       MMPLAYER_FENTER();
+
+       if (player->hw_resource[type] == NULL) {
+               LOGD("there is no acquired [%d type] resource", type);
+               return MM_ERROR_NONE;
+       }
+
+       LOGD("mark for release [%d type] resource", type);
+       rm_ret = mm_resource_manager_mark_for_release(player->resource_manager, player->hw_resource[type]);
+       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+               LOGE("failed to mark resource for release, ret(0x%x)", rm_ret);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       player->hw_resource[type] = NULL;
+
+       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);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+}
+
+static void
+__mmplayer_initialize_gapless_play(mmplayer_t *player)
+{
+       int i;
+
+       MMPLAYER_FENTER();
+
+       player->smooth_streaming = FALSE;
+       player->videodec_linked = 0;
+       player->audiodec_linked = 0;
+       player->textsink_linked = 0;
+       player->is_external_subtitle_present = FALSE;
+       player->is_external_subtitle_added_now = FALSE;
+       player->not_supported_codec = MISSING_PLUGIN_NONE;
+       player->can_support_codec = FOUND_PLUGIN_NONE;
+       player->pending_seek.is_pending = false;
+       player->pending_seek.pos = 0;
+       player->msg_posted = FALSE;
+       player->has_many_types = FALSE;
+       player->no_more_pad = FALSE;
+       player->not_found_demuxer = 0;
+       player->seek_state = MMPLAYER_SEEK_NONE;
+       player->is_subtitle_force_drop = FALSE;
+       player->play_subtitle = FALSE;
+       player->adjust_subtitle_pos = 0;
+
+       player->total_bitrate = 0;
+       player->total_maximum_bitrate = 0;
+
+       _mmplayer_track_initialize(player);
+       __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
+
+       for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++) {
+               player->bitrate[i] = 0;
+               player->maximum_bitrate[i] = 0;
+       }
+
+       if (player->v_stream_caps) {
+               gst_caps_unref(player->v_stream_caps);
+               player->v_stream_caps = NULL;
+       }
+
+       mm_player_set_attribute((MMHandleType)player, NULL, "content_video_found", 0, NULL);
+
+       /* clean found audio decoders */
+       if (player->audio_decoders) {
+               g_list_free_full(player->audio_decoders, (GDestroyNotify)g_free);
+               player->audio_decoders = NULL;
+       }
+
+       __mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER);
+
+       MMPLAYER_FLEAVE();
+}
+
+void _mmplayer_set_reconfigure_state(mmplayer_t *player, gboolean state)
+{
+       LOGI("set pipeline reconfigure state %d", state);
+       MMPLAYER_RECONFIGURE_LOCK(player);
+       player->gapless.reconfigure = state;
+       if (!state) /* wake up the waiting job */
+               MMPLAYER_RECONFIGURE_SIGNAL(player);
+       MMPLAYER_RECONFIGURE_UNLOCK(player);
+}
+
 static gpointer
 __mmplayer_gapless_play_thread(gpointer data)
 {
@@ -610,10 +705,7 @@ __mmplayer_gapless_play_thread(gpointer data)
                LOGD("reconfigure pipeline for gapless play.");
 
                if (player->gapless_play_thread_exit) {
-                       if (player->gapless.reconfigure) {
-                               player->gapless.reconfigure = false;
-                               MMPLAYER_PLAYBACK_UNLOCK(player);
-                       }
+                       _mmplayer_set_reconfigure_state(player, FALSE);
                        LOGD("exiting gapless play thread");
                        break;
                }
@@ -626,7 +718,10 @@ __mmplayer_gapless_play_thread(gpointer data)
                MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_TYPEFIND);
                MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_SRC);
 
-               __mmplayer_activate_next_source(player, GST_STATE_PLAYING);
+               /* Initialize Player values */
+               __mmplayer_initialize_gapless_play(player);
+
+               _mmplayer_activate_next_source(player, GST_STATE_PLAYING);
        }
        MMPLAYER_GAPLESS_PLAY_THREAD_UNLOCK(player);
 
@@ -650,19 +745,50 @@ __mmplayer_remove_g_source_from_context(GMainContext *context, guint source_id)
 }
 
 void
-__mmplayer_bus_msg_thread_destroy(MMHandleType hplayer)
+_mmplayer_watcher_removed_notify(gpointer data)
 {
-       mmplayer_t *player = (mmplayer_t *)hplayer;
-       GstMessage *msg = NULL;
-       GQueue *queue = NULL;
+       mmplayer_t *player = (mmplayer_t *)data;
+       MMPLAYER_RETURN_IF_FAIL(player);
+
+       MMPLAYER_BUS_WATCHER_LOCK(player);
+       player->bus_watcher = 0;
+       MMPLAYER_BUS_WATCHER_SIGNAL(player);
+       MMPLAYER_BUS_WATCHER_UNLOCK(player);
+}
 
+void
+_mmplayer_bus_watcher_remove(MMHandleType hplayer)
+{
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       gint64 end_time = 0;
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
 
        /* disconnecting bus watch */
-       if (player->bus_watcher)
+       if (player->bus_watcher > 0) {
                __mmplayer_remove_g_source_from_context(player->context.thread_default, player->bus_watcher);
-       player->bus_watcher = 0;
+               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);
+               MMPLAYER_BUS_WATCHER_UNLOCK(player);
+
+               g_mutex_clear(&player->bus_watcher_mutex);
+               g_cond_clear(&player->bus_watcher_cond);
+       }
+
+       MMPLAYER_FLEAVE();
+}
+
+void
+_mmplayer_bus_msg_thread_destroy(MMHandleType hplayer)
+{
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       GstMessage *msg = NULL;
+       GQueue *queue = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player);
 
        /* destroy the gst bus msg thread */
        if (player->bus_msg_thread) {
@@ -696,22 +822,16 @@ __mmplayer_bus_msg_thread_destroy(MMHandleType hplayer)
 }
 
 gboolean
-__mmplayer_gst_remove_fakesink(mmplayer_t *player, mmplayer_gst_element_t *fakesink)
+_mmplayer_gst_remove_fakesink(mmplayer_t *player, mmplayer_gst_element_t *fakesink)
 {
        GstElement *parent = NULL;
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, FALSE);
-
-       /* if we have no fakesink. this meas we are using decodebin which doesn'
-       t need to add extra fakesink */
-       MMPLAYER_RETURN_VAL_IF_FAIL(fakesink, TRUE);
+       MMPLAYER_RETURN_VAL_IF_FAIL(fakesink && fakesink->gst, TRUE);
 
        /* lock */
        MMPLAYER_FSINK_LOCK(player);
 
-       if (!fakesink->gst)
-               goto ERROR;
-
        /* get parent of fakesink */
        parent = (GstElement *)gst_object_get_parent((GstObject *)fakesink->gst);
        if (!parent) {
@@ -772,8 +892,10 @@ __mmplayer_gst_selector_update_start_time(mmplayer_t *player, mmplayer_track_typ
 
        for (idx = MM_PLAYER_TRACK_TYPE_AUDIO; idx < MM_PLAYER_TRACK_TYPE_TEXT; idx++) {
                if ((player->gapless.update_segment[idx] == TRUE) ||
-                       !(player->selector[idx].event_probe_id)) {
-                       /* LOGW("[%d] skip", idx); */
+                       !(player->track[idx].event_probe_id)) {
+#ifdef __DEBUG__
+                       LOGW("[%d] skip", idx);
+#endif
                        continue;
                }
 
@@ -834,18 +956,14 @@ __mmplayer_gst_selector_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer
        mmplayer_track_type_e stream_type = MM_PLAYER_TRACK_TYPE_VIDEO;
        gboolean caps_ret = TRUE;
 
-       if (GST_EVENT_IS_DOWNSTREAM(event) &&
-           GST_EVENT_TYPE(event) != GST_EVENT_STREAM_START &&
-           GST_EVENT_TYPE(event) != GST_EVENT_FLUSH_STOP &&
-           GST_EVENT_TYPE(event) != GST_EVENT_SEGMENT &&
-           GST_EVENT_TYPE(event) != GST_EVENT_EOS) {
+       if (GST_EVENT_TYPE(event) != GST_EVENT_STREAM_START &&
+               GST_EVENT_TYPE(event) != GST_EVENT_FLUSH_STOP &&
+               GST_EVENT_TYPE(event) != GST_EVENT_SEGMENT &&
+               GST_EVENT_TYPE(event) != GST_EVENT_EOS &&
+               GST_EVENT_TYPE(event) != GST_EVENT_QOS)
                return ret;
-       } else if (GST_EVENT_IS_UPSTREAM(event) &&
-                          GST_EVENT_TYPE(event) != GST_EVENT_QOS) {
-               return ret;
-       }
 
-       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
+       MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD(pad, caps, str, name, caps_ret);
        if (!caps_ret)
                goto ERROR;
 
@@ -940,11 +1058,13 @@ __mmplayer_gst_selector_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer
                                break;
                        }
 
+#ifdef __DEBUG__
                        LOGD("[%d] Adjusting QOS event: %" GST_TIME_FORMAT
                                 " - %" GST_TIME_FORMAT " = %" GST_TIME_FORMAT,
                                                stream_type, GST_TIME_ARGS(timestamp),
                                                GST_TIME_ARGS(running_time_diff),
                                                GST_TIME_ARGS(timestamp - running_time_diff));
+#endif
 
                        timestamp -= running_time_diff;
 
@@ -1027,6 +1147,35 @@ EXIT:
 }
 
 static GstElement *
+__mmplayer_gst_make_concat(mmplayer_t *player, main_element_id_e elem_idx)
+{
+       GstElement *pipeline = NULL;
+       GstElement *concat = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, NULL);
+
+       concat = gst_element_factory_make("concat", NULL);
+       if (!concat) {
+               LOGE("failed to create concat");
+               return NULL;
+       }
+
+       LOGD("Create concat [%d] element", elem_idx);
+
+       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);
+
+       MMPLAYER_FLEAVE();
+       return concat;
+}
+
+static GstElement *
 __mmplayer_gst_make_selector(mmplayer_t *player, main_element_id_e elem_idx, mmplayer_track_type_e stream_type)
 {
        GstElement *pipeline = NULL;
@@ -1046,14 +1195,14 @@ __mmplayer_gst_make_selector(mmplayer_t *player, main_element_id_e elem_idx, mmp
        player->pipeline->mainbin[elem_idx].id = elem_idx;
        player->pipeline->mainbin[elem_idx].gst = selector;
 
-       /* player->selector[stream_type].active_pad_index = DEFAULT_TRACK; */
+       /* 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->selector[stream_type].block_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
+       player->track[stream_type].block_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
                __mmplayer_gst_selector_blocked, NULL, NULL);
-       player->selector[stream_type].event_probe_id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH|GST_PAD_PROBE_TYPE_EVENT_FLUSH,
+       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);
 
        gst_element_set_state(selector, GST_STATE_PAUSED);
@@ -1068,10 +1217,10 @@ __mmplayer_gst_make_selector(mmplayer_t *player, main_element_id_e elem_idx, mmp
 }
 
 void
-__mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
+_mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
-       GstElement *selector = NULL;
+       GstElement *combiner = NULL;
        GstCaps *caps = NULL;
        GstStructure *str = NULL;
        const gchar *name = NULL;
@@ -1089,12 +1238,14 @@ __mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
        LOGD("pad-added signal handling");
 
        /* get mimetype from caps */
-       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
+       MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD(pad, caps, str, name, caps_ret);
        if (!caps_ret)
                goto ERROR;
 
        MMPLAYER_LOG_GST_CAPS_TYPE(caps);
-       /* LOGD("detected mimetype : %s", name); */
+#ifdef __DEBUG__
+       LOGD("detected mimetype : %s", name);
+#endif
 
        if (strstr(name, "video")) {
                gint stype = 0;
@@ -1107,25 +1258,30 @@ __mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
 
                MMPLAYER_FREEIF(caps_str);
 
-               mm_attrs_set_int_by_name(player->attrs, "content_video_found", TRUE);
+               mm_player_set_attribute((MMHandleType)player, NULL, "content_video_found", TRUE, NULL);
                mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype);
 
                LOGD("surface type : %d", stype);
 
                if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
-                       __mmplayer_gst_create_sinkbin(elem, pad, player);
+                       __mmplayer_gst_create_sink_bin(elem, pad, caps, player);
                        goto DONE;
                }
 
                /* in case of exporting video frame, it requires the 360 video filter.
                 * it will be handled in _no_more_pads(). */
-               if ((stype == MM_DISPLAY_SURFACE_NULL) && (!player->set_mode.media_packet_video_stream)) {
+               if ((stype == MM_DISPLAY_SURFACE_NULL) && (!player->set_mode.video_export)) {
                        __mmplayer_gst_make_fakesink(player, pad, name);
                        goto DONE;
                }
 
-               LOGD("video selector is required");
-               elem_idx = MMPLAYER_M_V_INPUT_SELECTOR;
+               if (MMPLAYER_USE_DECODEBIN(player)) {
+                       LOGD("video selector is required");
+                       elem_idx = MMPLAYER_M_V_INPUT_SELECTOR;
+               } else {
+                       LOGD("video concat is required");
+                       elem_idx = MMPLAYER_M_V_CONCAT;
+               }
                stream_type = MM_PLAYER_TRACK_TYPE_VIDEO;
        } else if (strstr(name, "audio")) {
                gint samplerate = 0;
@@ -1134,7 +1290,7 @@ __mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                if (MMPLAYER_IS_MS_BUFF_SRC(player) || player->build_audio_offload) {
                        if (player->build_audio_offload)
                                player->no_more_pad = TRUE; /* remove state holder */
-                       __mmplayer_gst_create_sinkbin(elem, pad, player);
+                       __mmplayer_gst_create_sink_bin(elem, pad, caps, player);
                        goto DONE;
                }
 
@@ -1145,14 +1301,23 @@ __mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                        __mmplayer_gst_make_fakesink(player, pad, name);
                        goto DONE;
                }
-
-               LOGD("audio selector is required");
-               elem_idx = MMPLAYER_M_A_INPUT_SELECTOR;
+               if (MMPLAYER_USE_DECODEBIN(player)) {
+                       LOGD("audio selector is required");
+                       elem_idx = MMPLAYER_M_A_INPUT_SELECTOR;
+               } else {
+                       LOGD("audio concat is required");
+                       elem_idx = MMPLAYER_M_A_CONCAT;
+               }
                stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
 
        } else if (strstr(name, "text")) {
-               LOGD("text selector is required");
-               elem_idx = MMPLAYER_M_T_INPUT_SELECTOR;
+               if (MMPLAYER_USE_DECODEBIN(player)) {
+                       LOGD("text selector is required");
+                       elem_idx = MMPLAYER_M_T_INPUT_SELECTOR;
+               } else {
+                       LOGD("text concat is required");
+                       elem_idx = MMPLAYER_M_T_CONCAT;
+               }
                stream_type = MM_PLAYER_TRACK_TYPE_TEXT;
        } else {
                LOGE("invalid caps info");
@@ -1160,32 +1325,41 @@ __mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
        }
 
        /* check selector and create it */
-       if (!(selector = player->pipeline->mainbin[elem_idx].gst)) {
-               selector = __mmplayer_gst_make_selector(player, elem_idx, stream_type);
-               if (!selector)
+       if (!(combiner = player->pipeline->mainbin[elem_idx].gst)) {
+               if (MMPLAYER_USE_DECODEBIN(player))
+                       combiner = __mmplayer_gst_make_selector(player, elem_idx, stream_type);
+               else
+                       combiner = __mmplayer_gst_make_concat(player, elem_idx);
+
+               if (!combiner)
                        goto ERROR;
                first_track = TRUE;
        } else {
-               LOGD("input-selector is already created.");
+               LOGD("Combiner element is already created.");
        }
 
        /* link */
-       sinkpad = gst_element_get_request_pad(selector, "sink_%u");
+       sinkpad = gst_element_get_request_pad(combiner, "sink_%u");
 
        LOGD("pad link: %s:%s - %s:%s", GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(sinkpad));
 
        if (gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) {
-               LOGE("failed to link selector");
-               gst_object_unref(GST_OBJECT(selector));
+               LOGE("failed to link combiner");
+               gst_object_unref(GST_OBJECT(combiner));
                goto ERROR;
        }
 
        if (first_track) {
-               LOGD("this track will be activated");
-               g_object_set(selector, "active-pad", sinkpad, NULL);
+               if (MMPLAYER_USE_DECODEBIN(player)) {
+                       LOGD("this track will be activated");
+                       g_object_set(combiner, "active-pad", sinkpad, NULL);
+               }
        }
 
-       __mmplayer_track_update_selector_info(player, stream_type, sinkpad);
+       if (MMPLAYER_USE_DECODEBIN(player))
+               _mmplayer_track_update_stream(player, stream_type, sinkpad);
+       else
+               __mmplayer_create_sink_path(player, combiner, stream_type, caps);
 
 DONE:
 ERROR:
@@ -1202,7 +1376,7 @@ ERROR:
 }
 
 static gboolean
-__mmplayer_create_sink_path(mmplayer_t *player, GstElement *selector, mmplayer_track_type_e type)
+__mmplayer_create_sink_path(mmplayer_t *player, GstElement *combiner, mmplayer_track_type_e type, GstCaps *caps)
 {
        GstPad *srcpad = NULL;
 
@@ -1211,25 +1385,25 @@ __mmplayer_create_sink_path(mmplayer_t *player, GstElement *selector, mmplayer_t
 
        LOGD("type %d", type);
 
-       if (!selector) {
+       if (!combiner) {
                LOGD("there is no %d track", type);
                return TRUE;
        }
 
-       srcpad = gst_element_get_static_pad(selector, "src");
+       srcpad = gst_element_get_static_pad(combiner, "src");
        if (!srcpad) {
-               LOGE("failed to get srcpad from selector");
+               LOGE("failed to get srcpad from combiner");
                return FALSE;
        }
 
-       LOGD("got pad %s:%s from selector", GST_DEBUG_PAD_NAME(srcpad));
+       LOGD("got pad %s:%s from combiner", GST_DEBUG_PAD_NAME(srcpad));
 
-       __mmplayer_gst_create_sinkbin(selector, srcpad, player);
+       __mmplayer_gst_create_sink_bin(combiner, srcpad, caps, player);
 
        LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
-       if (player->selector[type].block_id) {
-               gst_pad_remove_probe(srcpad, player->selector[type].block_id);
-               player->selector[type].block_id = 0;
+       if (player->track[type].block_id) {
+               gst_pad_remove_probe(srcpad, player->track[type].block_id);
+               player->track[type].block_id = 0;
        }
 
        if (srcpad) {
@@ -1244,35 +1418,26 @@ __mmplayer_create_sink_path(mmplayer_t *player, GstElement *selector, mmplayer_t
 static void
 __mmplayer_set_decode_track_info(mmplayer_t *player, mmplayer_track_type_e type)
 {
-       MMHandleType attrs = 0;
        gint active_index = 0;
 
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       LOGD("type: %d, the num of track: %d", type, player->selector[type].total_track_num);
+       LOGD("type: %d, the num of track: %d", type, player->track[type].total_track_num);
 
        /* change track to active pad */
-       active_index = player->selector[type].active_pad_index;
+       active_index = player->track[type].active_track_index;
        if ((active_index != DEFAULT_TRACK) &&
                (__mmplayer_change_selector_pad(player, type, active_index) != MM_ERROR_NONE)) {
                LOGW("failed to change %d type track to %d", type, active_index);
-               player->selector[type].active_pad_index = DEFAULT_TRACK;
+               player->track[type].active_track_index = DEFAULT_TRACK;
                return;
        }
 
-       if (type == MM_PLAYER_TRACK_TYPE_TEXT) {
-               attrs = MMPLAYER_GET_ATTRS(player);
-               if (attrs) {
-                       mm_attrs_set_int_by_name(attrs, "content_text_track_num", player->selector[type].total_track_num);
-                       mm_attrs_set_int_by_name(attrs, "current_text_track_index", player->selector[type].active_pad_index);
-
-                       if (mm_attrs_commit_all(attrs))
-                               LOGW("failed to commit attrs.");
-               } else {
-                       LOGW("cannot get content attribute");
-               }
-       }
+       if (type == MM_PLAYER_TRACK_TYPE_TEXT)
+               mm_player_set_attribute((MMHandleType)player, NULL,
+                               "content_text_track_num", player->track[type].total_track_num,
+                               "current_text_track_index", player->track[type].active_track_index, NULL);
 
        MMPLAYER_FLEAVE();
        return;
@@ -1299,16 +1464,17 @@ __mmplayer_create_audio_sink_path(mmplayer_t *player, GstElement *audio_selector
                }
 
                if (player->num_dynamic_pad == 0) /* FIXME: num_dynamic_pad is only for rtsp? */
-                       __mmplayer_pipeline_complete(NULL, player);
+                       _mmplayer_pipeline_complete(NULL, player);
 
                return TRUE;
        }
 
        /* apply the audio track information */
-       __mmplayer_set_decode_track_info(player, MM_PLAYER_TRACK_TYPE_AUDIO);
+       if (MMPLAYER_USE_DECODEBIN(player))
+               __mmplayer_set_decode_track_info(player, MM_PLAYER_TRACK_TYPE_AUDIO);
 
        /* create audio sink path */
-       if (!__mmplayer_create_sink_path(player, audio_selector, MM_PLAYER_TRACK_TYPE_AUDIO)) {
+       if (!__mmplayer_create_sink_path(player, audio_selector, MM_PLAYER_TRACK_TYPE_AUDIO, NULL)) {
                LOGE("failed to create audio sink path");
                return FALSE;
        }
@@ -1331,13 +1497,13 @@ __mmplayer_create_text_sink_path(mmplayer_t *player, GstElement *text_selector)
        /* apply the text track information */
        __mmplayer_set_decode_track_info(player, MM_PLAYER_TRACK_TYPE_TEXT);
 
-       if (player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num > 0)
+       if (player->track[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num > 0)
                player->has_closed_caption = TRUE;
 
        /* create text decode path */
        player->no_more_pad = TRUE;
 
-       if (!__mmplayer_create_sink_path(player, text_selector, MM_PLAYER_TRACK_TYPE_TEXT)) {
+       if (!__mmplayer_create_sink_path(player, text_selector, MM_PLAYER_TRACK_TYPE_TEXT, NULL)) {
                LOGE("failed to create text sink path");
                return FALSE;
        }
@@ -1360,7 +1526,7 @@ __mmplayer_gst_set_queue2_buffering(mmplayer_t *player)
 
        /* there is no mq, enable use-buffering on queue2 (ex) wav streaming
         * use file information was already set on Q2 when it was created. */
-       __mm_player_streaming_set_queue2(player->streamer,
+       _mm_player_streaming_set_queue2(player->streamer,
                                        player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst,
                                        TRUE,                                                           /* use_buffering */
                                        MUXED_BUFFER_TYPE_MAX,                          /* use previous buffer type setting */
@@ -1370,8 +1536,8 @@ __mmplayer_gst_set_queue2_buffering(mmplayer_t *player)
        return TRUE;
 }
 
-static void
-__mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data)
+void
+_mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data)
 {
        mmplayer_t *player = NULL;
        GstElement *video_selector = NULL;
@@ -1412,7 +1578,7 @@ __mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data)
        if (video_selector && !audio_selector && !text_selector)
                player->no_more_pad = TRUE;
 
-       if (!__mmplayer_create_sink_path(player, video_selector, MM_PLAYER_TRACK_TYPE_VIDEO))
+       if (!__mmplayer_create_sink_path(player, video_selector, MM_PLAYER_TRACK_TYPE_VIDEO, NULL))
                goto EXIT;
 
        /* create audio path followed by audio-select */
@@ -1426,11 +1592,7 @@ __mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data)
        __mmplayer_create_text_sink_path(player, text_selector);
 
 EXIT:
-       if (player->gapless.reconfigure) {
-               player->gapless.reconfigure = FALSE;
-               MMPLAYER_PLAYBACK_UNLOCK(player);
-       }
-
+       _mmplayer_set_reconfigure_state(player, FALSE);
        MMPLAYER_FLEAVE();
 }
 
@@ -1497,7 +1659,7 @@ EXIT:
 }
 
 static void
-__mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
+__mmplayer_gst_create_sink_bin(GstElement *elem, GstPad *pad, GstCaps *ref_caps, gpointer data)
 {
        mmplayer_t *player = NULL;
        GstCaps *caps = NULL;
@@ -1515,16 +1677,28 @@ __mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(elem && pad);
        MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && MMPLAYER_GET_ATTRS(player));
+       MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD(pad, caps, str, name, caps_ret);
+       if (!caps_ret) {
+               MMPLAYER_GST_GET_CAPS_INFO(ref_caps, str, name, caps_ret);
+               if (!caps_ret)
+                       goto ERROR;
 
-       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
-       if (!caps_ret)
-               goto ERROR;
+               caps = gst_caps_ref(ref_caps);
+       }
 
        caps_str = gst_caps_to_string(caps);
-
-       /* LOGD("detected mimetype : %s", name); */
+#ifdef __DEBUG__
+       LOGD("detected mimetype : %s", name);
+#endif
        if (strstr(name, "audio")) {
                if (player->pipeline->audiobin == NULL) {
+                       const gchar *audio_format = gst_structure_get_string(str, "format");
+                       if (audio_format) {
+                               LOGD("original audio format %s", audio_format);
+                               mm_player_set_attribute((MMHandleType)player, NULL,
+                                               "content_audio_format", audio_format, strlen(audio_format), NULL);
+                       }
+
                        if (__mmplayer_gst_create_audio_sink_bin(player) != MM_ERROR_NONE) {
                                LOGE("failed to create audiobin. continuing without audio");
                                goto ERROR;
@@ -1536,7 +1710,7 @@ __mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
                        reusing = TRUE;
                        sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
                        LOGD("reusing audiobin");
-                       __mmplayer_update_content_attrs(player, ATTR_AUDIO);
+                       _mmplayer_update_content_attrs(player, ATTR_AUDIO);
                }
        } else if (strstr(name, "video")) {
                /* 1. zero copy is updated at _decode_pad_added()
@@ -1547,26 +1721,14 @@ __mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
                        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 && player->video_overlay_resource == NULL) {
-                               LOGD("mark video overlay for acquire");
-                               if (mm_resource_manager_mark_for_acquire(player->resource_manager,
-                                               MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY,
-                                               MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
-                                               &player->video_overlay_resource)
-                                               != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                                       LOGE("could not mark video_overlay resource for acquire");
-                                       goto ERROR;
-                               }
+                       if ((surface_type == MM_DISPLAY_SURFACE_OVERLAY) &&
+                               (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE)) {
+                               LOGE("failed to acquire video overlay resource");
+                               goto ERROR;
                        }
 
                        player->interrupted_by_resource = FALSE;
 
-                       if (mm_resource_manager_commit(player->resource_manager) !=
-                                       MM_RESOURCE_MANAGER_ERROR_NONE) {
-                               LOGE("could not acquire resources for video playing");
-                               goto ERROR;
-                       }
-
                        if (__mmplayer_gst_create_video_sink_bin(player, caps, surface_type) != MM_ERROR_NONE) {
                                LOGE("failed to create videobin. continuing without video");
                                goto ERROR;
@@ -1578,7 +1740,7 @@ __mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
                        reusing = TRUE;
                        sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
                        LOGD("re-using videobin");
-                       __mmplayer_update_content_attrs(player, ATTR_VIDEO);
+                       _mmplayer_update_content_attrs(player, ATTR_VIDEO);
                }
        } else if (strstr(name, "text")) {
                if (player->pipeline->textbin == NULL) {
@@ -1623,7 +1785,7 @@ __mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
        LOGD("no more pads: %d, stream count dec : %d(num of dynamic pad)", player->no_more_pad, player->num_dynamic_pad);
 
        if ((player->no_more_pad) && (player->num_dynamic_pad == 0))
-               __mmplayer_pipeline_complete(NULL, player);
+               _mmplayer_pipeline_complete(NULL, player);
 
 ERROR:
 
@@ -1691,21 +1853,7 @@ __mmplayer_get_property_value_for_rotation(mmplayer_t *player, int display_angle
 }
 
 int
-__mmplayer_video_param_check_video_sink_bin(mmplayer_t *player)
-{
-       /* check video sinkbin is created */
-       MMPLAYER_RETURN_VAL_IF_FAIL(player &&
-               player->pipeline &&
-               player->pipeline->videobin &&
-               player->pipeline->videobin[MMPLAYER_V_BIN].gst &&
-               player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-               MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       return MM_ERROR_NONE;
-}
-
-int
-__mmplayer_get_video_angle(mmplayer_t *player, int *display_angle, int *orientation)
+_mmplayer_get_video_angle(mmplayer_t *player, int *display_angle, int *orientation)
 {
        int display_rotation = 0;
        gchar *org_orient = NULL;
@@ -1764,8 +1912,7 @@ __mmplayer_get_video_angle(mmplayer_t *player, int *display_angle, int *orientat
        return MM_ERROR_NONE;
 }
 
-void
-__mmplayer_video_param_set_display_rotation(mmplayer_t *player)
+static void __mmplayer_video_param_set_display_rotation(mmplayer_t *player)
 {
        int rotation_value = 0;
        int orientations = 0; // current supported angle values are 0, 90, 180, 270
@@ -1773,10 +1920,10 @@ __mmplayer_video_param_set_display_rotation(mmplayer_t *player)
        MMPLAYER_FENTER();
 
        /* check video sinkbin is created */
-       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
+       if (!_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_OVERLAY))
                return;
 
-       __mmplayer_get_video_angle(player, &display_angle, &orientations);
+       _mmplayer_get_video_angle(player, &display_angle, &orientations);
 
        /* get rotation value to set */
        __mmplayer_get_property_value_for_rotation(player, display_angle, orientations, &rotation_value);
@@ -1784,15 +1931,14 @@ __mmplayer_video_param_set_display_rotation(mmplayer_t *player)
        LOGD("set video param : rotate %d", rotation_value);
 }
 
-void
-__mmplayer_video_param_set_display_visible(mmplayer_t *player)
+static void __mmplayer_video_param_set_display_visible(mmplayer_t *player)
 {
        MMHandleType attrs = 0;
        int visible = 0;
        MMPLAYER_FENTER();
 
        /* check video sinkbin is created */
-       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
+       if (!_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_OVERLAY))
                return;
 
        attrs = MMPLAYER_GET_ATTRS(player);
@@ -1803,15 +1949,14 @@ __mmplayer_video_param_set_display_visible(mmplayer_t *player)
        LOGD("set video param : visible %d", visible);
 }
 
-void
-__mmplayer_video_param_set_display_method(mmplayer_t *player)
+static void __mmplayer_video_param_set_display_method(mmplayer_t *player)
 {
        MMHandleType attrs = 0;
        int display_method = 0;
        MMPLAYER_FENTER();
 
        /* check video sinkbin is created */
-       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
+       if (!_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_OVERLAY))
                return;
 
        attrs = MMPLAYER_GET_ATTRS(player);
@@ -1822,36 +1967,33 @@ __mmplayer_video_param_set_display_method(mmplayer_t *player)
        LOGD("set video param : method %d", display_method);
 }
 
-void
-__mmplayer_video_param_set_video_roi_area(mmplayer_t *player)
+static void __mmplayer_video_param_set_video_roi_area(mmplayer_t *player)
 {
        MMHandleType attrs = 0;
-       void *handle = NULL;
+       int handle = 0;
        MMPLAYER_FENTER();
 
        /* check video sinkbin is created */
-       if (__mmplayer_video_param_check_video_sink_bin(player) != MM_ERROR_NONE) {
-               LOGW("There is no video sink");
+       if (!_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_OVERLAY))
                return;
-       }
 
        attrs = MMPLAYER_GET_ATTRS(player);
        MMPLAYER_RETURN_IF_FAIL(attrs);
-       mm_attrs_get_data_by_name(attrs, "display_overlay", &handle);
-       if (handle) {
-               gst_video_overlay_set_video_roi_area(
-                        GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
-                        player->video_roi.scale_x, player->video_roi.scale_y, player->video_roi.scale_width, player->video_roi.scale_height);
-               LOGD("set video param : video roi area scale value: x(%f) y(%f) width(%f) height(%f)",
-                       player->video_roi.scale_x, player->video_roi.scale_y, player->video_roi.scale_width, player->video_roi.scale_height);
-       }
+
+       mm_attrs_get_int_by_name(attrs, "display_overlay", &handle);
+       MMPLAYER_RETURN_IF_FAIL(handle);
+
+       gst_video_overlay_set_video_roi_area(
+                GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
+                player->video_roi.scale_x, player->video_roi.scale_y, player->video_roi.scale_width, player->video_roi.scale_height);
+       LOGD("set video param : video roi area scale value: x(%f) y(%f) width(%f) height(%f)",
+               player->video_roi.scale_x, player->video_roi.scale_y, player->video_roi.scale_width, player->video_roi.scale_height);
 }
 
-void
-__mmplayer_video_param_set_roi_area(mmplayer_t *player)
+static void __mmplayer_video_param_set_roi_area(mmplayer_t *player)
 {
        MMHandleType attrs = 0;
-       void *handle = NULL;
+       int handle = 0;
        /*set wl_display*/
        int win_roi_x = 0;
        int win_roi_y = 0;
@@ -1860,74 +2002,67 @@ __mmplayer_video_param_set_roi_area(mmplayer_t *player)
        MMPLAYER_FENTER();
 
        /* check video sinkbin is created */
-       if (__mmplayer_video_param_check_video_sink_bin(player) != MM_ERROR_NONE) {
-               LOGW("There is no video sink");
+       if (!_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_OVERLAY))
                return;
-       }
 
        attrs = MMPLAYER_GET_ATTRS(player);
        MMPLAYER_RETURN_IF_FAIL(attrs);
 
-       mm_attrs_get_data_by_name(attrs, "display_overlay", &handle);
+       mm_attrs_get_int_by_name(attrs, "display_overlay", &handle);
+       MMPLAYER_RETURN_IF_FAIL(handle);
 
-       if (handle) {
-               /* It should be set after setting window */
-               mm_attrs_get_int_by_name(attrs, "display_win_roi_x", &win_roi_x);
-               mm_attrs_get_int_by_name(attrs, "display_win_roi_y", &win_roi_y);
-               mm_attrs_get_int_by_name(attrs, "display_win_roi_width", &win_roi_width);
-               mm_attrs_get_int_by_name(attrs, "display_win_roi_height", &win_roi_height);
+       /* It should be set after setting window */
+       mm_attrs_multiple_get(attrs, NULL,
+                               "display_win_roi_x", &win_roi_x,
+                               "display_win_roi_y", &win_roi_y,
+                               "display_win_roi_width", &win_roi_width,
+                               "display_win_roi_height", &win_roi_height, NULL);
 
-               /* After setting window handle, set display roi area */
-               gst_video_overlay_set_display_roi_area(
-                        GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
-                        win_roi_x, win_roi_y, win_roi_width, win_roi_height);
-               LOGD("set video param : roi area : x(%d) y(%d) width(%d) height(%d)",
-                       win_roi_x, win_roi_y, win_roi_width, win_roi_height);
-       }
+       /* After setting window handle, set display roi area */
+       gst_video_overlay_set_display_roi_area(
+                GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
+                win_roi_x, win_roi_y, win_roi_width, win_roi_height);
+       LOGD("set video param : roi area : x(%d) y(%d) width(%d) height(%d)",
+               win_roi_x, win_roi_y, win_roi_width, win_roi_height);
 }
 
-void
-__mmplayer_video_param_set_display_overlay(mmplayer_t *player)
+static void __mmplayer_video_param_set_display_overlay(mmplayer_t *player)
 {
        MMHandleType attrs = 0;
-       void *handle = NULL;
+       int handle = 0;
 
        /* check video sinkbin is created */
-       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
+       if (!_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_OVERLAY))
                return;
 
        attrs = MMPLAYER_GET_ATTRS(player);
        MMPLAYER_RETURN_IF_FAIL(attrs);
 
        /* common case if using overlay surface */
-       mm_attrs_get_data_by_name(attrs, "display_overlay", &handle);
-
-       if (handle) {
-               /* default is using wl_surface_id */
-               unsigned int wl_surface_id      = 0;
-               wl_surface_id = *(int *)handle;
-               LOGD("set video param : wl_surface_id %d", wl_surface_id);
-               gst_video_overlay_set_wl_window_wl_surface_id(
-                               GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
-                               *(int *)handle);
-       } else {
-               /* FIXIT : is it error case? */
-               LOGW("still we don't have a window handle on player attribute. create it's own surface.");
-       }
+       mm_attrs_get_int_by_name(attrs, "display_overlay", &handle);
+       MMPLAYER_RETURN_IF_FAIL(handle);
+
+       /* default is using wl_surface_id */
+       LOGD("set video param : wl_surface_id %d", handle);
+       gst_video_overlay_set_wl_window_wl_surface_id(
+                       GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
+                       handle);
 }
 
 int
-__mmplayer_update_wayland_videosink_video_param(mmplayer_t *player, char *param_name)
+_mmplayer_update_video_overlay_param(mmplayer_t *player, const char *param_name)
 {
        gboolean update_all_param = FALSE;
+
        MMPLAYER_FENTER();
 
-       /* check video sinkbin is created */
-       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
+       if (!_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_OVERLAY)) {
+               LOGW("videosink is not ready yet");
                return MM_ERROR_PLAYER_NOT_INITIALIZED;
+       }
 
        if (strcmp(player->ini.videosink_element_overlay, "tizenwlsink")) {
-               LOGE("can not find tizenwlsink");
+               LOGE("invalid videosink [%s]", player->ini.videosink_element_overlay);
                return MM_ERROR_PLAYER_INTERNAL;
        }
 
@@ -1948,61 +2083,22 @@ __mmplayer_update_wayland_videosink_video_param(mmplayer_t *player, char *param_
        if (update_all_param)
                __mmplayer_video_param_set_video_roi_area(player);
 
+
+       MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
 }
 
 int
-_mmplayer_update_video_param(mmplayer_t *player, char *param_name)
+_mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
 {
-       MMHandleType attrs = 0;
-       int surface_type = 0;
-       int ret = MM_ERROR_NONE;
+       gboolean disable_overlay = FALSE;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
-
-       /* check video sinkbin is created */
-       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
-               return MM_ERROR_PLAYER_NOT_INITIALIZED;
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if (!attrs) {
-               LOGE("cannot get content attribute");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-       LOGD("param_name : %s", param_name);
-
-       /* update display surface */
-       mm_attrs_get_int_by_name(attrs, "display_surface_type", &surface_type);
-       LOGD("check display surface type attribute: %d", surface_type);
-
-       /* configuring display */
-       switch (surface_type) {
-       case MM_DISPLAY_SURFACE_OVERLAY:
-               {
-                       ret = __mmplayer_update_wayland_videosink_video_param(player, param_name);
-                       if (ret != MM_ERROR_NONE)
-                               return ret;
-               }
-               break;
-       }
-
-       MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
-}
-
-int
-_mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
-{
-       gboolean disable_overlay = FALSE;
-       mmplayer_t *player = (mmplayer_t *)hplayer;
-       int ret = MM_ERROR_NONE;
-
-       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 */
+       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 */
 
        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");
@@ -2021,41 +2117,16 @@ _mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
                g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", TRUE, NULL);
 
                /* release overlay resource */
-               if (player->video_overlay_resource != NULL) {
-                       ret = mm_resource_manager_mark_for_release(player->resource_manager,
-                                       player->video_overlay_resource);
-                       if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                               LOGE("failed to mark overlay resource for release, ret(0x%x)", ret);
-                               goto ERROR;
-                       }
-                       player->video_overlay_resource = NULL;
-               }
-
-               ret = mm_resource_manager_commit(player->resource_manager);
-               if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                       LOGE("failed to commit acquiring of overlay resource, ret(0x%x)", ret);
+               if (__mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
+                       LOGE("failed to release overlay resource");
                        goto ERROR;
                }
        } else {
-               /* mark video overlay for acquire */
-               if (player->video_overlay_resource == NULL) {
-                       ret = mm_resource_manager_mark_for_acquire(player->resource_manager,
-                                       MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY,
-                                       MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
-                                       &player->video_overlay_resource);
-                       if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                               LOGE("could not prepare for video_overlay resource");
-                               goto ERROR;
-                       }
-               }
-
-               player->interrupted_by_resource = FALSE;
-               /* acquire resources for video overlay */
-               ret = mm_resource_manager_commit(player->resource_manager);
-               if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                       LOGE("could not acquire resources for video playing");
+               if (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
+                       LOGE("failed to acquire video overlay resource");
                        goto ERROR;
                }
+               player->interrupted_by_resource = FALSE;
 
                LOGD("enable overlay");
                __mmplayer_video_param_set_display_overlay(player);
@@ -2098,11 +2169,12 @@ _mmplayer_get_audio_only(MMHandleType hplayer, bool *paudio_only)
 }
 
 int
-__mmplayer_gst_element_link_bucket(GList *element_bucket)
+_mmplayer_gst_element_link_bucket(GList *element_bucket)
 {
        GList *bucket = element_bucket;
        mmplayer_gst_element_t *element = NULL;
        mmplayer_gst_element_t *prv_element = NULL;
+       GstElement *tee_element = NULL;
        gint successful_link_count = 0;
 
        MMPLAYER_FENTER();
@@ -2117,11 +2189,25 @@ __mmplayer_gst_element_link_bucket(GList *element_bucket)
 
                if (element && element->gst) {
                        if (prv_element && prv_element->gst) {
+                               if (strstr(GST_ELEMENT_NAME(element->gst), "audio-tee-queue") && strcmp(GST_ELEMENT_NAME(prv_element->gst), "audio-tee")) {
+                                       if (tee_element) {
+                                               prv_element->gst = tee_element;
+                                       } else {
+                                               LOGD("failed to make new audio branch - linking [%s] to [%s] is not supported",
+                                                       GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
+                                                       GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
+                                               return -1;
+                                       }
+                               }
                                if (gst_element_link(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst))) {
                                        LOGD("linking [%s] to [%s] success",
                                                GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
                                                GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
                                        successful_link_count++;
+                                       if (!strcmp(GST_ELEMENT_NAME(prv_element->gst), "audio-tee")) {
+                                               LOGD("keep audio-tee element for next audio pipeline branch");
+                                               tee_element = prv_element->gst;
+                                       }
                                } else {
                                        LOGD("linking [%s] to [%s] failed",
                                                GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
@@ -2140,7 +2226,7 @@ __mmplayer_gst_element_link_bucket(GList *element_bucket)
 }
 
 int
-__mmplayer_gst_element_add_bucket_to_bin(GstBin *bin, GList *element_bucket)
+_mmplayer_gst_element_add_bucket_to_bin(GstBin *bin, GList *element_bucket)
 {
        GList *bucket = element_bucket;
        mmplayer_gst_element_t *element = NULL;
@@ -2156,7 +2242,7 @@ __mmplayer_gst_element_add_bucket_to_bin(GstBin *bin, GList *element_bucket)
 
                if (element && element->gst) {
                        if (!gst_bin_add(bin, GST_ELEMENT(element->gst))) {
-                               LOGD("__mmplayer_gst_element_link_bucket : Adding element [%s]  to bin [%s] failed",
+                               LOGD("_mmplayer_gst_element_link_bucket : Adding element [%s]  to bin [%s] failed",
                                        GST_ELEMENT_NAME(GST_ELEMENT(element->gst)),
                                        GST_ELEMENT_NAME(GST_ELEMENT(bin)));
                                return 0;
@@ -2189,14 +2275,14 @@ __mmplayer_gst_caps_notify_cb(GstPad *pad, GParamSpec *unused, gpointer data)
        if (!caps)
                return;
 
-       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
+       MMPLAYER_GST_GET_CAPS_INFO_FROM_PAD(pad, caps, str, name, caps_ret);
        if (!caps_ret)
                goto ERROR;
 
        LOGD("name = %s", name);
 
        if (strstr(name, "audio")) {
-               __mmplayer_update_content_attrs(player, ATTR_AUDIO);
+               _mmplayer_update_content_attrs(player, ATTR_AUDIO);
 
                if (player->audio_stream_changed_cb) {
                        LOGE("call the audio stream changed cb");
@@ -2206,12 +2292,8 @@ __mmplayer_gst_caps_notify_cb(GstPad *pad, GParamSpec *unused, gpointer data)
                if ((name = gst_structure_get_string(str, "format")))
                        player->set_mode.video_zc = name[0] == 'S';
 
-               __mmplayer_update_content_attrs(player, ATTR_VIDEO);
-
-               if (player->video_stream_changed_cb) {
-                       LOGE("call the video stream changed cb");
-                       player->video_stream_changed_cb(player->video_stream_changed_cb_user_param);
-               }
+               _mmplayer_update_content_attrs(player, ATTR_VIDEO);
+               MMPLAYER_POST_MSG(player, MM_MESSAGE_VIDEO_STREAM_CHANGED, NULL);
        } else {
                LOGW("invalid caps info");
        }
@@ -2225,33 +2307,8 @@ ERROR:
        return;
 }
 
-/**
- * This function is to create audio pipeline for playing.
- *
- * @param      player          [in]    handle of player
- *
- * @return     This function returns zero on success.
- * @remark
- * @see                __mmplayer_gst_create_midi_pipeline, __mmplayer_gst_create_video_sink_bin
- */
-/* macro for code readability. just for sinkbin-creation functions */
-#define MMPLAYER_CREATE_ELEMENT(x_bin, x_id, x_factory, x_name, x_add_bucket, x_player) \
-       do {\
-               x_bin[x_id].id = x_id;\
-               x_bin[x_id].gst = gst_element_factory_make(x_factory, x_name);\
-               if (!x_bin[x_id].gst) {\
-                       LOGE("failed to create %s", x_factory);\
-                       goto ERROR;\
-               } else {\
-                       if (x_player->ini.set_dump_element_flag)\
-                               __mmplayer_add_dump_buffer_probe(x_player, x_bin[x_id].gst);\
-               } \
-               if (x_add_bucket)\
-                       element_bucket = g_list_append(element_bucket, &x_bin[x_id]);\
-       } while (0);
-
 void
-__mmplayer_audio_stream_clear_buffer(mmplayer_t *player, gboolean send_all)
+_mmplayer_audio_stream_clear_buffer(mmplayer_t *player, gboolean send_all)
 {
        GList *l = NULL;
 
@@ -2283,18 +2340,18 @@ __mmplayer_audio_stream_send_data(mmplayer_t *player, mmplayer_audio_stream_buff
        mmplayer_audio_decoded_data_info_t audio_stream = { 0, };
 
        MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player && player->audio_stream_render_cb);
+       MMPLAYER_RETURN_IF_FAIL(player && player->audio_decoded_cb);
 
        audio_stream.bitrate = a_buffer->bitrate;
        audio_stream.channel = a_buffer->channel;
-       audio_stream.depth = a_buffer->depth;
-       audio_stream.is_little_endian = a_buffer->is_little_endian;
        audio_stream.channel_mask = a_buffer->channel_mask;
        audio_stream.data_size = a_buffer->data_size;
        audio_stream.data = a_buffer->pcm_data;
-
-       /* LOGD("[%"G_GUINT64_FORMAT"] send data size:%d, %p", audio_stream.channel_mask, audio_stream.data_size, player->audio_stream_cb_user_param); */
-       player->audio_stream_render_cb(&audio_stream, player->audio_stream_cb_user_param);
+       audio_stream.pcm_format = a_buffer->pcm_format;
+#ifdef __DEBUG__
+       LOGD("[%"G_GUINT64_FORMAT"] send data size:%d, %p", audio_stream.channel_mask, audio_stream.data_size, player->audio_decoded_cb_user_param);
+#endif
+       player->audio_decoded_cb(&audio_stream, player->audio_decoded_cb_user_param);
 
        MMPLAYER_FLEAVE();
 }
@@ -2303,10 +2360,9 @@ static void
 __mmplayer_audio_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
+       const gchar *pcm_format = NULL;
        gint channel = 0;
        gint rate = 0;
-       gint depth = 0;
-       gint endianness = 0;
        guint64 channel_mask = 0;
        void *a_data = NULL;
        gint a_size = 0;
@@ -2315,7 +2371,7 @@ __mmplayer_audio_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer,
        GList *l = NULL;
 
        MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player && player->audio_stream_render_cb);
+       MMPLAYER_RETURN_IF_FAIL(player && player->audio_decoded_cb);
 
        gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
        a_data = mapinfo.data;
@@ -2323,12 +2379,12 @@ __mmplayer_audio_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer,
 
        GstCaps *caps = gst_pad_get_current_caps(pad);
        GstStructure *structure = gst_caps_get_structure(caps, 0);
-
-       /* MMPLAYER_LOG_GST_CAPS_TYPE(caps); */
+#ifdef __DEBUG__
+       MMPLAYER_LOG_GST_CAPS_TYPE(caps);
+#endif
+       pcm_format = gst_structure_get_string(structure, "format");
        gst_structure_get_int(structure, "rate", &rate);
        gst_structure_get_int(structure, "channels", &channel);
-       gst_structure_get_int(structure, "depth", &depth);
-       gst_structure_get_int(structure, "endianness", &endianness);
        gst_structure_get(structure, "channel-mask", GST_TYPE_BITMASK, &channel_mask, NULL);
        gst_caps_unref(GST_CAPS(caps));
 
@@ -2339,7 +2395,9 @@ __mmplayer_audio_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer,
                        mmplayer_audio_stream_buff_t *tmp = (mmplayer_audio_stream_buff_t *)l->data;
                        if (tmp) {
                                if (channel_mask == tmp->channel_mask) {
-                                       /* LOGD("[%"G_GUINT64_FORMAT"] total: %d, data: %d, buffer: %d", channel_mask, tmp->data_size, a_size, tmp->buff_size); */
+#ifdef __DEBUG__
+                                       LOGD("[%"G_GUINT64_FORMAT"] total: %d, data: %d, buffer: %d", channel_mask, tmp->data_size, a_size, tmp->buff_size);
+#endif
                                        if (tmp->data_size + a_size < tmp->buff_size) {
                                                memcpy(tmp->pcm_data + tmp->data_size, a_data, a_size);
                                                tmp->data_size += a_size;
@@ -2369,7 +2427,7 @@ __mmplayer_audio_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer,
                }
        }
 
-       /* create new audio stream data */
+       /* create new audio stream data for newly found audio channel */
        a_buffer = (mmplayer_audio_stream_buff_t *)g_try_malloc0(sizeof(mmplayer_audio_stream_buff_t));
        if (a_buffer == NULL) {
                LOGE("failed to alloc data.");
@@ -2377,12 +2435,11 @@ __mmplayer_audio_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer,
        }
        a_buffer->bitrate = rate;
        a_buffer->channel = channel;
-       a_buffer->depth = depth;
-       a_buffer->is_little_endian = (endianness == 1234 ? true : false);
        a_buffer->channel_mask = channel_mask;
        a_buffer->data_size = a_size;
+       a_buffer->pcm_format = _mmplayer_convert_audio_pcm_str_to_media_format_mime(pcm_format);
 
-       if (!player->audio_stream_sink_sync) {
+       if (player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK) {
                /* If sync is FALSE, use buffer list to reduce the IPC. */
                a_buffer->buff_size = (a_size > player->ini.pcm_buffer_size) ? (a_size) : (player->ini.pcm_buffer_size);
                a_buffer->pcm_data = g_try_malloc(a_buffer->buff_size);
@@ -2392,7 +2449,9 @@ __mmplayer_audio_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer,
                        goto DONE;
                }
                memcpy(a_buffer->pcm_data, a_data, a_size);
-               /* LOGD("new [%"G_GUINT64_FORMAT"] total:%d buff:%d", channel_mask, a_buffer->data_size, a_buffer->buff_size); */
+#ifdef __DEBUG__
+               LOGD("new [%"G_GUINT64_FORMAT"] total:%d buff:%d", channel_mask, a_buffer->data_size, a_buffer->buff_size);
+#endif
                player->audio_stream_buff_list = g_list_append(player->audio_stream_buff_list, a_buffer);
        } else {
                /* If sync is TRUE, send data directly. */
@@ -2443,22 +2502,39 @@ __mmplayer_gst_audio_deinterleave_pad_added(GstElement *elem, GstPad *pad, gpoin
                goto ERROR;
        }
 
-       LOGE("player->audio_stream_sink_sync: %d", player->audio_stream_sink_sync);
+       LOGE("audio_extract_opt : 0x%X", player->audio_extract_opt);
 
        gst_object_unref(sinkpad);
-       g_object_set(sink, "sync", player->audio_stream_sink_sync, NULL);
+       if (!(player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK))
+               g_object_set(sink, "sync", TRUE, NULL);
        g_object_set(sink, "signal-handoffs", TRUE, NULL);
 
-       gst_element_set_state(sink, GST_STATE_PAUSED);
-       gst_element_set_state(queue, GST_STATE_PAUSED);
+       /* keep the first sink reference only */
+       if (!audiobin[MMPLAYER_A_SINK].gst) {
+               audiobin[MMPLAYER_A_SINK].id = MMPLAYER_A_SINK;
+               audiobin[MMPLAYER_A_SINK].gst = sink;
+       }
+
 
-       __mmplayer_add_signal_connection(player,
+       _mmplayer_add_signal_connection(player,
                G_OBJECT(sink),
                MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
                "handoff",
                G_CALLBACK(__mmplayer_audio_stream_decoded_render_cb),
                (gpointer)player);
 
+       __mmplayer_add_sink(player, sink);
+
+       if (gst_element_sync_state_with_parent(queue) == GST_STATE_CHANGE_FAILURE) {
+               LOGE("failed to sync state");
+               goto ERROR;
+       }
+
+       if (gst_element_sync_state_with_parent(sink) == GST_STATE_CHANGE_FAILURE) {
+               LOGE("failed to sync state");
+               goto ERROR;
+       }
+
        MMPLAYER_FLEAVE();
        return;
 
@@ -2481,9 +2557,25 @@ ERROR:
 }
 
 void
-__mmplayer_gst_set_pulsesink_property(mmplayer_t *player, MMHandleType attrs)
+__mmplayer_gst_audio_deinterleave_no_more_pads(GstElement* object, gpointer data)
+{
+       mmplayer_t *player = (mmplayer_t *)data;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
+
+       player->no_more_pad = TRUE;
+       _mmplayer_pipeline_complete(NULL, player);
+
+       MMPLAYER_FLEAVE();
+       return;
+}
+
+void
+__mmplayer_gst_set_pulsesink_property(mmplayer_t *player)
 {
        #define MAX_PROPS_LEN 128
+       mmplayer_gst_element_t *audiobin = NULL;
        gint latency_mode = 0;
        gchar *stream_type = NULL;
        gchar *latency = NULL;
@@ -2498,37 +2590,48 @@ __mmplayer_gst_set_pulsesink_property(mmplayer_t *player, MMHandleType attrs)
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->audiobin);
 
-       mm_attrs_get_int_by_name(attrs, "sound_stream_index", &stream_id);
-       mm_attrs_get_string_by_name(attrs, "sound_stream_type", &stream_type);
+       audiobin = player->pipeline->audiobin;
 
-       if (!stream_type) {
-               LOGE("stream_type is null.");
-       } else {
-               snprintf(stream_props, sizeof(stream_props) - 1, "props,media.role=%s, media.parent_id=%d",
-                               stream_type, stream_id);
-               props = gst_structure_from_string(stream_props, NULL);
-               g_object_set(player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "stream-properties", props, NULL);
-               LOGI("stream_type[%s], stream_id[%d], result[%s].", stream_type, stream_id, stream_props);
-               gst_structure_free(props);
+       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "volume", player->sound.volume, NULL);
+       if (player->sound.mute) {
+               LOGD("mute enabled");
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "mute", player->sound.mute, NULL);
        }
 
-       mm_attrs_get_int_by_name(attrs, "sound_latency_mode", &latency_mode);
+       mm_attrs_get_int_by_name(player->attrs, "sound_stream_index", &stream_id);
+       mm_attrs_get_string_by_name(player->attrs, "sound_stream_type", &stream_type);
+
+       if (!stream_type)
+               snprintf(stream_props, sizeof(stream_props) - 1,
+                               "props,application.process.id.origin=%d", player->client_pid);
+       else
+               snprintf(stream_props, sizeof(stream_props) - 1,
+                               "props,media.role=%s, media.parent_id=%d, application.process.id.origin=%d",
+                               stream_type, stream_id, player->client_pid);
+
+       props = gst_structure_from_string(stream_props, NULL);
+       g_object_set(audiobin[MMPLAYER_A_SINK].gst, "stream-properties", props, NULL);
+       LOGI("props result[%s].", stream_props);
+       gst_structure_free(props);
+
+       mm_attrs_get_int_by_name(player->attrs, "sound_latency_mode", &latency_mode);
 
        switch (latency_mode) {
        case AUDIO_LATENCY_MODE_LOW:
-               latency = g_strndup("low", 3);
+               latency = g_strdup("low");
                break;
        case AUDIO_LATENCY_MODE_MID:
-               latency = g_strndup("mid", 3);
+               latency = g_strdup("mid");
                break;
        case AUDIO_LATENCY_MODE_HIGH:
-               latency = g_strndup("high", 4);
+               latency = g_strdup("high");
+               break;
+       default:
+               latency = g_strdup("mid");
                break;
        };
 
-       g_object_set(player->pipeline->audiobin[MMPLAYER_A_SINK].gst,
-                       "latency", latency,
-                       NULL);
+       g_object_set(audiobin[MMPLAYER_A_SINK].gst, "latency", latency, NULL);
 
        LOGD("audiosink property - latency=%s", latency);
 
@@ -2537,18 +2640,23 @@ __mmplayer_gst_set_pulsesink_property(mmplayer_t *player, MMHandleType attrs)
        MMPLAYER_FLEAVE();
 }
 
-void
+int
 __mmplayer_gst_set_openalsink_property(mmplayer_t *player)
 {
        mmplayer_gst_element_t *audiobin = NULL;
 
        MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->audiobin);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
        audiobin = player->pipeline->audiobin;
 
        g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "source-ambisonics-type", 1, NULL);
-       sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &stream_info);
+       if (sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &stream_info)) {
+               LOGE("failed to create media stream info");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
        g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "stream-info", stream_info, NULL);
 
        if (player->video360_yaw_radians <= M_PI &&
@@ -2565,16 +2673,16 @@ __mmplayer_gst_set_openalsink_property(mmplayer_t *player)
        }
 
        MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
 }
 
 static int
-__mmplayer_gst_fill_audio_bucket(mmplayer_t *player, GList **bucket)
+__mmplayer_gst_make_audio_playback_sink(mmplayer_t *player, GList **bucket)
 {
        mmplayer_gst_element_t *audiobin = NULL;
-       MMHandleType attrs = 0;
-       GList *element_bucket = NULL;
-       GstCaps *acaps = NULL;
        GstPad *sink_pad = NULL;
+       GstCaps *acaps = NULL;
+       gint channels = 0;
        int pitch_control = 0;
        double pitch_value = 1.0;
 
@@ -2583,17 +2691,17 @@ __mmplayer_gst_fill_audio_bucket(mmplayer_t *player, GList **bucket)
                                player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
        audiobin = player->pipeline->audiobin;
-       attrs = MMPLAYER_GET_ATTRS(player);
 
-       if (player->build_audio_offload) { /* skip all the audio filters */
-               LOGD("create audio offload sink : %s", player->ini.audio_offload_sink_element);
-               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.audio_offload_sink_element, "audiosink", TRUE, player);
-               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "sync", TRUE, NULL);
-               __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst);
-               goto DONE;
-       }
+       LOGD("make element for normal audio playback");
+
+       /* audio bin structure for playback. {} means optional.
+          optional : pitch, audioeq, custom audioeq, openalsink for 360 audio content
+
+        * src - ... - {aconv - pitch} - aconv - rgvolume - resample - volume -
+                       {audioeq} - {custom audioeq} - pulsesink or {aconv - capsfilter - openalsink}
+        */
 
-       /* pitch */
+       /* for pitch control */
        mm_attrs_multiple_get(player->attrs, NULL,
                                MM_PLAYER_PITCH_CONTROL, &pitch_control,
                                MM_PLAYER_PITCH_VALUE, &pitch_value,
@@ -2608,10 +2716,10 @@ __mmplayer_gst_fill_audio_bucket(mmplayer_t *player, GList **bucket)
                        gst_object_unref(factory);
 
                        /* converter */
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV_PITCH, "audioconvert", "audio convert pitch", TRUE, player);
+                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV_PITCH, "audioconvert", "audio convert pitch", *bucket, player);
 
                        /* pitch */
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_PITCH, "pitch", "audio pitch", TRUE, player);
+                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_PITCH, "pitch", "audio pitch", *bucket, player);
                        g_object_set(G_OBJECT(audiobin[MMPLAYER_A_PITCH].gst), "pitch", (gdouble)pitch_value, NULL);
                } else {
                        LOGW("there is no pitch element");
@@ -2619,158 +2727,314 @@ __mmplayer_gst_fill_audio_bucket(mmplayer_t *player, GList **bucket)
        }
 
        /* converter */
-       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audio converter", TRUE, player);
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audio converter", *bucket, player);
 
        /* replaygain volume */
-       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RGVOL, "rgvolume", "audio rgvolume", TRUE, player);
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RGVOL, "rgvolume", "audio rgvolume", *bucket, player);
        if (player->sound.rg_enable)
                g_object_set(G_OBJECT(audiobin[MMPLAYER_A_RGVOL].gst), "enable-rgvolume", TRUE, NULL);
        else
                g_object_set(G_OBJECT(audiobin[MMPLAYER_A_RGVOL].gst), "enable-rgvolume", FALSE, NULL);
 
        /* resampler */
-       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RESAMPLER,  player->ini.audioresampler_element, "audio resampler", TRUE, player);
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RESAMPLER,  player->ini.audioresampler_element, "audio resampler", *bucket, player);
 
-       if (player->audio_stream_render_cb) { /* pcm extraction only, no sound output */
-               gchar *dst_format = NULL;
-               int dst_len = 0;
-               int dst_samplerate = 0;
-               int dst_channels = 0;
-               GstCaps *caps = NULL;
-               char *caps_str = NULL;
+       if (g_strrstr(player->ini.audiosink_element, "openalsink")) {
+               /* currently, only openalsink uses volume element */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_VOL, "volume", "volume", *bucket, player);
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "volume", player->sound.volume, NULL);
 
-               /* get conf. values */
-               mm_attrs_multiple_get(player->attrs, NULL,
-                                       "pcm_audioformat", &dst_format, &dst_len,
-                                       "pcm_extraction_samplerate", &dst_samplerate,
-                                       "pcm_extraction_channels", &dst_channels,
-                                       NULL);
+               if (player->sound.mute) {
+                       LOGD("mute enabled");
+                       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
+               }
+       }
 
-               LOGD("pcm info - format: %s(%d), samplerate : %d, channel: %d", dst_format, dst_len, dst_samplerate, dst_channels);
+       mm_attrs_get_int_by_name(player->attrs, "content_audio_channels", &channels);
 
-               /* capsfilter */
-               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audio capsfilter", TRUE, player);
-               caps = gst_caps_new_simple("audio/x-raw",
-                               "format", G_TYPE_STRING, dst_format,
-                               "rate", G_TYPE_INT, dst_samplerate,
-                               "channels", G_TYPE_INT, dst_channels,
-                               NULL);
+       /* audio effect element. if audio effect is enabled */
+       if ((strcmp(player->ini.audioeffect_element, ""))
+               && (channels <= 2)
+               && (player->ini.use_audio_effect_preset || player->ini.use_audio_effect_custom)) {
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER, player->ini.audioeffect_element, "audio effect filter", *bucket, player);
 
-               caps_str = gst_caps_to_string(caps);
-               LOGD("new caps : %s", caps_str);
+               LOGD("audio effect config. bypass = %d, effect type = %d", player->bypass_audio_effect, player->audio_effect_info.effect_type);
 
-               g_object_set(GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL);
+               if ((!player->bypass_audio_effect)
+                       && (player->ini.use_audio_effect_preset || player->ini.use_audio_effect_custom)) {
+                       if (player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM) {
+                               if (!_mmplayer_audio_effect_custom_apply(player))
+                                       LOGI("apply audio effect(custom) setting success");
+                       }
+               }
 
-               /* clean */
-               gst_caps_unref(caps);
-               MMPLAYER_FREEIF(caps_str);
+               if ((strcmp(player->ini.audioeffect_element_custom, ""))
+                       && (player->set_mode.rich_audio)) {
+                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER_SEC, player->ini.audioeffect_element_custom, "audio effect filter custom", *bucket, player);
+               }
+       }
 
-               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_DEINTERLEAVE, "deinterleave", "deinterleave", TRUE, player);
+       /* create audio sink */
+       LOGD("spherical %d, channels %d, ambisonic type %d, format %d, order %d",
+                       player->is_content_spherical, channels, player->video360_metadata.ambisonic_type,
+                       player->video360_metadata.ambisonic_format, player->video360_metadata.ambisonic_order);
 
-               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_DEINTERLEAVE].gst), "keep-positions", TRUE, NULL);
+       /* Note: qtdemux converts audio metadata defaults to openalsink defaults. */
+       if (player->is_360_feature_enabled &&
+               player->is_content_spherical &&
+               channels == 4 &&
+               player->video360_metadata.ambisonic_type == MMFILE_AMBISONIC_TYPE_PERIPHONIC &&
+               player->video360_metadata.ambisonic_format == MMFILE_AMBISONIC_FORMAT_AMB &&
+               player->video360_metadata.ambisonic_order == MMFILE_AMBISONIC_ORDER_FOA) {
 
-               /* raw pad handling signal, audiosink will be added after getting signal */
-               __mmplayer_add_signal_connection(player, G_OBJECT(audiobin[MMPLAYER_A_DEINTERLEAVE].gst),
-                               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added", G_CALLBACK(__mmplayer_gst_audio_deinterleave_pad_added), (gpointer)player);
+               strncpy(player->ini.audiosink_element, "openalsink", PLAYER_INI_MAX_STRLEN - 1);
+
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV_BFORMAT, "audioconvert", "audio-converter-bformat", *bucket, player);
 
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_360, "capsfilter", "audio-caps-filter", *bucket, player);
+               acaps = gst_caps_from_string(SPATIAL_AUDIO_CAPS);
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_CAPS_360].gst), "caps", acaps, NULL);
+               gst_caps_unref(acaps);
+
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "openalsink", "audiosink", *bucket, player);
+
+               player->is_openal_plugin_used = TRUE;
        } else {
+               if (player->is_360_feature_enabled && player->is_content_spherical)
+                       LOGW("Audio track isn't of the ambisonic type and can't be played back as a spatial sound.");
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.audiosink_element, "audiosink", *bucket, player);
+       }
 
-               /* normal playback */
-               gint channels = 0;
+       if ((MMPLAYER_IS_RTSP_STREAMING(player)) ||
+               (player->videodec_linked && player->ini.use_system_clock)) {
+               LOGD("system clock will be used.");
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "provide-clock", FALSE,  NULL);
+       }
 
-               /* for logical volume control */
-               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_VOL, "volume", "volume", TRUE, player);
-               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "volume", player->sound.volume, NULL);
+       if (g_strrstr(player->ini.audiosink_element, "pulsesink")) {
+               __mmplayer_gst_set_pulsesink_property(player);
+       } else if (g_strrstr(player->ini.audiosink_element, "openalsink")) {
+               if (__mmplayer_gst_set_openalsink_property(player) != MM_ERROR_NONE)
+                       goto ERROR;
+       }
 
-               if (player->sound.mute) {
-                       LOGD("mute enabled");
-                       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
-               }
+       /* qos on */
+       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL);       /* qos on */
+       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "slave-method", GST_AUDIO_BASE_SINK_SLAVE_NONE, NULL);
 
-               mm_attrs_get_int_by_name(player->attrs, "content_audio_channels", &channels);
+       sink_pad = gst_element_get_static_pad(audiobin[MMPLAYER_A_SINK].gst, "sink");
+       _mmplayer_add_signal_connection(player, G_OBJECT(sink_pad), MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
+                               "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), (gpointer)player);
+       gst_object_unref(GST_OBJECT(sink_pad));
 
-               /* audio effect element. if audio effect is enabled */
-               if ((strcmp(player->ini.audioeffect_element, ""))
-                       && (channels <= 2)
-                       && (player->ini.use_audio_effect_preset || player->ini.use_audio_effect_custom)) {
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER, player->ini.audioeffect_element, "audio effect filter", TRUE, player);
+       __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst);
 
-                       LOGD("audio effect config. bypass = %d, effect type  = %d", player->bypass_audio_effect, player->audio_effect_info.effect_type);
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
 
-                       if ((!player->bypass_audio_effect)
-                               && (player->ini.use_audio_effect_preset || player->ini.use_audio_effect_custom)) {
-                               if (player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM) {
-                                       if (!_mmplayer_audio_effect_custom_apply(player))
-                                               LOGI("apply audio effect(custom) setting success");
-                               }
-                       }
+ERROR: /* MMPLAYER_CREATE_ELEMENT */
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_PLAYER_INTERNAL;
+}
 
-                       if ((strcmp(player->ini.audioeffect_element_custom, ""))
-                               && (player->set_mode.rich_audio))
-                               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER_SEC, player->ini.audioeffect_element_custom, "audio effect filter custom", TRUE, player);
-               }
+static int
+__mmplayer_gst_make_audio_extract_sink(mmplayer_t *player, GList **bucket)
+{
+       mmplayer_gst_element_t *audiobin = NULL;
+       enum audio_element_id extract_sink_id = MMPLAYER_A_SINK;
 
-               /* create audio sink */
-               LOGD("360 spherical %d, channels %d, ambisonic type %d, format %d, order %d",
-                               player->is_content_spherical, channels, player->video360_metadata.ambisonic_type,
-                               player->video360_metadata.ambisonic_format, player->video360_metadata.ambisonic_order);
+       gchar *dst_format = NULL;
+       int dst_len = 0;
+       int dst_samplerate = 0;
+       int dst_channels = 0;
+       GstCaps *caps = NULL;
+       char *caps_str = NULL;
 
-               /* Note: qtdemux converts audio metadata defaults to openalsink defaults. */
-               if (player->is_360_feature_enabled &&
-                       player->is_content_spherical &&
-                       channels == 4 &&
-                       player->video360_metadata.ambisonic_type == MMFILE_AMBISONIC_TYPE_PERIPHONIC &&
-                       player->video360_metadata.ambisonic_format == MMFILE_AMBISONIC_FORMAT_AMB &&
-                       player->video360_metadata.ambisonic_order == MMFILE_AMBISONIC_ORDER_FOA) {
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-                       strncpy(player->ini.audiosink_element, "openalsink", PLAYER_INI_MAX_STRLEN - 1);
+       audiobin = player->pipeline->audiobin;
 
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV_BFORMAT, "audioconvert", "audio-converter-bformat", TRUE, player);
+       LOGD("make element for audio extract, option = 0x%X", player->audio_extract_opt);
 
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_360, "capsfilter", "audio-caps-filter", TRUE, player);
-                       acaps = gst_caps_from_string(SPATIAL_AUDIO_CAPS);
-                       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_CAPS_360].gst), "caps", acaps, NULL);
-                       gst_caps_unref(acaps);
+       /* audio bin structure according to the mmplayer_audio_extract_opt_e.
 
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "openalsink", "audiosink", TRUE, player);
+          [case 1] extract interleave audio pcm without playback
+                               : MM_PLAYER_AUDIO_EXTRACT_DEFAULT (sync)
+                                 MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK (non sync)
 
-                       player->is_openal_plugin_used = TRUE;
-               } else {
-                       if (player->is_360_feature_enabled && player->is_content_spherical)
-                               LOGW("Audio track isn't of the ambisonic type and can't be played back as a spatial sound.");
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.audiosink_element, "audiosink", TRUE, player);
-               }
+                               * src - ... - aconv - resample - capsfilter - fakesink (sync or not)
+
+          [case 2] deinterleave for each channel without playback
+                               : MM_PLAYER_AUDIO_EXTRACT_DEINTERLEAVE (sync)
+                                 MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_AND_DEINTERLEAVE (non sync)
+
+                               * src - ... - aconv - resample - capsfilter - deinterleave - fakesink (sync or not)
+                                                                                                                                                  - fakesink (sync or not)
+                                                                                                                                                  - ...      (sync or not)
+
+          [case 3] [case 1(sync only)] + playback
+                               : MM_PLAYER_AUDIO_EXTRACT_WITH_PLAYBACK
+
+                               * src - ... - tee - queue1 - playback path
+                                                                 - queue2 - [case1 pipeline with sync]
+
+          [case 4] [case 2(sync only)] + playback
+                               : MM_PLAYER_AUDIO_EXTRACT_DEINTERLEAVE_WITH_PLAYBACK
+
+                               * src - ... - tee - queue1 - playback path
+                                                                 - queue2 - [case2 pipeline with sync]
+
+        */
+
+       /* 1. create tee and playback path
+             'tee' should be added at first to copy the decoded stream
+        */
+       if (player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_WITH_PLAYBACK) {
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TEE, "tee", "audio-tee", *bucket, player);
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_TEE].gst), "num-src-pads", 2, NULL);
 
-               if ((MMPLAYER_IS_RTSP_STREAMING(player)) ||
-                       (player->videodec_linked && player->ini.use_system_clock)) {
-                       LOGD("system clock will be used.");
-                       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "provide-clock", FALSE,  NULL);
+               /* tee - path 1 : for playback path */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TEE_Q1, "queue", "audio-tee-queue1", *bucket, player);
+               __mmplayer_gst_make_audio_playback_sink(player, bucket);
+
+               /* tee - path 2 : for extract path */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TEE_Q2, "queue", "audio-tee-queue2", *bucket, player);
+               extract_sink_id = MMPLAYER_A_EXTRACT_SINK; /* there is another playback sink */
+       }
+
+       /* if there is tee, 'tee - path 2' is linked here */
+       /* converter */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_EXTRACT_CONV, "audioconvert", "audio-ext-conv", *bucket, player);
+
+       /* resampler */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_EXTRACT_RESAMPLER,  player->ini.audioresampler_element, "audio-ext-resampler", *bucket, player);
+
+       /* 2. decide the extract pcm format */
+       mm_attrs_multiple_get(player->attrs, NULL,
+                               MM_PLAYER_PCM_EXT_FORMAT, &dst_format, &dst_len,
+                               MM_PLAYER_PCM_EXT_SAMPLERATE, &dst_samplerate,
+                               MM_PLAYER_PCM_EXT_CHANNELS, &dst_channels,
+                               NULL);
+
+       LOGD("required extract pcm format - format: %s(%d), samplerate : %d, channel: %d",
+                       dst_format, dst_len, dst_samplerate, dst_channels);
+
+       if (dst_format == NULL || dst_len == 0 || dst_samplerate == 0 || dst_channels == 0) {
+               mm_attrs_multiple_get(player->attrs, NULL,
+                                       "content_audio_format", &dst_format, &dst_len, /* get string and len */
+                                       "content_audio_samplerate", &dst_samplerate,
+                                       "content_audio_channels", &dst_channels,
+                                       NULL);
+
+               LOGD("apply the decoded pcm format - format: %s(%d), samplerate : %d, channel: %d",
+                               dst_format, dst_len, dst_samplerate, dst_channels);
+
+               /* If there is no enough information, set it to platform default value. */
+               if (dst_format == NULL || _mmplayer_convert_audio_pcm_str_to_media_format_mime(dst_format) == MEDIA_FORMAT_MAX) {
+                       LOGD("set platform default format");
+                       dst_format = DEFAULT_PCM_OUT_FORMAT;
                }
+               if (dst_samplerate <= 0) dst_samplerate = DEFAULT_PCM_OUT_SAMPLERATE;
+               if (dst_channels <= 0)   dst_channels = DEFAULT_PCM_OUT_CHANNEL;
+       }
 
-               if (g_strrstr(player->ini.audiosink_element, "pulsesink"))
-                       __mmplayer_gst_set_pulsesink_property(player, attrs);
-               else if (g_strrstr(player->ini.audiosink_element, "openalsink"))
-                       __mmplayer_gst_set_openalsink_property(player);
+       /* 3. create capsfilter */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_EXTRACT_CAPS, "capsfilter", "audio-ext-caps", *bucket, player);
+       caps = gst_caps_new_simple("audio/x-raw",
+                       "format", G_TYPE_STRING, dst_format,
+                       "rate", G_TYPE_INT, dst_samplerate,
+                       "channels", G_TYPE_INT, dst_channels,
+                       NULL);
 
-               /* qos on */
-               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL);       /* qos on */
-               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "slave-method", GST_AUDIO_BASE_SINK_SLAVE_NONE, NULL);
+       caps_str = gst_caps_to_string(caps);
+       LOGD("new caps : %s", caps_str);
 
-               sink_pad = gst_element_get_static_pad(audiobin[MMPLAYER_A_SINK].gst, "sink");
-               __mmplayer_add_signal_connection(player, G_OBJECT(sink_pad), MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
-                                       "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), (gpointer)player);
-               gst_object_unref(GST_OBJECT(sink_pad));
+       g_object_set(GST_ELEMENT(audiobin[MMPLAYER_A_EXTRACT_CAPS].gst), "caps", caps, NULL);
+
+       /* clean */
+       gst_caps_unref(caps);
+       MMPLAYER_FREEIF(caps_str);
+
+       /* 4-1. create deinterleave to extract pcm for each channel */
+       if (player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_DEINTERLEAVE) {
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_EXTRACT_DEINTERLEAVE, "deinterleave", "deinterleave", *bucket, player);
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_EXTRACT_DEINTERLEAVE].gst), "keep-positions", TRUE, NULL);
+
+               /* audiosink will be added after getting signal for each channel */
+               _mmplayer_add_signal_connection(player, G_OBJECT(audiobin[MMPLAYER_A_EXTRACT_DEINTERLEAVE].gst),
+                               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added", G_CALLBACK(__mmplayer_gst_audio_deinterleave_pad_added), (gpointer)player);
+               _mmplayer_add_signal_connection(player, G_OBJECT(audiobin[MMPLAYER_A_EXTRACT_DEINTERLEAVE].gst),
+                               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 */
+               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))
+                       g_object_set(G_OBJECT(audiobin[extract_sink_id].gst), "sync", TRUE, NULL);
+               g_object_set(G_OBJECT(audiobin[extract_sink_id].gst), "signal-handoffs", TRUE, NULL);
+
+               _mmplayer_add_signal_connection(player,
+                       G_OBJECT(audiobin[extract_sink_id].gst),
+                       MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
+                       "handoff",
+                       G_CALLBACK(__mmplayer_audio_stream_decoded_render_cb),
+                       (gpointer)player);
+
+               __mmplayer_add_sink(player, audiobin[extract_sink_id].gst);
+       }
+
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+
+ERROR: /* MMPLAYER_CREATE_ELEMENT */
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+static int
+__mmplayer_gst_make_audio_bin_element(mmplayer_t *player, GList **bucket)
+{
+       int ret = MM_ERROR_NONE;
+       mmplayer_gst_element_t *audiobin = NULL;
+       GList *element_bucket = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       audiobin = player->pipeline->audiobin;
+
+       if (player->build_audio_offload) { /* skip all the audio filters */
+               LOGD("create audio offload sink : %s", player->ini.audio_offload_sink_element);
+
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.audio_offload_sink_element, "audiosink", element_bucket, player);
+               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);
+               goto DONE;
        }
 
+       /* FIXME: need to mention the supportable condition at API reference */
+       if (player->audio_decoded_cb && (!MMPLAYER_IS_RTSP_STREAMING(player)))
+               ret = __mmplayer_gst_make_audio_extract_sink(player, &element_bucket);
+       else
+               ret = __mmplayer_gst_make_audio_playback_sink(player, &element_bucket);
+
+       if (ret != MM_ERROR_NONE)
+               goto ERROR;
 DONE:
+       LOGD("success to make audio bin element");
        *bucket = element_bucket;
 
        MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
 
 ERROR:
+       LOGE("failed to make audio bin element");
        g_list_free(element_bucket);
 
        *bucket = NULL;
@@ -2810,17 +3074,17 @@ __mmplayer_gst_create_audio_sink_bin(mmplayer_t *player)
        player->pipeline->audiobin = audiobin;
 
        /* create audio filters and audiosink */
-       if (__mmplayer_gst_fill_audio_bucket(player, &element_bucket) != MM_ERROR_NONE)
+       if (__mmplayer_gst_make_audio_bin_element(player, &element_bucket) != MM_ERROR_NONE)
                goto ERROR;
 
        /* adding created elements to bin */
        LOGD("adding created elements to bin");
-       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(audiobin[MMPLAYER_A_BIN].gst), element_bucket))
+       if (!_mmplayer_gst_element_add_bucket_to_bin(GST_BIN(audiobin[MMPLAYER_A_BIN].gst), element_bucket))
                goto ERROR;
 
        /* linking elements in the bucket by added order. */
        LOGD("Linking elements in the bucket by added order.");
-       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1)
+       if (_mmplayer_gst_element_link_bucket(element_bucket) == -1)
                goto ERROR;
 
        /* get first element's sinkpad for creating ghostpad */
@@ -2929,27 +3193,27 @@ _mmplayer_video_stream_release_bo(mmplayer_t *player, void *bo)
        LOGW("failed to find bo %p", bo);
        return ret;
 }
+static void
+__mmplayer_video_stream_bo_list_free(mmplayer_video_bo_info_t *tmp)
+{
+       if (!tmp)
+               return;
+
+       if (tmp->bo)
+               tbm_bo_unref(tmp->bo);
+       g_free(tmp);
+}
 
 static void
 __mmplayer_video_stream_destroy_bo_list(mmplayer_t *player)
 {
-       GList *l = NULL;
-
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
 
        MMPLAYER_VIDEO_BO_LOCK(player);
        if (player->video_bo_list) {
                LOGD("destroy video_bo_list : %d", g_list_length(player->video_bo_list));
-               for (l = g_list_first(player->video_bo_list); l; l = g_list_next(l)) {
-                       mmplayer_video_bo_info_t *tmp = (mmplayer_video_bo_info_t *)l->data;
-                       if (tmp) {
-                               if (tmp->bo)
-                                       tbm_bo_unref(tmp->bo);
-                               g_free(tmp);
-                       }
-               }
-               g_list_free(player->video_bo_list);
+               g_list_free_full(player->video_bo_list, (GDestroyNotify)__mmplayer_video_stream_bo_list_free);
                player->video_bo_list = NULL;
        }
        player->video_bo_size = 0;
@@ -3005,16 +3269,16 @@ __mmplayer_video_stream_get_bo(mmplayer_t *player, int size)
                }
 
                /* update video num buffers */
-               player->video_num_buffers = idx;
-               if (idx == player->ini.num_of_video_bo)
-                       player->video_extra_num_buffers = player->ini.num_of_video_bo/2;
+               LOGD("video_num_buffers : %d", idx);
+               mm_player_set_attribute((MMHandleType)player, NULL,
+                               MM_PLAYER_VIDEO_BUFFER_TOTAL_SIZE, idx,
+                               MM_PLAYER_VIDEO_BUFFER_EXTRA_SIZE, MAX(DEFAULT_NUM_OF_V_OUT_BUFFER, (idx / 2)),
+                               NULL);
 
                if (idx == 0) {
                        MMPLAYER_VIDEO_BO_UNLOCK(player);
                        return NULL;
                }
-
-               LOGD("Num of video buffers(%d/%d)", player->video_num_buffers, player->video_extra_num_buffers);
        }
 
        while (TRUE) {
@@ -3049,7 +3313,7 @@ __mmplayer_video_stream_decoded_preroll_cb(GstElement *object, GstBuffer *buffer
 {
        mmplayer_t *player = (mmplayer_t *)data;
        MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player && player->video_stream_cb);
+       MMPLAYER_RETURN_IF_FAIL(player && player->video_decoded_cb);
 
        /* send prerolled pkt */
        player->video_stream_prerolled = false;
@@ -3069,7 +3333,7 @@ __mmplayer_video_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer,
 
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
-       MMPLAYER_RETURN_IF_FAIL(player->video_stream_cb);
+       MMPLAYER_RETURN_IF_FAIL(player->video_decoded_cb);
 
        if (player->video_stream_prerolled) {
                player->video_stream_prerolled = false;
@@ -3084,7 +3348,7 @@ __mmplayer_video_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer,
                return;
        }
 
-       __mmplayer_get_video_angle(player, NULL, &stream->orientation);
+       _mmplayer_get_video_angle(player, NULL, &stream->orientation);
 
        /* set size and timestamp */
        mem = gst_buffer_peek_memory(buffer, 0);
@@ -3093,7 +3357,7 @@ __mmplayer_video_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer,
 
        /* check zero-copy */
        if (player->set_mode.video_zc &&
-               player->set_mode.media_packet_video_stream &&
+               player->set_mode.video_export &&
                gst_is_tizen_memory(mem)) {
                __mmplayer_zerocopy_set_stride_elevation_bo(stream, mem);
                stream->internal_buffer = gst_buffer_ref(buffer);
@@ -3105,8 +3369,8 @@ __mmplayer_video_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer,
                        goto ERROR;
        }
 
-       if (!player->video_stream_cb(stream, player->video_stream_cb_user_param)) {
-               LOGE("failed to send video stream data.");
+       if (!player->video_decoded_cb(stream, player->video_decoded_cb_user_param)) {
+               LOGE("failed to send video decoded data.");
                goto ERROR;
        }
 
@@ -3207,7 +3471,7 @@ __mmplayer_gst_create_video_filters(mmplayer_t *player, MMDisplaySurfaceType sur
        /* create video360 filter */
        if (player->is_360_feature_enabled && player->is_content_spherical) {
                LOGD("create video360 element");
-               MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_360, "video360", "video-360", TRUE, player);
+               MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_360, "video360", "video-360", element_bucket, player);
                __mmplayer_gst_set_video360_property(player);
                goto EXIT;
        }
@@ -3220,7 +3484,7 @@ __mmplayer_gst_create_video_filters(mmplayer_t *player, MMDisplaySurfaceType sur
        /* in case of sw codec & overlay surface type, except 360 playback.
         * if libav video decoder is selected, videoconvert is required to render the shm wl-buffer which support RGB only via tizenwlsink. */
        LOGD("create video converter: %s", video_csc);
-       MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_CONV, video_csc, "video converter", TRUE, player);
+       MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_CONV, video_csc, "video converter", element_bucket, player);
 
 EXIT:
        *bucket = element_bucket;
@@ -3279,41 +3543,43 @@ __mmplayer_gst_set_videosink_property(mmplayer_t *player, MMDisplaySurfaceType s
                return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       LOGD("surface type %d, videosink factory name is %s", surface_type, factory_name);
        if (surface_type == MM_DISPLAY_SURFACE_OVERLAY) {
                bool use_tbm = (player->set_mode.video_zc || (player->is_360_feature_enabled && player->is_content_spherical));
-               if (!use_tbm) {
-                       /* support shard memory with S/W codec on HawkP */
-                       if (strncmp(factory_name, "tizenwlsink", strlen(factory_name)) == 0) {
-                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-                                       "use-tbm", use_tbm, NULL);
-                       }
+               if (strncmp(factory_name, "tizenwlsink", strlen(factory_name)) == 0) {
+                       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                               "use-tbm", use_tbm, NULL);
                }
+
+               if (_mmplayer_update_video_overlay_param(player, "update_all_param") != MM_ERROR_NONE)
+                       return MM_ERROR_PLAYER_INTERNAL;
+
+               LOGI("videosink factory name is %s use-tbm : %d", factory_name, use_tbm);
+
        } else {
                g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
                                                                                "sync", TRUE, "max-lateness", FAKE_SINK_MAX_LATENESS, NULL);
        }
 
-       mm_attrs_get_int_by_name(attrs, "gapless_mode", &gapless);
+       mm_attrs_get_int_by_name(attrs, MM_PLAYER_GAPLESS_MODE, &gapless);
        if (gapless > 0) {
                LOGD("disable last-sample");
                g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "enable-last-sample", FALSE, NULL);
        }
 
-       if (player->set_mode.media_packet_video_stream) {
+       if (player->set_mode.video_export) {
                int enable = 0;
                mm_attrs_get_int_by_name(player->attrs, "enable_video_decoded_cb", &enable);
                if (enable || (surface_type == MM_DISPLAY_SURFACE_REMOTE) || (surface_type == MM_DISPLAY_SURFACE_NULL))
                        g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "signal-handoffs", TRUE, NULL);
 
-               __mmplayer_add_signal_connection(player,
+               _mmplayer_add_signal_connection(player,
                                                                G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
                                                                MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
                                                                "handoff",
                                                                G_CALLBACK(__mmplayer_video_stream_decoded_render_cb),
                                                                (gpointer)player);
 
-               __mmplayer_add_signal_connection(player,
+               _mmplayer_add_signal_connection(player,
                                                                G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
                                                                MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
                                                                "preroll-handoff",
@@ -3321,14 +3587,11 @@ __mmplayer_gst_set_videosink_property(mmplayer_t *player, MMDisplaySurfaceType s
                                                                (gpointer)player);
        }
 
-       if (_mmplayer_update_video_param(player, "update_all_param") != MM_ERROR_NONE)
-               return MM_ERROR_PLAYER_INTERNAL;
-
        if (videobin[MMPLAYER_V_SINK].gst) {
                GstPad *sink_pad = NULL;
                sink_pad = gst_element_get_static_pad(videobin[MMPLAYER_V_SINK].gst, "sink");
                if (sink_pad) {
-                       __mmplayer_add_signal_connection(player, G_OBJECT(sink_pad), MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                       _mmplayer_add_signal_connection(player, G_OBJECT(sink_pad), MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
                                        "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), (gpointer)player);
                        gst_object_unref(GST_OBJECT(sink_pad));
                } else {
@@ -3374,7 +3637,7 @@ __mmplayer_gst_create_video_sink_bin(mmplayer_t *player, GstCaps *caps, MMDispla
                goto ERROR;
 
        videosink_factory_name = __mmplayer_get_videosink_factory_name(player, surface_type);
-       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_factory_name, "videosink", TRUE, player);
+       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_factory_name, "videosink", element_bucket, player);
 
        /* additional setting for sink plug-in */
        if (__mmplayer_gst_set_videosink_property(player, surface_type) != MM_ERROR_NONE) {
@@ -3386,13 +3649,13 @@ __mmplayer_gst_create_video_sink_bin(mmplayer_t *player, GstCaps *caps, MMDispla
        __mmplayer_add_sink(player, videobin[MMPLAYER_V_SINK].gst);
 
        /* adding created elements to bin */
-       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(videobin[MMPLAYER_V_BIN].gst), element_bucket)) {
+       if (!_mmplayer_gst_element_add_bucket_to_bin(GST_BIN(videobin[MMPLAYER_V_BIN].gst), element_bucket)) {
                LOGE("failed to add elements");
                goto ERROR;
        }
 
        /* Linking elements in the bucket by added order */
-       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1) {
+       if (_mmplayer_gst_element_link_bucket(element_bucket) == -1) {
                LOGE("failed to link elements");
                goto ERROR;
        }
@@ -3448,14 +3711,14 @@ __mmplayer_gst_create_plain_text_elements(mmplayer_t *player)
        GList *element_bucket = NULL;
        mmplayer_gst_element_t *textbin = player->pipeline->textbin;
 
-       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_QUEUE, "queue", "text_queue", TRUE, player);
-       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_IDENTITY, "identity", "text_identity", TRUE, player);
+       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_QUEUE, "queue", "text_queue", element_bucket, player);
+       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_IDENTITY, "identity", "text_identity", element_bucket, player);
        g_object_set(G_OBJECT(textbin[MMPLAYER_T_IDENTITY].gst),
                                                        "signal-handoffs", FALSE,
                                                        NULL);
 
-       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_FAKE_SINK, "fakesink", "text_fakesink", TRUE, player);
-       __mmplayer_add_signal_connection(player,
+       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_FAKE_SINK, "fakesink", "text_fakesink", element_bucket, player);
+       _mmplayer_add_signal_connection(player,
                                                        G_OBJECT(textbin[MMPLAYER_T_FAKE_SINK].gst),
                                                        MM_PLAYER_SIGNAL_TYPE_TEXTBIN,
                                                        "handoff",
@@ -3472,7 +3735,7 @@ __mmplayer_gst_create_plain_text_elements(mmplayer_t *player)
 
        /* adding created elements to bin */
        LOGD("adding created elements to bin");
-       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(textbin[MMPLAYER_T_BIN].gst), element_bucket)) {
+       if (!_mmplayer_gst_element_add_bucket_to_bin(GST_BIN(textbin[MMPLAYER_T_BIN].gst), element_bucket)) {
                LOGE("failed to add elements");
                goto ERROR;
        }
@@ -3483,7 +3746,7 @@ __mmplayer_gst_create_plain_text_elements(mmplayer_t *player)
 
        /* linking elements in the bucket by added order. */
        LOGD("Linking elements in the bucket by added order.");
-       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1) {
+       if (_mmplayer_gst_element_link_bucket(element_bucket) == -1) {
                LOGE("failed to link elements");
                goto ERROR;
        }
@@ -3610,7 +3873,7 @@ ERROR:
        if (textbin[MMPLAYER_T_BIN].gst)
                gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
 
-       MMPLAYER_FREEIF(player->pipeline->textbin);
+       MMPLAYER_FREEIF(textbin);
        player->pipeline->textbin = NULL;
 
        MMPLAYER_FLEAVE();
@@ -3650,7 +3913,7 @@ __mmplayer_gst_create_text_pipeline(mmplayer_t *player)
                return MM_ERROR_PLAYER_INVALID_URI;
        }
 
-       if (!util_get_storage_info(subtitle_uri, &player->storage_info[MMPLAYER_PATH_TEXT])) {
+       if (!_mmplayer_get_storage_info(subtitle_uri, &player->storage_info[MMPLAYER_PATH_TEXT])) {
                LOGE("failed to get storage info of subtitle path");
                return MM_ERROR_PLAYER_INVALID_URI;
        }
@@ -3687,7 +3950,7 @@ __mmplayer_gst_create_text_pipeline(mmplayer_t *player)
                goto ERROR;
        }
 
-       charset = util_get_charset(subtitle_uri);
+       charset = _mmplayer_get_charset(subtitle_uri);
        if (charset) {
                LOGD("detected charset is %s", charset);
                g_object_set(G_OBJECT(subparse), "subtitle-encoding", charset, NULL);
@@ -3947,8 +4210,6 @@ __mmplayer_gst_create_pipeline(mmplayer_t *player)
        }
 
        player->pipeline = (mmplayer_pipeline_info_t *)g_malloc0(sizeof(mmplayer_pipeline_info_t));
-       if (player->pipeline == NULL)
-               goto INIT_ERROR;
 
        /* create mainbin */
        mainbin = (mmplayer_gst_element_t *)g_try_malloc0(sizeof(mmplayer_gst_element_t) * MMPLAYER_M_NUM);
@@ -3967,10 +4228,14 @@ __mmplayer_gst_create_pipeline(mmplayer_t *player)
        player->pipeline->mainbin = mainbin;
 
        /* create the source and decoder elements */
-       if (MMPLAYER_IS_MS_BUFF_SRC(player))
-               ret = __mmplayer_gst_build_es_pipeline(player);
-       else
-               ret = __mmplayer_gst_build_pipeline(player);
+       if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
+               ret = _mmplayer_gst_build_es_pipeline(player);
+       } else {
+               if (MMPLAYER_USE_DECODEBIN(player))
+                       ret = _mmplayer_gst_build_pipeline(player); /* TEMP: previous pipeline, will be removed.*/
+               else
+                       ret = _mmplayer_gst_build_pipeline_with_src(player);
+       }
 
        if (ret != MM_ERROR_NONE) {
                LOGE("failed to create some elements");
@@ -3983,7 +4248,7 @@ __mmplayer_gst_create_pipeline(mmplayer_t *player)
                LOGE("failed to create text pipeline");
 
        /* add bus watch */
-       ret = __mmplayer_gst_add_bus_watch(player);
+       ret = _mmplayer_gst_add_bus_watch(player);
        if (ret != MM_ERROR_NONE) {
                LOGE("failed to add bus watch");
                goto INIT_ERROR;
@@ -3993,6 +4258,7 @@ __mmplayer_gst_create_pipeline(mmplayer_t *player)
        return MM_ERROR_NONE;
 
 INIT_ERROR:
+       _mmplayer_bus_watcher_remove(player);
        __mmplayer_gst_destroy_pipeline(player);
        return MM_ERROR_PLAYER_INTERNAL;
 }
@@ -4026,17 +4292,18 @@ __mmplayer_gst_destroy_pipeline(mmplayer_t *player)
        MMPLAYER_FREEIF(player->type);
        player->no_more_pad = FALSE;
        player->num_dynamic_pad = 0;
-       player->demux_pad_index = 0;
 
        MMPLAYER_SUBTITLE_INFO_LOCK(player);
        player->subtitle_language_list = NULL;
        MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
 
+       MMPLAYER_RECONFIGURE_LOCK(player);
        __mmplayer_reset_gapless_state(player);
+       MMPLAYER_RECONFIGURE_UNLOCK(player);
 
        if (player->streamer) {
-               __mm_player_streaming_initialize(player->streamer, FALSE);
-               __mm_player_streaming_destroy(player->streamer);
+               _mm_player_streaming_initialize(player->streamer, FALSE);
+               _mm_player_streaming_destroy(player->streamer);
                player->streamer = NULL;
        }
 
@@ -4046,7 +4313,7 @@ __mmplayer_gst_destroy_pipeline(mmplayer_t *player)
        MMPLAYER_FREEIF(player->unlinked_demuxer_mime);
 
        /* cleanup running stuffs */
-       __mmplayer_cancel_eos_timer(player);
+       _mmplayer_cancel_eos_timer(player);
 
        /* cleanup gst stuffs */
        if (player->pipeline) {
@@ -4065,7 +4332,7 @@ __mmplayer_gst_destroy_pipeline(mmplayer_t *player)
                        gst_object_unref(bus);
 
                        timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
-                       ret = __mmplayer_gst_set_state(player, mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_NULL, FALSE, timeout);
+                       ret = _mmplayer_gst_set_state(player, mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_NULL, FALSE, timeout);
                        if (ret != MM_ERROR_NONE) {
                                LOGE("fail to change state to NULL");
                                return MM_ERROR_PLAYER_INTERNAL;
@@ -4110,7 +4377,7 @@ __mmplayer_gst_destroy_pipeline(mmplayer_t *player)
                gst_caps_unref(player->s_stream_caps);
                player->s_stream_caps = NULL;
        }
-       __mmplayer_track_destroy(player);
+       _mmplayer_track_destroy(player);
 
        if (player->sink_elements)
                g_list_free(player->sink_elements);
@@ -4149,7 +4416,7 @@ __mmplayer_gst_realize(mmplayer_t *player)
        /* set pipeline state to READY */
        /* NOTE : state change to READY must be performed sync. */
        timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
-       ret = __mmplayer_gst_set_state(player,
+       ret = _mmplayer_gst_set_state(player,
                                player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_READY, FALSE, timeout);
 
        if (ret != MM_ERROR_NONE) {
@@ -4222,7 +4489,7 @@ __mmplayer_gst_set_message_callback(mmplayer_t *player, MMMessageCallback callba
 }
 
 int
-__mmplayer_parse_profile(const char *uri, void *param, mmplayer_parse_profile_t *data)
+_mmplayer_parse_profile(const char *uri, void *param, mmplayer_parse_profile_t *data)
 {
        int ret = MM_ERROR_NONE;
        char *path = NULL;
@@ -4278,7 +4545,7 @@ __mmplayer_can_do_interrupt(mmplayer_t *player)
                goto FAILED;
        }
 
-       if (player->audio_stream_render_cb) {
+       if (player->audio_decoded_cb) {
                LOGW("not support in pcm extraction mode");
                goto FAILED;
        }
@@ -4315,7 +4582,7 @@ __mmplayer_can_do_interrupt(mmplayer_t *player)
 FAILED:    /* with CMD UNLOCKED */
        return FALSE;
 
-INTERRUPT: /* with CMD LOCKED, released at mrp_resource_release_cb() */
+INTERRUPT: /* with CMD LOCKED, will do UNLOCK at __resource_release_cb() */
        return TRUE;
 }
 
@@ -4324,49 +4591,48 @@ __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
                void *user_data)
 {
        mmplayer_t *player = NULL;
+       MMMessageParamType msg = {0, };
+       gint64 pos = 0;
+       mmplayer_resource_type_e res_idx = MMPLAYER_RESOURCE_TYPE_MAX;
 
        MMPLAYER_FENTER();
 
-       if (user_data == NULL) {
-               LOGE("user_data is null");
+       if (!user_data) {
+               LOGE("user_data is null");
                return FALSE;
        }
        player = (mmplayer_t *)user_data;
 
-       /* do something to release resource here.
-        * player stop and interrupt forwarding */
        if (!__mmplayer_can_do_interrupt(player)) {
                LOGW("no need to interrupt, so leave");
+               /* FIXME: there is no way to avoid releasing resource. */
+               return FALSE;
+       }
+
+       player->interrupted_by_resource = TRUE;
+
+       /* get last play position */
+       if (_mmplayer_gst_get_position(player, &pos) == MM_ERROR_NONE) {
+               msg.union_type = MM_MSG_UNION_TIME;
+               msg.time.elapsed = pos;
+               MMPLAYER_POST_MSG(player, MM_MESSAGE_PLAY_POSITION, &msg);
        } else {
-               MMMessageParamType msg = {0, };
-               gint64 pos = 0;
+               LOGW("failed to get play position.");
+       }
 
-               player->interrupted_by_resource = TRUE;
+       LOGD("video resource conflict so, resource will be freed by unrealizing");
+       if (_mmplayer_unrealize((MMHandleType)player) != MM_ERROR_NONE)
+               LOGE("failed to unrealize");
 
-               /* get last play position */
-               if (_mmplayer_get_position((MMHandleType)player, &pos) != MM_ERROR_NONE) {
-                       LOGW("failed to get play position.");
-               } else {
-                       msg.union_type = MM_MSG_UNION_TIME;
-                       msg.time.elapsed = pos;
-                       MMPLAYER_POST_MSG(player, MM_MESSAGE_PLAY_POSITION, &msg);
-               }
-               LOGD("video resource conflict so, resource will be freed by unrealizing");
-               if (_mmplayer_unrealize((MMHandleType)player))
-                       LOGW("failed to unrealize");
+       /* lock is called in __mmplayer_can_do_interrupt() */
+       MMPLAYER_CMD_UNLOCK(player);
 
-               /* 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++) {
+               player->hw_resource[res_idx] = NULL;
        }
 
-       if (res == player->video_overlay_resource)
-               player->video_overlay_resource = FALSE;
-       else
-               player->video_decoder_resource = FALSE;
-
        MMPLAYER_FLEAVE();
-
-       return FALSE;
+       return TRUE; /* release all the resources */
 }
 
 static void
@@ -4463,9 +4729,6 @@ _mmplayer_create_player(MMHandleType handle)
        g_mutex_init(&player->video_bo_mutex);
        g_cond_init(&player->video_bo_cond);
 
-       /* create media stream callback mutex */
-       g_mutex_init(&player->media_stream_cb_lock);
-
        /* create subtitle info lock and cond */
        g_mutex_init(&player->subtitle_info_mutex);
        g_cond_init(&player->subtitle_info_cond);
@@ -4479,8 +4742,6 @@ _mmplayer_create_player(MMHandleType handle)
 
        player->play_subtitle = FALSE;
        player->has_closed_caption = FALSE;
-       player->video_num_buffers = DEFAULT_NUM_OF_V_OUT_BUFFER;
-       player->video_extra_num_buffers = DEFAULT_NUM_OF_V_OUT_BUFFER;
        player->pending_resume = FALSE;
        if (player->ini.dump_element_keyword[0][0] == '\0')
                player->ini.set_dump_element_flag = FALSE;
@@ -4529,6 +4790,7 @@ ERROR:
        /* free update tag lock */
        g_mutex_clear(&player->update_tag_lock);
        g_queue_free(player->bus_msg_q);
+       player->bus_msg_q = NULL;
        /* free gapless play thread */
        if (player->gapless_play_thread) {
                MMPLAYER_GAPLESS_PLAY_THREAD_LOCK(player);
@@ -4627,7 +4889,9 @@ __mmplayer_init_gstreamer(mmplayer_t *player)
        }
        /* release */
        for (i = 0; i < arg_count; i++) {
-               //LOGD("release - argv[%d] : %s", i, argv2[i]);
+#ifdef __DEBUG__
+               LOGD("release - argv[%d] : %s", i, argv2[i]);
+#endif
                MMPLAYER_FREEIF(argv2[i]);
        }
 
@@ -4691,7 +4955,7 @@ __mmplayer_check_async_state_transition(mmplayer_t *player)
                        gst_element_state_get_name(element_pending_state));
 
                /* dump state of all element */
-               __mmplayer_dump_pipeline_state(player);
+               _mmplayer_dump_pipeline_state(player);
 
                return;
        }
@@ -4737,6 +5001,9 @@ _mmplayer_destroy(MMHandleType handle)
                        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");
@@ -4751,9 +5018,6 @@ _mmplayer_destroy(MMHandleType handle)
 
        __mmplayer_release_dump_list(player->dump_list);
 
-       /* release miscellaneous information */
-       __mmplayer_release_misc(player);
-
        /* release miscellaneous information.
           these info needs to be released after pipeline is destroyed. */
        __mmplayer_release_misc_post(player);
@@ -4761,6 +5025,11 @@ _mmplayer_destroy(MMHandleType handle)
        /* release attributes */
        _mmplayer_deconstruct_attribute(handle);
 
+       if (player->uri_info.uri_list) {
+               g_list_free_full(player->uri_info.uri_list, (GDestroyNotify)g_free);
+               player->uri_info.uri_list = NULL;
+       }
+
        /* release lock */
        g_mutex_clear(&player->fsink_lock);
 
@@ -4771,9 +5040,6 @@ _mmplayer_destroy(MMHandleType handle)
        g_mutex_clear(&player->video_bo_mutex);
        g_cond_clear(&player->video_bo_cond);
 
-       /* release media stream callback lock */
-       g_mutex_clear(&player->media_stream_cb_lock);
-
        MMPLAYER_FLEAVE();
 
        return MM_ERROR_NONE;
@@ -4783,10 +5049,10 @@ int
 _mmplayer_realize(MMHandleType hplayer)
 {
        mmplayer_t *player = (mmplayer_t *)hplayer;
+       int ret = MM_ERROR_NONE;
        char *uri = NULL;
        void *param = NULL;
        MMHandleType attrs = 0;
-       int ret = MM_ERROR_NONE;
 
        MMPLAYER_FENTER();
 
@@ -4805,7 +5071,7 @@ _mmplayer_realize(MMHandleType hplayer)
        mm_attrs_get_data_by_name(attrs, "profile_user_param", &param);
 
        if (player->profile.uri_type == MM_PLAYER_URI_TYPE_NONE) {
-               ret = __mmplayer_parse_profile((const char *)uri, param, &player->profile);
+               ret = _mmplayer_parse_profile((const char *)uri, param, &player->profile);
 
                if (ret != MM_ERROR_NONE) {
                        LOGE("failed to parse profile");
@@ -4839,21 +5105,21 @@ _mmplayer_realize(MMHandleType hplayer)
        player->is_subtitle_off = FALSE; /* set the subtitle ON default */
        player->video360_metadata.is_spherical = -1;
        player->is_openal_plugin_used = FALSE;
-       player->demux_pad_index = 0;
        player->subtitle_language_list = NULL;
        player->is_subtitle_force_drop = FALSE;
 
-       __mmplayer_track_initialize(player);
+       _mmplayer_track_initialize(player);
        __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
 
        if ((MMPLAYER_IS_STREAMING(player)) && (player->streamer == NULL)) {
                gint prebuffer_ms = 0, rebuffer_ms = 0;
 
-               player->streamer = __mm_player_streaming_create();
-               __mm_player_streaming_initialize(player->streamer, TRUE);
+               player->streamer = _mm_player_streaming_create();
+               _mm_player_streaming_initialize(player->streamer, TRUE);
 
-               mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_PREBUFFER_MS, &prebuffer_ms);
-               mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_REBUFFER_MS, &rebuffer_ms);
+               mm_attrs_multiple_get(player->attrs, NULL,
+                               MM_PLAYER_PREBUFFER_MS, &prebuffer_ms,
+                               MM_PLAYER_REBUFFER_MS, &rebuffer_ms, NULL);
 
                if (prebuffer_ms > 0) {
                        prebuffer_ms = MAX(prebuffer_ms, 1000);
@@ -4893,9 +5159,10 @@ _mmplayer_unrealize(MMHandleType hplayer)
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
        MMPLAYER_CMD_UNLOCK(player);
+       _mmplayer_bus_watcher_remove(player);
        /* destroy the gst bus msg thread which is created during realize.
           this funct have to be called before getting cmd lock. */
-       __mmplayer_bus_msg_thread_destroy(player);
+       _mmplayer_bus_msg_thread_destroy(player);
        MMPLAYER_CMD_LOCK(player);
 
        /* check current state */
@@ -4907,36 +5174,18 @@ _mmplayer_unrealize(MMHandleType hplayer)
        /* unrealize pipeline */
        ret = __mmplayer_gst_unrealize(player);
 
-       /* set asm stop if success */
-       if (MM_ERROR_NONE == ret) {
-               if (!player->interrupted_by_resource) {
-                       if (player->video_decoder_resource != NULL) {
-                               ret = mm_resource_manager_mark_for_release(player->resource_manager,
-                                               player->video_decoder_resource);
-                               if (ret != MM_RESOURCE_MANAGER_ERROR_NONE)
-                                       LOGE("failed to mark decoder resource for release, ret(0x%x)", ret);
-                               else
-                                       player->video_decoder_resource = NULL;
-                       }
+       if (!player->interrupted_by_resource) {
+               int rm_ret = MM_ERROR_NONE;
+               mmplayer_resource_type_e res_idx = MMPLAYER_RESOURCE_TYPE_MAX;
 
-                       if (player->video_overlay_resource != NULL) {
-                               ret = mm_resource_manager_mark_for_release(player->resource_manager,
-                                               player->video_overlay_resource);
-                               if (ret != MM_RESOURCE_MANAGER_ERROR_NONE)
-                                       LOGE("failed to mark overlay resource for release, ret(0x%x)", ret);
-                               else
-                                       player->video_overlay_resource = NULL;
-                       }
-
-                       ret = mm_resource_manager_commit(player->resource_manager);
-                       if (ret != MM_RESOURCE_MANAGER_ERROR_NONE)
-                               LOGE("failed to commit resource releases, ret(0x%x)", ret);
+               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);
                }
-       } else
-               LOGE("failed and don't change asm state to stop");
+       }
 
        MMPLAYER_FLEAVE();
-
        return ret;
 }
 
@@ -4962,157 +5211,130 @@ _mmplayer_get_state(MMHandleType hplayer, int *state)
        return MM_ERROR_NONE;
 }
 
-
-int
-_mmplayer_set_volume(MMHandleType hplayer, mmplayer_volume_type_t volume)
+static int
+__mmplayer_gst_set_volume_property(mmplayer_t *player, const char *prop_name)
 {
-       mmplayer_t *player = (mmplayer_t *)hplayer;
        GstElement *vol_element = NULL;
-       int i = 0;
+       enum audio_element_id volume_elem_id = MMPLAYER_A_VOL;
 
        MMPLAYER_FENTER();
-
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       LOGD("volume [L]=%f:[R]=%f",
-               volume.level[MM_VOLUME_CHANNEL_LEFT], volume.level[MM_VOLUME_CHANNEL_RIGHT]);
-
-       /* invalid factor range or not */
-       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++) {
-               if (volume.level[i] < MM_VOLUME_FACTOR_MIN || volume.level[i] > MM_VOLUME_FACTOR_MAX) {
-                       LOGE("Invalid factor!(valid factor:0~1.0)");
-                       return MM_ERROR_INVALID_ARGUMENT;
-               }
-       }
-
-       /* not support to set other value into each channel */
-       if ((volume.level[MM_VOLUME_CHANNEL_LEFT] != volume.level[MM_VOLUME_CHANNEL_RIGHT]))
-               return MM_ERROR_INVALID_ARGUMENT;
-
-       /* Save volume to handle. Currently the first array element will be saved. */
-       player->sound.volume = volume.level[MM_VOLUME_CHANNEL_LEFT];
+       MMPLAYER_RETURN_VAL_IF_FAIL(prop_name, MM_ERROR_INVALID_ARGUMENT);
 
        /* check pipeline handle */
        if (!player->pipeline || !player->pipeline->audiobin) {
-               LOGD("audiobin is not created yet");
-               LOGD("but, current stored volume will be set when it's created.");
+               LOGD("'%s' will be applied when audiobin is created", prop_name);
 
-               /* NOTE : stored volume will be used in create_audiobin
+               /* NOTE : stored value will be used in create_audiobin
                 * returning MM_ERROR_NONE here makes application to able to
-                * set volume at anytime.
+                * set audio volume or mute at anytime.
                 */
                return MM_ERROR_NONE;
        }
 
-       /* setting volume to volume element */
-       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+       if (player->build_audio_offload || g_strrstr(player->ini.audiosink_element, "pulsesink"))
+               volume_elem_id = MMPLAYER_A_SINK;
 
-       if (vol_element) {
-               LOGD("volume is set [%f]", player->sound.volume);
-               g_object_set(vol_element, "volume", player->sound.volume, NULL);
+       vol_element = player->pipeline->audiobin[volume_elem_id].gst;
+       if (!vol_element) {
+               LOGE("failed to get vol element %d", volume_elem_id);
+               return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       MMPLAYER_FLEAVE();
+       LOGD("set '%s' property to element[%s]", prop_name, GST_ELEMENT_NAME(vol_element));
+
+       if (!g_object_class_find_property(G_OBJECT_GET_CLASS(vol_element), prop_name)) {
+               LOGE("there is no '%s' property", prop_name);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       if (!strcmp(prop_name, "volume")) {
+               g_object_set(vol_element, "volume", player->sound.volume, NULL);
+       } else if (!strcmp(prop_name, "mute")) {
+               g_object_set(vol_element, "mute", player->sound.mute, NULL);
+       } else {
+               LOGE("invalid property %s", prop_name);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
        return MM_ERROR_NONE;
 }
 
 int
-_mmplayer_get_volume(MMHandleType hplayer, mmplayer_volume_type_t *volume)
+_mmplayer_set_volume(MMHandleType hplayer, float volume)
 {
+       int ret = MM_ERROR_NONE;
        mmplayer_t *player = (mmplayer_t *)hplayer;
-       int i = 0;
 
        MMPLAYER_FENTER();
-
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(volume, MM_ERROR_INVALID_ARGUMENT);
 
-       /* returning stored volume */
-       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++)
-               volume->level[i] = player->sound.volume;
+       LOGD("volume = %f", volume);
 
-       MMPLAYER_FLEAVE();
+       /* invalid factor range or not */
+       if (volume < MM_VOLUME_FACTOR_MIN || volume > MM_VOLUME_FACTOR_MAX) {
+               LOGE("Invalid volume value");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
 
-       return MM_ERROR_NONE;
+       player->sound.volume = volume;
+
+       ret = __mmplayer_gst_set_volume_property(player, "volume");
+
+       MMPLAYER_FLEAVE();
+       return ret;
 }
 
 int
-_mmplayer_set_mute(MMHandleType hplayer, int mute)
+_mmplayer_get_volume(MMHandleType hplayer, float *volume)
 {
        mmplayer_t *player = (mmplayer_t *)hplayer;
-       GstElement *vol_element = NULL;
 
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(volume, MM_ERROR_INVALID_ARGUMENT);
 
-       /* mute value shoud 0 or 1 */
-       if (mute != 0 && mute != 1) {
-               LOGE("bad mute value");
-
-               /* FIXIT : definitly, we need _BAD_PARAM error code */
-               return MM_ERROR_INVALID_ARGUMENT;
-       }
-
-       player->sound.mute = mute;
-
-       /* just hold mute value if pipeline is not ready */
-       if (!player->pipeline || !player->pipeline->audiobin) {
-               LOGD("pipeline is not ready. holding mute value");
-               return MM_ERROR_NONE;
-       }
-
-       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+       *volume = player->sound.volume;
 
-       /* NOTE : volume will only created when the bt is enabled */
-       if (vol_element) {
-               LOGD("mute : %d", mute);
-               g_object_set(vol_element, "mute", mute, NULL);
-       } else
-               LOGD("volume elemnet is not created. using volume in audiosink");
+       LOGD("current vol = %f", *volume);
 
        MMPLAYER_FLEAVE();
-
        return MM_ERROR_NONE;
 }
 
 int
-_mmplayer_get_mute(MMHandleType hplayer, int *pmute)
+_mmplayer_set_mute(MMHandleType hplayer, bool mute)
 {
+       int ret = MM_ERROR_NONE;
        mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
-
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(pmute, MM_ERROR_INVALID_ARGUMENT);
 
-       /* just hold mute value if pipeline is not ready */
-       if (!player->pipeline || !player->pipeline->audiobin) {
-               LOGD("pipeline is not ready. returning stored value");
-               *pmute = player->sound.mute;
-               return MM_ERROR_NONE;
-       }
+       LOGD("mute = %d", mute);
+
+       player->sound.mute = mute;
 
-       *pmute = player->sound.mute;
+       ret = __mmplayer_gst_set_volume_property(player, "mute");
 
        MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
+       return ret;
 }
 
 int
-_mmplayer_set_videostream_changed_cb(MMHandleType hplayer, mm_player_stream_changed_callback callback, void *user_param)
+_mmplayer_get_mute(MMHandleType hplayer, bool *mute)
 {
        mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(mute, MM_ERROR_INVALID_ARGUMENT);
 
-       player->video_stream_changed_cb = callback;
-       player->video_stream_changed_cb_user_param = user_param;
-       LOGD("Handle value is %p : %p", player, player->video_stream_changed_cb);
+       *mute = player->sound.mute;
+
+       LOGD("current mute = %d", *mute);
 
        MMPLAYER_FLEAVE();
 
@@ -5138,7 +5360,7 @@ _mmplayer_set_audiostream_changed_cb(MMHandleType hplayer, mm_player_stream_chan
 }
 
 int
-_mmplayer_set_audiostream_cb(MMHandleType hplayer, bool sync, mm_player_audio_stream_callback callback, void *user_param)
+_mmplayer_set_audio_decoded_cb(MMHandleType hplayer, mmplayer_audio_extract_opt_e opt, mm_player_audio_decoded_callback callback, void *user_param)
 {
        mmplayer_t *player = (mmplayer_t *)hplayer;
 
@@ -5146,10 +5368,10 @@ _mmplayer_set_audiostream_cb(MMHandleType hplayer, bool sync, mm_player_audio_st
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       player->audio_stream_render_cb = callback;
-       player->audio_stream_cb_user_param = user_param;
-       player->audio_stream_sink_sync = sync;
-       LOGD("handle: %p, cb: %p, sync: %d", player, player->audio_stream_render_cb, player->audio_stream_sink_sync);
+       player->audio_decoded_cb = callback;
+       player->audio_decoded_cb_user_param = user_param;
+       player->audio_extract_opt = opt;
+       LOGD("handle: %p, cb: %p, opt: 0x%X", player, player->audio_decoded_cb, player->audio_extract_opt);
 
        MMPLAYER_FLEAVE();
 
@@ -5157,7 +5379,7 @@ _mmplayer_set_audiostream_cb(MMHandleType hplayer, bool sync, mm_player_audio_st
 }
 
 int
-_mmplayer_set_videostream_cb(MMHandleType hplayer, mm_player_video_stream_callback callback, void *user_param)
+_mmplayer_set_video_decoded_cb(MMHandleType hplayer, mm_player_video_decoded_callback callback, void *user_param)
 {
        mmplayer_t *player = (mmplayer_t *)hplayer;
 
@@ -5168,11 +5390,11 @@ _mmplayer_set_videostream_cb(MMHandleType hplayer, mm_player_video_stream_callba
        if (callback && !player->bufmgr)
                player->bufmgr = tbm_bufmgr_init(-1);
 
-       player->set_mode.media_packet_video_stream = (callback) ? true : false;
-       player->video_stream_cb = callback;
-       player->video_stream_cb_user_param = user_param;
+       player->set_mode.video_export = (callback) ? true : false;
+       player->video_decoded_cb = callback;
+       player->video_decoded_cb_user_param = user_param;
 
-       LOGD("Stream cb Handle value is %p : %p, enable:%d", player, player->video_stream_cb, player->set_mode.media_packet_video_stream);
+       LOGD("Stream cb Handle value is %p : %p, enable:%d", player, player->video_decoded_cb, player->set_mode.video_export);
 
        MMPLAYER_FLEAVE();
 
@@ -5193,7 +5415,7 @@ _mmplayer_start(MMHandleType hplayer)
        MMPLAYER_CHECK_STATE(player, MMPLAYER_COMMAND_START);
 
        /* start pipeline */
-       ret = __mmplayer_gst_start(player);
+       ret = _mmplayer_gst_start(player);
        if (ret != MM_ERROR_NONE)
                LOGE("failed to start player.");
 
@@ -5290,28 +5512,32 @@ __mmplayer_handle_missed_plugin(mmplayer_t *player)
        return MM_ERROR_NONE;
 }
 
-static void
-__mmplayer_check_pipeline(mmplayer_t *player)
+static void __mmplayer_check_pipeline_reconfigure_state(mmplayer_t *player)
 {
        GstState element_state = GST_STATE_VOID_PENDING;
        GstState element_pending_state = GST_STATE_VOID_PENDING;
-       gint timeout = 0;
-       int ret = MM_ERROR_NONE;
+       GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
+       gint timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
 
-       if (!player->gapless.reconfigure)
-               return;
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline);
 
-       LOGW("pipeline is under construction.");
+       MMPLAYER_RECONFIGURE_LOCK(player);
+       if (!player->gapless.reconfigure) {
+               MMPLAYER_RECONFIGURE_UNLOCK(player);
+               return;
+       }
 
-       MMPLAYER_PLAYBACK_LOCK(player);
-       MMPLAYER_PLAYBACK_UNLOCK(player);
+       LOGI("reconfigure is under process");
+       MMPLAYER_RECONFIGURE_WAIT(player);
+       MMPLAYER_RECONFIGURE_UNLOCK(player);
+       LOGI("reconfigure is completed.");
 
-       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
+       result = gst_element_get_state(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+                               &element_state, &element_pending_state, timeout * GST_SECOND);
+       if (result == GST_STATE_CHANGE_FAILURE)
+               LOGW("failed to get pipeline state in %d sec", timeout);
 
-       /* wait for state transition */
-       ret = gst_element_get_state(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &element_state, &element_pending_state, timeout * GST_SECOND);
-       if (ret == GST_STATE_CHANGE_FAILURE)
-               LOGE("failed to change pipeline state within %d sec", timeout);
+       return;
 }
 
 /* NOTE : it should be able to call 'stop' anytime*/
@@ -5328,18 +5554,20 @@ _mmplayer_stop(MMHandleType hplayer)
        /* check current state */
        MMPLAYER_CHECK_STATE(player, MMPLAYER_COMMAND_STOP);
 
-       /* check pipline building state */
-       __mmplayer_check_pipeline(player);
+       /* need to wait till the rebuilding pipeline is completed */
+       __mmplayer_check_pipeline_reconfigure_state(player);
+       MMPLAYER_RECONFIGURE_LOCK(player);
        __mmplayer_reset_gapless_state(player);
+       MMPLAYER_RECONFIGURE_UNLOCK(player);
 
        /* NOTE : application should not wait for EOS after calling STOP */
-       __mmplayer_cancel_eos_timer(player);
+       _mmplayer_cancel_eos_timer(player);
 
        /* reset */
        player->seek_state = MMPLAYER_SEEK_NONE;
 
        /* stop pipeline */
-       ret = __mmplayer_gst_stop(player);
+       ret = _mmplayer_gst_stop(player);
 
        if (ret != MM_ERROR_NONE)
                LOGE("failed to stop player.");
@@ -5364,8 +5592,8 @@ _mmplayer_pause(MMHandleType hplayer)
        /* check current state */
        MMPLAYER_CHECK_STATE(player, MMPLAYER_COMMAND_PAUSE);
 
-       /* check pipline building state */
-       __mmplayer_check_pipeline(player);
+       /* check pipline reconfigure state */
+       __mmplayer_check_pipeline_reconfigure_state(player);
 
        switch (MMPLAYER_CURRENT_STATE(player)) {
        case MM_PLAYER_STATE_READY:
@@ -5400,7 +5628,7 @@ _mmplayer_pause(MMHandleType hplayer)
                           This causes problem is position calculation during normal pause resume scenarios also.
                           Currently during pause , we are sending the current position to rtspsrc module for position saving. */
                        if ((MMPLAYER_IS_RTSP_STREAMING(player)) &&
-                               (__mmplayer_get_stream_service_type(player) == STREAMING_SERVICE_VOD)) {
+                               (_mmplayer_get_stream_service_type(player) == STREAMING_SERVICE_VOD)) {
                                g_object_set(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "resume-position", player->last_position, NULL);
                        }
                }
@@ -5413,13 +5641,13 @@ _mmplayer_pause(MMHandleType hplayer)
        }
 
        /* pause pipeline */
-       ret = __mmplayer_gst_pause(player, async);
+       ret = _mmplayer_gst_pause(player, async);
 
        if (ret != MM_ERROR_NONE)
                LOGE("failed to pause player. ret : 0x%x", ret);
 
        if (MMPLAYER_PREV_STATE(player) == MM_PLAYER_STATE_READY && MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PAUSED) {
-               if (MM_ERROR_NONE != _mmplayer_update_video_param(player, "display_rotation"))
+               if (_mmplayer_update_video_overlay_param(player, "display_rotation") != MM_ERROR_NONE)
                        LOGE("failed to update display_rotation");
        }
 
@@ -5445,7 +5673,7 @@ _mmplayer_abort_pause(MMHandleType hplayer)
        LOGD("set the pipeline state to READY");
 
        /* set state to READY */
-       ret = __mmplayer_gst_set_state(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+       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");
@@ -5481,7 +5709,7 @@ _mmplayer_resume(MMHandleType hplayer)
        /* check current state */
        MMPLAYER_CHECK_STATE(player, MMPLAYER_COMMAND_RESUME);
 
-       ret = __mmplayer_gst_resume(player, async);
+       ret = _mmplayer_gst_resume(player, async);
        if (ret != MM_ERROR_NONE)
                LOGE("failed to resume player.");
 
@@ -5501,7 +5729,7 @@ _mmplayer_set_playspeed(MMHandleType hplayer, float rate, bool streaming)
        mmplayer_t *player = (mmplayer_t *)hplayer;
        gint64 pos_nsec = 0;
        int ret = MM_ERROR_NONE;
-       int mute = FALSE;
+       bool mute = false;
        signed long long start = 0, stop = 0;
        mmplayer_state_e current_state = MM_PLAYER_STATE_NONE;
        MMPLAYER_FENTER();
@@ -5512,7 +5740,7 @@ _mmplayer_set_playspeed(MMHandleType hplayer, float rate, bool streaming)
        /* The sound of video is not supported under 0.0 and over 2.0. */
        if (rate >= TRICK_PLAY_MUTE_THRESHOLD_MAX || rate < TRICK_PLAY_MUTE_THRESHOLD_MIN) {
                if (player->can_support_codec & FOUND_PLUGIN_VIDEO)
-                       mute = TRUE;
+                       mute = true;
        }
        _mmplayer_set_mute(hplayer, mute);
 
@@ -5545,7 +5773,7 @@ _mmplayer_set_playspeed(MMHandleType hplayer, float rate, bool streaming)
                stop = pos_nsec;
        }
 
-       if (!__mmplayer_gst_seek(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+       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),
@@ -5572,10 +5800,10 @@ _mmplayer_set_position(MMHandleType hplayer, gint64 position)
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       /* check pipline building state */
-       __mmplayer_check_pipeline(player);
+       /* check pipline reconfigure state */
+       __mmplayer_check_pipeline_reconfigure_state(player);
 
-       ret = __mmplayer_gst_set_position(player, position, FALSE);
+       ret = _mmplayer_gst_set_position(player, position, FALSE);
 
        MMPLAYER_FLEAVE();
 
@@ -5583,19 +5811,6 @@ _mmplayer_set_position(MMHandleType hplayer, gint64 position)
 }
 
 int
-_mmplayer_get_position(MMHandleType hplayer, gint64 *position)
-{
-       mmplayer_t *player = (mmplayer_t *)hplayer;
-       int ret = MM_ERROR_NONE;
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       ret = __mmplayer_gst_get_position(player, position);
-
-       return ret;
-}
-
-int
 _mmplayer_get_duration(MMHandleType hplayer, gint64 *duration)
 {
        mmplayer_t *player = (mmplayer_t *)hplayer;
@@ -5619,7 +5834,7 @@ _mmplayer_get_buffer_position(MMHandleType hplayer, int *start_pos, int *end_pos
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       ret = __mmplayer_gst_get_buffer_position(player, start_pos, end_pos);
+       ret = _mmplayer_gst_get_buffer_position(player, start_pos, end_pos);
 
        return ret;
 }
@@ -5667,8 +5882,8 @@ __mmplayer_is_only_mp3_type(gchar *str_caps)
        return FALSE;
 }
 
-static void
-__mmplayer_set_audio_attrs(mmplayer_t *player, GstCaps *caps)
+void
+_mmplayer_set_audio_attrs(mmplayer_t *player, GstCaps *caps)
 {
        GstStructure *caps_structure = NULL;
        gint samplerate = 0;
@@ -5681,10 +5896,11 @@ __mmplayer_set_audio_attrs(mmplayer_t *player, GstCaps *caps)
 
        /* set stream information */
        gst_structure_get_int(caps_structure, "rate", &samplerate);
-       mm_attrs_set_int_by_name(player->attrs, "content_audio_samplerate", samplerate);
-
        gst_structure_get_int(caps_structure, "channels", &channels);
-       mm_attrs_set_int_by_name(player->attrs, "content_audio_channels", channels);
+
+       mm_player_set_attribute((MMHandleType)player, NULL,
+                       "content_audio_samplerate", samplerate,
+                       "content_audio_channels", channels, NULL);
 
        LOGD("audio samplerate : %d     channels : %d", samplerate, channels);
 }
@@ -5733,11 +5949,10 @@ __mmplayer_update_content_type_info(mmplayer_t *player)
 }
 
 void
-__mmplayer_typefind_have_type(GstElement *tf, guint probability,
+_mmplayer_typefind_have_type(GstElement *tf, guint probability,
        GstCaps *caps, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
-       GstPad *pad = NULL;
 
        MMPLAYER_FENTER();
 
@@ -5769,32 +5984,32 @@ __mmplayer_typefind_have_type(GstElement *tf, guint probability,
 
        __mmplayer_update_content_type_info(player);
 
-       pad = gst_element_get_static_pad(tf, "src");
-       if (!pad) {
-               LOGE("fail to get typefind src pad.");
-               return;
-       }
+       if (!player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst) {
+               GstPad *pad = NULL;
 
-       if (!__mmplayer_gst_create_decoder(player, pad, caps)) {
-               gboolean async = FALSE;
-               LOGE("failed to autoplug %s", player->type);
+               pad = gst_element_get_static_pad(tf, "src");
+               if (!pad) {
+                       LOGE("fail to get typefind src pad.");
+                       return;
+               }
 
-               mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
+               if (!_mmplayer_gst_create_decoder(player, pad, caps)) {
+                       gboolean async = FALSE;
+                       LOGE("failed to autoplug %s", player->type);
 
-               if (async && player->msg_posted == FALSE)
-                       __mmplayer_handle_missed_plugin(player);
+                       mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
 
+                       if (async && player->msg_posted == FALSE)
+                               __mmplayer_handle_missed_plugin(player);
+               }
+               gst_object_unref(GST_OBJECT(pad));
        }
-
-       gst_object_unref(GST_OBJECT(pad));
-
        MMPLAYER_FLEAVE();
-
        return;
 }
 
 GstElement *
-__mmplayer_gst_make_decodebin(mmplayer_t *player)
+_mmplayer_gst_make_decodebin(mmplayer_t *player)
 {
        GstElement *decodebin = NULL;
 
@@ -5809,38 +6024,42 @@ __mmplayer_gst_make_decodebin(mmplayer_t *player)
        }
 
        /* raw pad handling signal */
-       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
-                                               G_CALLBACK(__mmplayer_gst_decode_pad_added), (gpointer)player);
+       _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
+                                               G_CALLBACK(_mmplayer_gst_decode_pad_added), (gpointer)player);
 
        /* no-more-pad pad handling signal */
-       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
-                                               G_CALLBACK(__mmplayer_gst_decode_no_more_pads), (gpointer)player);
+       _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
+                                               G_CALLBACK(_mmplayer_gst_decode_no_more_pads), (gpointer)player);
 
-       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-removed",
-                                               G_CALLBACK(__mmplayer_gst_decode_pad_removed), (gpointer)player);
+       _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-removed",
+                                               G_CALLBACK(_mmplayer_gst_decode_pad_removed), (gpointer)player);
 
        /* This signal is emitted when a pad for which there is no further possible
           decoding is added to the decodebin.*/
-       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "unknown-type",
-                                               G_CALLBACK(__mmplayer_gst_decode_unknown_type), (gpointer)player);
+       _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "unknown-type",
+                                               G_CALLBACK(_mmplayer_gst_decode_unknown_type), (gpointer)player);
 
        /* This signal is emitted whenever decodebin finds a new stream. It is emitted
           before looking for any elements that can handle that stream.*/
-       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue",
-                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_continue), (gpointer)player);
+       _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue",
+                                               G_CALLBACK(_mmplayer_gst_decode_autoplug_continue), (gpointer)player);
+
+       if (player->need_video_dec_sorting || player->need_audio_dec_sorting)
+               _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-sort",
+                                                       G_CALLBACK(_mmplayer_gst_decode_autoplug_sort), (gpointer)player);
 
        /* This signal is emitted whenever decodebin finds a new stream. It is emitted
           before looking for any elements that can handle that stream.*/
-       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select",
-                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_select), (gpointer)player);
+       _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select",
+                                               G_CALLBACK(_mmplayer_gst_decode_autoplug_select), (gpointer)player);
 
        /* This signal is emitted once decodebin has finished decoding all the data.*/
-       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "drained",
-                                               G_CALLBACK(__mmplayer_gst_decode_drained), (gpointer)player);
+       _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "drained",
+                                               G_CALLBACK(_mmplayer_gst_decode_drained), (gpointer)player);
 
        /* This signal is emitted when a element is added to the bin.*/
-       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added",
-                                               G_CALLBACK(__mmplayer_gst_element_added), (gpointer)player);
+       _mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added",
+                                               G_CALLBACK(_mmplayer_gst_element_added), (gpointer)player);
 
 ERROR:
        return decodebin;
@@ -5881,7 +6100,7 @@ __mmplayer_gst_make_queue2(mmplayer_t *player)
                dur_bytes = 0;
        }
 
-       __mm_player_streaming_set_queue2(player->streamer,
+       _mm_player_streaming_set_queue2(player->streamer,
                                                                        queue2,
                                                                        FALSE,
                                                                        type,
@@ -5891,7 +6110,7 @@ __mmplayer_gst_make_queue2(mmplayer_t *player)
 }
 
 gboolean
-__mmplayer_gst_create_decoder(mmplayer_t *player, GstPad *srcpad, const GstCaps *caps)
+_mmplayer_gst_create_decoder(mmplayer_t *player, GstPad *srcpad, const GstCaps *caps)
 {
        mmplayer_gst_element_t *mainbin = NULL;
        GstElement *decodebin = NULL;
@@ -5945,7 +6164,7 @@ __mmplayer_gst_create_decoder(mmplayer_t *player, GstPad *srcpad, const GstCaps
        }
 
        /* create decodebin */
-       decodebin = __mmplayer_gst_make_decodebin(player);
+       decodebin = _mmplayer_gst_make_decodebin(player);
        if (!decodebin) {
                LOGE("failed to make decodebin");
                goto ERROR;
@@ -6104,8 +6323,8 @@ DONE:
        return MM_ERROR_NONE;
 }
 
-static void
-__mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data)
+void
+_mmplayer_pipeline_complete(GstElement *decodebin, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
 
@@ -6114,9 +6333,9 @@ __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data)
        MMPLAYER_RETURN_IF_FAIL(player);
 
        /* remove fakesink. */
-       if (!__mmplayer_gst_remove_fakesink(player,
+       if (!_mmplayer_gst_remove_fakesink(player,
                                &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK])) {
-               /* NOTE : __mmplayer_pipeline_complete() can be called several time. because
+               /* NOTE : _mmplayer_pipeline_complete() can be called several time. because
                 * signaling mechanism(pad-added, no-more-pad, new-decoded-pad) from various
                 * source element are not same. To overcome this situation, this function will called
                 * several places and several times. Therefore, this is not an error case.
@@ -6126,8 +6345,7 @@ __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data)
 
        LOGD("[handle: %p] pipeline has completely constructed", player);
 
-       if ((player->ini.async_start) &&
-               (player->msg_posted == FALSE) &&
+       if ((player->msg_posted == FALSE) &&
                (player->cmd >= MMPLAYER_COMMAND_START))
                __mmplayer_handle_missed_plugin(player);
 
@@ -6177,7 +6395,7 @@ __mmplayer_get_next_uri(mmplayer_t *player)
                        continue;
                }
 
-               if (__mmplayer_parse_profile((const char *)uri, NULL, &profile) != MM_ERROR_NONE) {
+               if (_mmplayer_parse_profile((const char *)uri, NULL, &profile) != MM_ERROR_NONE) {
                        LOGE("failed to parse profile");
                        continue;
                }
@@ -6192,16 +6410,15 @@ __mmplayer_get_next_uri(mmplayer_t *player)
                break;
        }
 
-       if (uri_idx == num_of_list) {
+       if (!uri || uri_idx == num_of_list) {
                LOGE("failed to find next uri");
                return FALSE;
        }
 
        player->uri_info.uri_idx = uri_idx;
-       mm_attrs_set_string_by_name(player->attrs, "profile_uri", uri);
-
-       if (mm_attrs_commit_all(player->attrs)) {
-               LOGE("failed to commit");
+       if (mm_player_set_attribute((MMHandleType)player, NULL,
+                       "profile_uri", uri, strlen(uri), NULL) != MM_ERROR_NONE) {
+               LOGE("failed to set attribute");
                return FALSE;
        }
 
@@ -6212,20 +6429,26 @@ __mmplayer_get_next_uri(mmplayer_t *player)
 static gboolean
 __mmplayer_verify_gapless_play_path(mmplayer_t *player)
 {
-#define REPEAT_COUNT_INFINITELY -1
+#define REPEAT_COUNT_INFINITE -1
 #define REPEAT_COUNT_MIN 2
+#define ORIGINAL_URI_ONLY 1
 
        MMHandleType attrs = 0;
        gint video = 0;
        gint count = 0;
        gint gapless = 0;
-       guint num_of_list = 0;
+       guint num_of_uri = 0;
        int profile_tv = -1;
 
        MMPLAYER_FENTER();
 
        LOGD("checking for gapless play option");
 
+       if (player->build_audio_offload) {
+               LOGE("offload path is not supportable.");
+               goto ERROR;
+       }
+
        if (player->pipeline->textbin) {
                LOGE("subtitle path is enabled. gapless play is not supported.");
                goto ERROR;
@@ -6237,7 +6460,10 @@ __mmplayer_verify_gapless_play_path(mmplayer_t *player)
                goto ERROR;
        }
 
-       mm_attrs_get_int_by_name(attrs, "content_video_found", &video);
+       mm_attrs_multiple_get(player->attrs, NULL,
+                       "content_video_found", &video,
+                       "profile_play_count", &count,
+                       MM_PLAYER_GAPLESS_MODE, &gapless, NULL);
 
        /* gapless playback is not supported in case of video at TV profile. */
        profile_tv = __mmplayer_check_profile();
@@ -6246,35 +6472,25 @@ __mmplayer_verify_gapless_play_path(mmplayer_t *player)
                goto ERROR;
        }
 
-       if (mm_attrs_get_int_by_name(attrs, "profile_play_count", &count) != MM_ERROR_NONE)
-               LOGE("failed to get play count");
-
-       if (mm_attrs_get_int_by_name(attrs, "gapless_mode", &gapless) != MM_ERROR_NONE)
-               LOGE("failed to get gapless mode");
-
        /* check repeat count in case of audio */
        if (!gapless &&
-               (video || (count != REPEAT_COUNT_INFINITELY && count < REPEAT_COUNT_MIN))) {
+               (video || (count != REPEAT_COUNT_INFINITE && count < REPEAT_COUNT_MIN))) {
                LOGW("gapless is disabled");
                goto ERROR;
        }
 
-       num_of_list = g_list_length(player->uri_info.uri_list);
+       num_of_uri = g_list_length(player->uri_info.uri_list);
 
-       LOGD("repeat count = %d, num_of_list = %d", count, num_of_list);
+       LOGD("repeat count = %d, num_of_list = %d", count, num_of_uri);
 
-       if (num_of_list == 0) {
+       if (num_of_uri == ORIGINAL_URI_ONLY) {
                /* audio looping path */
                if (count >= REPEAT_COUNT_MIN) {
                        /* decrease play count */
                        /* we succeeded to rewind. update play count and then wait for next EOS */
                        count--;
-                       mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
-                       /* commit attribute */
-                       if (mm_attrs_commit_all(attrs))
-                               LOGE("failed to commit attribute");
-
-               } else if (count != REPEAT_COUNT_INFINITELY) {
+                       mm_player_set_attribute((MMHandleType)player, NULL, "profile_play_count", count, NULL);
+               } else if (count != REPEAT_COUNT_INFINITE) {
                        LOGD("there is no next uri and no repeat");
                        goto ERROR;
                }
@@ -6294,200 +6510,90 @@ ERROR:
 }
 
 static void
-__mmplayer_initialize_gapless_play(mmplayer_t *player)
+__mmplayer_remove_sinkpad (const GValue *item, gpointer user_data)
 {
-       int i;
-
-       MMPLAYER_FENTER();
-
-       player->smooth_streaming = FALSE;
-       player->videodec_linked = 0;
-       player->audiodec_linked = 0;
-       player->textsink_linked = 0;
-       player->is_external_subtitle_present = FALSE;
-       player->is_external_subtitle_added_now = FALSE;
-       player->not_supported_codec = MISSING_PLUGIN_NONE;
-       player->can_support_codec = FOUND_PLUGIN_NONE;
-       player->pending_seek.is_pending = false;
-       player->pending_seek.pos = 0;
-       player->msg_posted = FALSE;
-       player->has_many_types = FALSE;
-       player->no_more_pad = FALSE;
-       player->not_found_demuxer = 0;
-       player->seek_state = MMPLAYER_SEEK_NONE;
-       player->is_subtitle_force_drop = FALSE;
-       player->play_subtitle = FALSE;
-       player->adjust_subtitle_pos = 0;
-
-       player->total_bitrate = 0;
-       player->total_maximum_bitrate = 0;
-
-       __mmplayer_track_initialize(player);
-       __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
-
-       for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++) {
-               player->bitrate[i] = 0;
-               player->maximum_bitrate[i] = 0;
-       }
-
-       if (player->v_stream_caps) {
-               gst_caps_unref(player->v_stream_caps);
-               player->v_stream_caps = NULL;
-       }
-
-       mm_attrs_set_int_by_name(player->attrs, "content_video_found", 0);
-
-       /* clean found audio decoders */
-       if (player->audio_decoders) {
-               GList *a_dec = player->audio_decoders;
-               for (; a_dec; a_dec = g_list_next(a_dec)) {
-                       gchar *name = a_dec->data;
-                       MMPLAYER_FREEIF(name);
-               }
-               g_list_free(player->audio_decoders);
-               player->audio_decoders = NULL;
-       }
-
-       MMPLAYER_FLEAVE();
+       GstPad *sinkpad = g_value_get_object (item);
+       GstElement *element = GST_ELEMENT(user_data);
+       LOGD("(%s)element release request pad(%s)", GST_ELEMENT_NAME(element), GST_PAD_NAME(sinkpad));
+       gst_element_release_request_pad(element, GST_PAD(sinkpad));
 }
 
-static void
-__mmplayer_activate_next_source(mmplayer_t *player, GstState target)
+static gboolean
+__mmplayer_deactivate_combiner(mmplayer_t *player, mmplayer_track_type_e type)
 {
-       mmplayer_gst_element_t *mainbin = NULL;
-       MMMessageParamType msg_param = {0,};
-       GstElement *element = NULL;
-       MMHandleType attrs = 0;
-       char *uri = NULL;
-       main_element_id_e elem_idx = MMPLAYER_M_NUM;
+       mmplayer_gst_element_t *sinkbin = NULL;
+       main_element_id_e concatId = MMPLAYER_M_NUM;
+       main_element_id_e sinkId = MMPLAYER_M_NUM;
+       gboolean send_notice = FALSE;
+       GstElement *element;
+       GstIterator *iter;
 
        MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
 
-       if (!player || !player->pipeline || !player->pipeline->mainbin) {
-               LOGE("player is not initialized");
-               goto ERROR;
-       }
-
-       mainbin = player->pipeline->mainbin;
-       msg_param.code = MM_ERROR_PLAYER_INTERNAL;
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if (!attrs) {
-               LOGE("fail to get attributes");
-               goto ERROR;
-       }
-
-       /* Initialize Player values */
-       __mmplayer_initialize_gapless_play(player);
-
-       mm_attrs_get_string_by_name(attrs, "profile_uri", &uri);
-
-       if (__mmplayer_parse_profile((const char *)uri, NULL, &player->profile) != MM_ERROR_NONE) {
-               LOGE("failed to parse profile");
-               msg_param.code = MM_ERROR_PLAYER_INVALID_URI;
-               goto ERROR;
-       }
-
-       if ((MMPLAYER_URL_HAS_DASH_SUFFIX(player)) ||
-               (MMPLAYER_URL_HAS_HLS_SUFFIX(player))) {
-               LOGE("dash or hls is not supportable");
-               msg_param.code = MM_ERROR_PLAYER_INVALID_URI;
-               goto ERROR;
-       }
-
-       element = __mmplayer_gst_create_source(player);
-       if (!element) {
-               LOGE("no source element was created");
-               goto ERROR;
-       }
-
-       if (gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element) == FALSE) {
-               LOGE("failed to add source element to pipeline");
-               gst_object_unref(GST_OBJECT(element));
-               element = NULL;
-               goto ERROR;
-       }
-
-       /* take source element */
-       mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC;
-       mainbin[MMPLAYER_M_SRC].gst = element;
-
-       element = NULL;
-
-       if (MMPLAYER_IS_HTTP_STREAMING(player)) {
-               if (player->streamer == NULL) {
-                       player->streamer = __mm_player_streaming_create();
-                       __mm_player_streaming_initialize(player->streamer, TRUE);
-               }
-
-               elem_idx = MMPLAYER_M_TYPEFIND;
-               element = gst_element_factory_make("typefind", "typefinder");
-               __mmplayer_add_signal_connection(player, G_OBJECT(element),
-                       MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type", G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player);
-       } else {
-               elem_idx = MMPLAYER_M_AUTOPLUG;
-               element = __mmplayer_gst_make_decodebin(player);
-       }
-
-       /* check autoplug element is OK */
-       if (!element) {
-               LOGE("can not create element(%d)", elem_idx);
-               goto ERROR;
-       }
-
-       if (gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element) == FALSE) {
-               LOGE("failed to add sinkbin to pipeline");
-               gst_object_unref(GST_OBJECT(element));
-               element = NULL;
-               goto ERROR;
-       }
-
-       mainbin[elem_idx].id = elem_idx;
-       mainbin[elem_idx].gst = element;
+       LOGD("type %d", type);
 
-       if (gst_element_link(mainbin[MMPLAYER_M_SRC].gst, mainbin[elem_idx].gst) == FALSE) {
-               LOGE("Failed to link src - autoplug(or typefind)");
-               goto ERROR;
+       switch (type) {
+       case MM_PLAYER_TRACK_TYPE_AUDIO:
+               concatId = MMPLAYER_M_A_CONCAT;
+               sinkId = MMPLAYER_A_BIN;
+               sinkbin = player->pipeline->audiobin;
+               break;
+       case MM_PLAYER_TRACK_TYPE_VIDEO:
+               concatId = MMPLAYER_M_V_CONCAT;
+               sinkId = MMPLAYER_V_BIN;
+               sinkbin = player->pipeline->videobin;
+               send_notice = TRUE;
+               break;
+       case MM_PLAYER_TRACK_TYPE_TEXT:
+               concatId = MMPLAYER_M_T_CONCAT;
+               sinkId = MMPLAYER_T_BIN;
+               sinkbin = player->pipeline->textbin;
+               break;
+       default:
+               LOGE("requested type is not supportable");
+               return FALSE;
+               break;
        }
 
-       if (gst_element_set_state(mainbin[MMPLAYER_M_SRC].gst, target) == GST_STATE_CHANGE_FAILURE) {
-               LOGE("Failed to change state of src element");
-               goto ERROR;
-       }
+       element = player->pipeline->mainbin[concatId].gst;
+       if (!element)
+               return TRUE;
 
-       if (!MMPLAYER_IS_HTTP_STREAMING(player)) {
-               if (gst_element_set_state(mainbin[MMPLAYER_M_AUTOPLUG].gst, target) == GST_STATE_CHANGE_FAILURE) {
-                       LOGE("Failed to change state of decodebin");
-                       goto ERROR;
-               }
-       } else {
-               if (gst_element_set_state(mainbin[MMPLAYER_M_TYPEFIND].gst, target) == GST_STATE_CHANGE_FAILURE) {
-                       LOGE("Failed to change state of src element");
-                       goto ERROR;
+       if ((sinkbin) && (sinkbin[sinkId].gst)) {
+               GstPad *srcpad = gst_element_get_static_pad(element, "src");
+               GstPad *sinkpad = gst_element_get_static_pad(sinkbin[sinkId].gst, "sink");
+               if (srcpad && sinkpad) {
+                       /* after getting drained signal there is no data flows, so no need to do pad_block */
+                       LOGD("unlink %s:%s, %s:%s", GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
+                       gst_pad_unlink(srcpad, sinkpad);
+
+                       /* send custom event to sink pad to handle it at video sink */
+                       if (send_notice) {
+                               LOGD("send custom event to sinkpad");
+                               GstStructure *s = gst_structure_new_empty("tizen/flush-buffer");
+                               GstEvent *event = gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM, s);
+                               gst_pad_send_event(sinkpad, event);
+                       }
                }
+               gst_object_unref(srcpad);
+               gst_object_unref(sinkpad);
        }
 
-       player->gapless.stream_changed = TRUE;
-       player->gapless.running = TRUE;
-       MMPLAYER_FLEAVE();
-       return;
-
-ERROR:
-       if (player) {
-               MMPLAYER_PLAYBACK_UNLOCK(player);
+       LOGD("release concat request pad");
+       /* release and unref requests pad from the selector */
+       iter = gst_element_iterate_sink_pads(element);
+       while (gst_iterator_foreach(iter, __mmplayer_remove_sinkpad, element) == GST_ITERATOR_RESYNC)
+               gst_iterator_resync(iter);
+       gst_iterator_free(iter);
 
-               if (!player->msg_posted) {
-                       MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
-                       player->msg_posted = TRUE;
-               }
-       }
-       return;
+       return TRUE;
 }
 
 static gboolean
 __mmplayer_deactivate_selector(mmplayer_t *player, mmplayer_track_type_e type)
 {
-       mmplayer_selector_t *selector = &player->selector[type];
+       mmplayer_track_t *selector = &player->track[type];
        mmplayer_gst_element_t *sinkbin = NULL;
        main_element_id_e selectorId = MMPLAYER_M_NUM;
        main_element_id_e sinkId = MMPLAYER_M_NUM;
@@ -6558,11 +6664,12 @@ __mmplayer_deactivate_selector(mmplayer_t *player, mmplayer_track_type_e type)
                LOGD("selector release");
 
                /* release and unref requests pad from the selector */
-               for (n = 0; n < selector->channels->len; n++) {
-                       GstPad *sinkpad = g_ptr_array_index(selector->channels, n);
+               for (n = 0; n < selector->streams->len; n++) {
+                       GstPad *sinkpad = g_ptr_array_index(selector->streams, n);
                        gst_element_release_request_pad((player->pipeline->mainbin[selectorId].gst), sinkpad);
                }
-               g_ptr_array_set_size(selector->channels, 0);
+
+               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);
@@ -6580,25 +6687,32 @@ __mmplayer_deactivate_old_path(mmplayer_t *player)
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       if ((!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_AUDIO)) ||
-               (!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_VIDEO)) ||
-               (!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_TEXT))) {
-               LOGE("deactivate selector error");
-               goto ERROR;
+       if (MMPLAYER_USE_DECODEBIN(player)) {
+               if ((!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_AUDIO)) ||
+                       (!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_VIDEO)) ||
+                       (!__mmplayer_deactivate_selector(player, MM_PLAYER_TRACK_TYPE_TEXT))) {
+                       LOGE("deactivate selector error");
+                       goto ERROR;
+               }
+       } else {
+               if ((!__mmplayer_deactivate_combiner(player, MM_PLAYER_TRACK_TYPE_AUDIO)) ||
+                       (!__mmplayer_deactivate_combiner(player, MM_PLAYER_TRACK_TYPE_VIDEO)) ||
+                       (!__mmplayer_deactivate_combiner(player, MM_PLAYER_TRACK_TYPE_TEXT))) {
+                       LOGE("deactivate concat error");
+                       goto ERROR;
+               }
        }
 
-       __mmplayer_track_destroy(player);
+       _mmplayer_track_destroy(player);
        __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG);
 
        if (player->streamer) {
-               __mm_player_streaming_initialize(player->streamer, FALSE);
-               __mm_player_streaming_destroy(player->streamer);
+               _mm_player_streaming_initialize(player->streamer, FALSE);
+               _mm_player_streaming_destroy(player->streamer);
                player->streamer = NULL;
        }
 
-       MMPLAYER_PLAYBACK_LOCK(player);
        MMPLAYER_GAPLESS_PLAY_THREAD_SIGNAL(player);
-
        MMPLAYER_FLEAVE();
        return;
 
@@ -6625,10 +6739,11 @@ _mmplayer_set_uri(MMHandleType hplayer, const char *uri)
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(uri, MM_ERROR_INVALID_ARGUMENT);
 
-       mm_attrs_set_string_by_name(player->attrs, "profile_uri", uri);
-       if (mm_attrs_commit_all(player->attrs)) {
-               LOGE("failed to commit the original uri.");
+       if (mm_player_set_attribute(hplayer, NULL,
+                       "profile_uri", uri, strlen(uri), NULL) != MM_ERROR_NONE) {
+               LOGE("failed to set attribute");
                result = MM_ERROR_PLAYER_INTERNAL;
        } else {
                if (_mmplayer_set_next_uri(hplayer, uri, TRUE) != MM_ERROR_NONE)
@@ -6712,7 +6827,7 @@ _mmplayer_get_next_uri(MMHandleType hplayer, char **uri)
        if (num_of_list > 0) {
                gint uri_idx = player->uri_info.uri_idx;
 
-               if (uri_idx < num_of_list-1)
+               if (uri_idx < num_of_list - 1)
                        uri_idx++;
                else
                        uri_idx = 0;
@@ -6727,8 +6842,8 @@ _mmplayer_get_next_uri(MMHandleType hplayer, char **uri)
        return MM_ERROR_NONE;
 }
 
-static void
-__mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPad *pad,
+void
+_mmplayer_gst_decode_unknown_type(GstElement *elem, GstPad *pad,
        GstCaps *caps, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
@@ -6749,9 +6864,9 @@ __mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPad *pad,
        __mmplayer_check_not_supported_codec(player, klass, mime);
 }
 
-static gboolean
-__mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPad *pad,
-       GstCaps *caps,  gpointer data)
+gboolean
+_mmplayer_gst_decode_autoplug_continue(GstElement *bin, GstPad *pad,
+       GstCaps *caps, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
        const char *mime = NULL;
@@ -6778,15 +6893,10 @@ __mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPad *pad,
                caps_str = gst_caps_to_string(caps);
                /* set it directly because not sent by TAG */
                if (g_strrstr(caps_str, "mobile-xmf"))
-                       mm_attrs_set_string_by_name(player->attrs, "content_audio_codec", "mobile-xmf");
+                       mm_player_set_attribute((MMHandleType)player, NULL,
+                                       "content_audio_codec", "mobile-xmf", strlen("mobile-xmf"), NULL);
+
                MMPLAYER_FREEIF(caps_str);
-       } else if (g_str_has_prefix(mime, "video") && !player->ini.video_playback_supported) {
-               MMMessageParamType msg_param;
-               memset(&msg_param, 0, sizeof(MMMessageParamType));
-               msg_param.code = MM_ERROR_NOT_SUPPORT_API;
-               MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
-               LOGD("video file is not supported on this device");
-               ret = FALSE;
        } else if (g_str_has_prefix(mime, "video") && player->videodec_linked) {
                LOGD("already video linked");
                ret = FALSE;
@@ -6800,7 +6910,7 @@ __mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPad *pad,
 static gboolean
 __mmplayer_is_audio_offload_device_type(mmplayer_t *player)
 {
-       gboolean ret = TRUE;
+       gboolean ret = FALSE;
        GDBusConnection *conn = NULL;
        GError *err = NULL;
        GVariant *result = NULL;
@@ -6810,9 +6920,8 @@ __mmplayer_is_audio_offload_device_type(mmplayer_t *player)
 
        conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
        if (!conn || err) {
-               LOGE("failed g_bus_get_sync() (%s)", err ? err->message : NULL);
+               LOGE("failed g_bus_get_sync() (%s)", (err ? err->message : "null"));
                g_error_free(err);
-               ret = FALSE;
                goto DONE;
        }
 
@@ -6828,9 +6937,8 @@ __mmplayer_is_audio_offload_device_type(mmplayer_t *player)
                                        NULL,
                                        &err);
        if (!result || err) {
-               LOGE("failed g_dbus_connection_call_sync() (%s)", err ? err->message : NULL);
+               LOGE("failed g_dbus_connection_call_sync() (%s)", (err ? err->message : "null"));
                g_error_free(err);
-               ret = FALSE;
                goto DONE;
        }
 
@@ -6838,10 +6946,8 @@ __mmplayer_is_audio_offload_device_type(mmplayer_t *player)
        g_variant_get(result, "(&s&s)", &dbus_device_type, &dbus_ret);
 
        LOGI("g_dbus_connection_call_sync() success (%s, %s)", dbus_device_type, dbus_ret);
-       if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
-               ret = FALSE;
+       if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
                goto DONE;
-       }
 
        /* the device type is listed in ini file among audio-jack, bt-a2dp, usb-audio, builtin-speaker */
        for (idx = 0; player->ini.audio_offload_device_type[idx][0] != '\0'; idx++) {
@@ -6853,11 +6959,11 @@ __mmplayer_is_audio_offload_device_type(mmplayer_t *player)
        }
 
        LOGD("audio offload is not supportable");
-       ret = FALSE;
 
 DONE:
        g_variant_unref(result);
-       g_object_unref(conn);
+       if (conn)
+               g_object_unref(conn);
 
        return ret;
 }
@@ -6882,9 +6988,7 @@ static void __mmplayer_rebuild_audio_pipeline(mmplayer_t *player)
        _mmplayer_set_position((MMHandleType)player, position);
 
        /* async not to be blocked in streaming case */
-       mm_attrs_set_int_by_name(player->attrs, "profile_prepare_async", TRUE);
-       if (mm_attrs_commit_all(player->attrs))
-               LOGE("failed to commit");
+       mm_player_set_attribute((MMHandleType)player, NULL, "profile_prepare_async", TRUE, NULL);
 
        _mmplayer_pause((MMHandleType)player);
 
@@ -6949,6 +7053,37 @@ __mmplayer_add_audio_device_connected_cb(mmplayer_t *player)
        return TRUE;
 }
 
+int _mmplayer_audio_offload_is_activated(MMHandleType hplayer, bool *activated)
+{
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(activated, MM_ERROR_INVALID_ARGUMENT);
+
+       *activated = player->build_audio_offload;
+
+       LOGD("offload activated : %d", (int)*activated);
+
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+}
+
+static gboolean
+__mmplayer_is_offload_supported_type(mmplayer_t *player)
+{
+       /* NOTE :
+          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)) {
+               LOGD("offload supportable media format type");
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
 static gboolean
 __mmplayer_can_build_audio_offload_path(mmplayer_t *player)
 {
@@ -6959,7 +7094,7 @@ __mmplayer_can_build_audio_offload_path(mmplayer_t *player)
        MMPLAYER_RETURN_VAL_IF_FAIL(player && player->attrs, FALSE);
 
        LOGD("current stream : %s, sink: %s", player->type, player->ini.audio_offload_sink_element);
-       if (!__mmplayer_is_only_mp3_type(player->type))
+       if (!__mmplayer_is_offload_supported_type(player))
                goto DONE;
 
        if (!strcmp(player->ini.audio_offload_sink_element, "")) {
@@ -6979,6 +7114,12 @@ __mmplayer_can_build_audio_offload_path(mmplayer_t *player)
        }
        gst_object_unref(factory);
 
+       if (_mmplayer_acquire_hw_resource(player,
+                       MMPLAYER_RESOURCE_TYPE_AUDIO_OFFLOAD) != MM_ERROR_NONE) {
+               LOGE("failed to acquire audio offload decoder resource");
+               goto DONE;
+       }
+
        if (!__mmplayer_add_audio_device_connected_cb(player))
                goto DONE;
 
@@ -6989,6 +7130,9 @@ __mmplayer_can_build_audio_offload_path(mmplayer_t *player)
        ret = TRUE;
 
 DONE:
+       if (!ret)
+               __mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_AUDIO_OFFLOAD);
+
        MMPLAYER_FLEAVE();
        return ret;
 }
@@ -6997,8 +7141,6 @@ static GstAutoplugSelectResult
 __mmplayer_check_codec_info(mmplayer_t *player, const char *klass, GstCaps *caps, char *factory_name)
 {
        GstAutoplugSelectResult ret = GST_AUTOPLUG_SELECT_TRY;
-       int idx = 0;
-       int codec_type = MM_PLAYER_CODEC_TYPE_DEFAULT;
        int audio_offload = 0;
 
        if ((g_strrstr(klass, "Codec/Decoder/Audio"))) {
@@ -7012,35 +7154,17 @@ __mmplayer_check_codec_info(mmplayer_t *player, const char *klass, GstCaps *caps
                        player->can_support_codec |= FOUND_PLUGIN_AUDIO;
                        player->audiodec_linked = 1;
 
-                       ret = GST_AUTOPLUG_SELECT_EXPOSE;
-                       goto DONE;
-               }
-
-               mm_attrs_get_int_by_name(player->attrs, "audio_codec_type", &codec_type);
-
-               LOGD("audio codec type: %d", codec_type);
-               if (codec_type == MM_PLAYER_CODEC_TYPE_HW) {
-                       /* sw codec will be skipped */
-                       for (idx = 0; player->ini.audiocodec_element_sw[idx][0] != '\0'; idx++) {
-                               if (strstr(factory_name, player->ini.audiocodec_element_sw[idx])) {
-                                       LOGW("skipping sw acodec:[%s] by codec type", factory_name);
-                                       ret = GST_AUTOPLUG_SELECT_SKIP;
-                                       goto DONE;
-                               }
-                       }
-               } else if (codec_type == MM_PLAYER_CODEC_TYPE_SW) {
-                       /* hw codec will be skipped */
-                       if (strcmp(player->ini.audiocodec_element_hw, "") &&
-                           g_strrstr(factory_name, player->ini.audiocodec_element_hw)) {
-                               LOGW("skipping hw acodec:[%s] by codec type", factory_name);
-                               ret = GST_AUTOPLUG_SELECT_SKIP;
-                               goto DONE;
-                       }
+                       ret = GST_AUTOPLUG_SELECT_EXPOSE;
+                       goto DONE;
                }
 
+               /* FIXME: If HW audio decoder is selected, related resource have to be acquired here.
+                                 And need to consider the multi-track audio content.
+                         There is no HW audio decoder in public. */
+
                /* set stream information */
                if (!player->audiodec_linked)
-                       __mmplayer_set_audio_attrs(player, caps);
+                       _mmplayer_set_audio_attrs(player, caps);
 
                /* update codec info */
                player->not_supported_codec &= MISSING_PLUGIN_VIDEO;
@@ -7049,55 +7173,22 @@ __mmplayer_check_codec_info(mmplayer_t *player, const char *klass, GstCaps *caps
 
        } else if (g_strrstr(klass, "Codec/Decoder/Video")) {
 
-               mm_attrs_get_int_by_name(player->attrs, "video_codec_type", &codec_type);
-
-               LOGD("video codec type: %d", codec_type);
-               if (codec_type == MM_PLAYER_CODEC_TYPE_HW) {
-                       /* sw codec is skipped */
-                       for (idx = 0; player->ini.videocodec_element_sw[idx][0] != '\0'; idx++) {
-                               if (strstr(factory_name, player->ini.videocodec_element_sw[idx])) {
-                                       LOGW("skipping sw vcodec:[%s] by codec type", factory_name);
-                                       ret = GST_AUTOPLUG_SELECT_SKIP;
-                                       goto DONE;
-                               }
-                       }
-               } else if (codec_type == MM_PLAYER_CODEC_TYPE_SW) {
-                       /* hw codec is skipped */
-                       if (g_strrstr(factory_name, player->ini.videocodec_element_hw)) {
-                               LOGW("skipping hw vcodec:[%s] by codec type", factory_name);
-                               ret = GST_AUTOPLUG_SELECT_SKIP;
-                               goto DONE;
-                       }
-               }
-
                if ((strlen(player->ini.videocodec_element_hw) > 0) &&
                        (g_strrstr(factory_name, player->ini.videocodec_element_hw))) {
 
                        /* mark video decoder for acquire */
-                       if (player->video_decoder_resource == NULL) {
-                               if (mm_resource_manager_mark_for_acquire(player->resource_manager,
-                                               MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER,
-                                               MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
-                                               &player->video_decoder_resource)
-                                       != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                                       LOGE("could not mark video_decoder resource for acquire");
-                                       ret = GST_AUTOPLUG_SELECT_SKIP;
-                                       goto DONE;
-                               }
-                       } else {
+                       if (player->hw_resource[MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER] != NULL) {
                                LOGW("video decoder resource is already acquired, skip it.");
                                ret = GST_AUTOPLUG_SELECT_SKIP;
                                goto DONE;
                        }
 
-                       player->interrupted_by_resource = FALSE;
-                       /* acquire resources for video playing */
-                       if (mm_resource_manager_commit(player->resource_manager)
-                                       != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                               LOGE("could not acquire resources for video decoding");
+                       if (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
+                               LOGE("failed to acquire video decoder resource");
                                ret = GST_AUTOPLUG_SELECT_SKIP;
                                goto DONE;
                        }
+                       player->interrupted_by_resource = FALSE;
                }
 
                /* update codec info */
@@ -7110,8 +7201,132 @@ DONE:
        return ret;
 }
 
+GValueArray *
+_mmplayer_gst_decode_autoplug_sort(GstElement *bin,
+               GstPad *pad, GstCaps *caps, GValueArray *factories, gpointer data)
+{
+#define DEFAULT_IDX 0xFFFF
+#define MIN_FACTORY_NUM 2
+       mmplayer_t *player = (mmplayer_t *)data;
+       GValueArray *new_factories = NULL;
+       GValue val = { 0, };
+       GstElementFactory *factory = NULL;
+       const gchar *klass = NULL;
+       gchar *factory_name = NULL;
+       guint hw_dec_idx = DEFAULT_IDX;
+       guint first_sw_dec_idx = DEFAULT_IDX;
+       guint last_sw_dec_idx = DEFAULT_IDX;
+       guint new_pos = DEFAULT_IDX;
+       guint rm_pos = DEFAULT_IDX;
+       int audio_codec_type;
+       int video_codec_type;
+       mmplayer_codec_type_e codec_type = MM_PLAYER_CODEC_TYPE_DEFAULT;
+
+       if (factories->n_values < MIN_FACTORY_NUM)
+               return NULL;
+
+       mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_VIDEO_CODEC_TYPE, &video_codec_type);
+       mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_AUDIO_CODEC_TYPE, &audio_codec_type);
+
+#ifdef __DEBUG__
+       LOGD("num of factory : %d, codec type %d, %d", factories->n_values, video_codec_type, audio_codec_type);
+#endif
+       for (int i = 0 ; i < factories->n_values ; i++) {
+               gchar *hw_dec_info = NULL;
+               gchar (*sw_dec_info)[PLAYER_INI_MAX_STRLEN] = {NULL, };
+
+               factory = g_value_get_object(g_value_array_get_nth(factories, i));
+               if (!factory) {
+                       LOGW("failed to get factory object");
+                       continue;
+               }
+               klass = gst_element_factory_get_klass(factory);
+               factory_name = GST_OBJECT_NAME(factory);
+
+#ifdef __DEBUG__
+               LOGD("Klass [%s] Factory [%s]", klass, factory_name);
+#endif
+               if (g_strrstr(klass, "Codec/Decoder/Audio")) {
+                       if (!player->need_audio_dec_sorting) {
+                               LOGD("sorting is not required");
+                               return NULL;
+                       }
+                       codec_type = audio_codec_type;
+                       hw_dec_info = player->ini.audiocodec_element_hw;
+                       sw_dec_info = player->ini.audiocodec_element_sw;
+               } else if (g_strrstr(klass, "Codec/Decoder/Video")) {
+                       if (!player->need_video_dec_sorting) {
+                               LOGD("sorting is not required");
+                               return NULL;
+                       }
+                       codec_type = video_codec_type;
+                       hw_dec_info = player->ini.videocodec_element_hw;
+                       sw_dec_info = player->ini.videocodec_element_sw;
+               } else {
+                       continue;
+               }
+
+               if (g_strrstr(factory_name, hw_dec_info)) {
+                       hw_dec_idx = i;
+               } else {
+                       for (int j = 0; sw_dec_info[j][0] != '\0'; j++) {
+                               if (strstr(factory_name, sw_dec_info[j])) {
+                                       last_sw_dec_idx = i;
+                                       if (first_sw_dec_idx == DEFAULT_IDX) {
+                                               first_sw_dec_idx = i;
+                                       }
+                               }
+                       }
+
+                       if (first_sw_dec_idx == DEFAULT_IDX)
+                               LOGW("unknown codec %s", factory_name);
+               }
+       }
+
+       if (hw_dec_idx == DEFAULT_IDX || first_sw_dec_idx == DEFAULT_IDX)
+               return NULL;
+
+       if (codec_type == MM_PLAYER_CODEC_TYPE_HW) {
+               if (hw_dec_idx < first_sw_dec_idx)
+                       return NULL;
+               new_pos = first_sw_dec_idx;
+               rm_pos = hw_dec_idx + 1;
+       } else if (codec_type == MM_PLAYER_CODEC_TYPE_SW) {
+               if (last_sw_dec_idx < hw_dec_idx)
+                       return NULL;
+               new_pos = last_sw_dec_idx + 1;
+               rm_pos = hw_dec_idx;
+       } else {
+               return NULL;
+       }
+
+       /* change position - insert H/W decoder according to the new position */
+       factory = g_value_get_object(g_value_array_get_nth(factories, hw_dec_idx));
+       if (!factory) {
+               LOGW("failed to get factory object");
+               return NULL;
+       }
+       new_factories = g_value_array_copy(factories);
+       g_value_init (&val, G_TYPE_OBJECT);
+       g_value_set_object (&val, factory);
+       g_value_array_insert(new_factories, new_pos, &val);
+       g_value_unset (&val);
+       g_value_array_remove(new_factories, rm_pos);    /* remove previous H/W element */
+
+       for (int i = 0 ; i < new_factories->n_values ; i++) {
+               factory = g_value_get_object(g_value_array_get_nth(new_factories, i));
+               if (factory)
+                       LOGD("[Re-arranged] Klass [%s] Factory [%s]",
+                               gst_element_factory_get_klass(factory), GST_OBJECT_NAME (factory));
+               else
+                       LOGE("[Re-arranged] failed to get factory object");
+       }
+
+       return new_factories;
+}
+
 gint
-__mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPad *pad,
+_mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPad *pad,
        GstCaps *caps, GstElementFactory *factory, gpointer data)
 {
        GstAutoplugSelectResult result = GST_AUTOPLUG_SELECT_TRY;
@@ -7203,7 +7418,7 @@ __mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPad *pad,
 
                /* don't make video because of not required */
                if ((stype == MM_DISPLAY_SURFACE_NULL) &&
-                       (!player->set_mode.media_packet_video_stream)) {
+                       (!player->set_mode.video_export)) {
                        LOGD("no need video decoding, expose pad");
                        result = GST_AUTOPLUG_SELECT_EXPOSE;
                        goto DONE;
@@ -7240,8 +7455,8 @@ DONE:
        return result;
 }
 
-static void
-__mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPad *new_pad,
+void
+_mmplayer_gst_decode_pad_removed(GstElement *elem, GstPad *new_pad,
        gpointer data)
 {
        //mmplayer_t *player = (mmplayer_t *)data;
@@ -7264,8 +7479,38 @@ __mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPad *new_pad,
        gst_caps_unref(caps);
 }
 
-static void
-__mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
+void
+_mmplayer_gst_about_to_finish(GstElement *bin, gpointer data)
+{
+       mmplayer_t *player = (mmplayer_t *)data;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player);
+
+       LOGD("got about to finish signal");
+
+       if (!MMPLAYER_CMD_TRYLOCK(player)) {
+               LOGW("Fail to get cmd lock");
+               return;
+       }
+
+       if (!__mmplayer_verify_gapless_play_path(player)) {
+               LOGD("decoding is finished.");
+               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);
+
+       MMPLAYER_FLEAVE();
+}
+
+void
+_mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
        GstIterator *iter = NULL;
@@ -7277,22 +7522,21 @@ __mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       LOGD("__mmplayer_gst_decode_drained");
+       LOGD("got drained signal");
 
        if (!MMPLAYER_CMD_TRYLOCK(player)) {
                LOGW("Fail to get cmd lock");
                return;
        }
 
-       if (!player->gapless.reconfigure && /* If it is already checked, skip verify. */
-               !__mmplayer_verify_gapless_play_path(player)) {
+       if (!__mmplayer_verify_gapless_play_path(player)) {
                LOGD("decoding is finished.");
-               __mmplayer_reset_gapless_state(player);
                MMPLAYER_CMD_UNLOCK(player);
                return;
        }
 
-       player->gapless.reconfigure = TRUE;
+       _mmplayer_set_reconfigure_state(player, TRUE);
+       MMPLAYER_CMD_UNLOCK(player);
 
        /* check decodebin src pads whether they received EOS or not */
        iter = gst_element_iterate_src_pads(player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst);
@@ -7322,7 +7566,6 @@ __mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
 
        if (!is_all_drained) {
                LOGD("Wait util the all pads get EOS.");
-               MMPLAYER_CMD_UNLOCK(player);
                MMPLAYER_FLEAVE();
                return;
        }
@@ -7333,13 +7576,12 @@ __mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
        /* 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_deactivate_old_path(player);
-       MMPLAYER_CMD_UNLOCK(player);
 
        MMPLAYER_FLEAVE();
 }
 
 void
-__mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data)
+_mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
        const gchar *klass = NULL;
@@ -7357,6 +7599,16 @@ __mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data
                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")) {
@@ -7372,7 +7624,9 @@ __mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data
                                                "max-video-height", player->adaptive_info.limit.height, NULL);
 
        } else if (g_strrstr(klass, "Demuxer")) {
-               //LOGD("plugged element is demuxer. take it");
+#ifdef __DEBUG__
+               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;
        }
@@ -7411,8 +7665,8 @@ __mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data
                        (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) ||
                        (MMPLAYER_IS_DASH_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);
+                       _mm_player_streaming_set_multiqueue(player->streamer, element);
+                       _mm_player_streaming_sync_property(player->streamer, player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst);
                }
 
        }
@@ -7429,20 +7683,6 @@ __mmplayer_release_misc(mmplayer_t *player)
 
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       player->video_stream_cb = NULL;
-       player->video_stream_cb_user_param = NULL;
-       player->video_stream_prerolled = false;
-
-       player->audio_stream_render_cb = NULL;
-       player->audio_stream_cb_user_param = NULL;
-       player->audio_stream_sink_sync = false;
-
-       player->video_stream_changed_cb = NULL;
-       player->video_stream_changed_cb_user_param = NULL;
-
-       player->audio_stream_changed_cb = NULL;
-       player->audio_stream_changed_cb_user_param = NULL;
-
        player->sent_bos = FALSE;
        player->playback_rate = DEFAULT_PLAYBACK_RATE;
 
@@ -7466,13 +7706,14 @@ __mmplayer_release_misc(mmplayer_t *player)
        player->play_subtitle = FALSE;
        player->adjust_subtitle_pos = 0;
        player->has_closed_caption = FALSE;
-       player->set_mode.media_packet_video_stream = false;
+       player->set_mode.video_export = false;
        player->profile.uri_type = MM_PLAYER_URI_TYPE_NONE;
        memset(&player->set_mode, 0, sizeof(mmplayer_setting_mode_t));
        /* recover mode */
        player->set_mode.rich_audio = cur_mode;
 
-       if (mm_sound_remove_device_connected_callback(player->audio_device_cb_id) != MM_ERROR_NONE)
+       if (player->audio_device_cb_id > 0 &&
+               mm_sound_remove_device_connected_callback(player->audio_device_cb_id) != MM_ERROR_NONE)
                LOGW("failed to remove audio device_connected_callback");
        player->audio_device_cb_id = 0;
 
@@ -7481,17 +7722,6 @@ __mmplayer_release_misc(mmplayer_t *player)
                player->maximum_bitrate[i] = 0;
        }
 
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-
-       /* remove media stream cb(appsrc cb) */
-       for (i = 0; i < MM_PLAYER_STREAM_TYPE_MAX; i++) {
-               player->media_stream_buffer_status_cb[i] = NULL;
-               player->media_stream_seek_data_cb[i] = NULL;
-               player->buffer_cb_user_param[i] = NULL;
-               player->seek_cb_user_param[i] = NULL;
-       }
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
-
        /* free memory related to audio effect */
        MMPLAYER_FREEIF(player->audio_effect_info.custom_ext_level_for_plugin);
 
@@ -7533,45 +7763,44 @@ __mmplayer_release_misc_post(mmplayer_t *player)
        MMPLAYER_FENTER();
 
        /* player->pipeline is already released before. */
-
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       mm_attrs_set_int_by_name(player->attrs, "content_video_found", 0);
+       player->video_decoded_cb = NULL;
+       player->video_decoded_cb_user_param = NULL;
+       player->video_stream_prerolled = false;
+
+       player->audio_decoded_cb = NULL;
+       player->audio_decoded_cb_user_param = NULL;
+       player->audio_extract_opt = MM_PLAYER_AUDIO_EXTRACT_DEFAULT;
+
+       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);
 
        /* clean found audio decoders */
        if (player->audio_decoders) {
-               GList *a_dec = player->audio_decoders;
-               for (; a_dec; a_dec = g_list_next(a_dec)) {
-                       gchar *name = a_dec->data;
-                       MMPLAYER_FREEIF(name);
-               }
-               g_list_free(player->audio_decoders);
+               g_list_free_full(player->audio_decoders, (GDestroyNotify)g_free);
                player->audio_decoders = NULL;
        }
 
        /* clean the uri list except original uri */
-       if (player->uri_info.uri_list) {
+       if (player->uri_info.uri_list && g_list_length(player->uri_info.uri_list) > 1) {
+               GList *tmp = NULL;
                original_uri = g_list_nth_data(player->uri_info.uri_list, 0);
+               tmp = g_list_remove_link(player->uri_info.uri_list, player->uri_info.uri_list);
+               g_list_free_full(tmp, (GDestroyNotify)g_free);
 
-               if (player->attrs) {
-                       mm_attrs_set_string_by_name(player->attrs, "profile_uri", original_uri);
-                       LOGD("restore original uri = %s", original_uri);
+               if (!original_uri)
+                       LOGW("failed to get original uri info");
 
-                       if (mm_attrs_commit_all(player->attrs))
-                               LOGE("failed to commit the original uri.");
-               }
+               mm_player_set_attribute((MMHandleType)player, NULL, "profile_uri",
+                               original_uri, (original_uri) ? strlen(original_uri) : (0), NULL);
 
-               GList *uri_list = player->uri_info.uri_list;
-               for (; uri_list; uri_list = g_list_next(uri_list)) {
-                       gchar *uri = uri_list->data;
-                       MMPLAYER_FREEIF(uri);
-               }
-               g_list_free(player->uri_info.uri_list);
-               player->uri_info.uri_list = NULL;
        }
 
        /* clear the audio stream buffer list */
-       __mmplayer_audio_stream_clear_buffer(player, FALSE);
+       _mmplayer_audio_stream_clear_buffer(player, FALSE);
 
        /* clear the video stream bo list */
        __mmplayer_video_stream_destroy_bo_list(player);
@@ -7616,7 +7845,7 @@ __mmplayer_check_subtitle(mmplayer_t *player)
 }
 
 void
-__mmplayer_cancel_eos_timer(mmplayer_t *player)
+_mmplayer_cancel_eos_timer(mmplayer_t *player)
 {
        MMPLAYER_RETURN_IF_FAIL(player);
 
@@ -7656,7 +7885,7 @@ __mmplayer_del_sink(mmplayer_t *player, GstElement *sink)
 }
 
 void
-__mmplayer_add_signal_connection(mmplayer_t *player, GObject *object,
+_mmplayer_add_signal_connection(mmplayer_t *player, GObject *object,
        mmplayer_signal_type_e type, const gchar *signal, GCallback cb_funct, gpointer u_data)
 {
        mmplayer_signal_item_t *item = NULL;
@@ -7743,22 +7972,20 @@ __mmplayer_release_signal_connection(mmplayer_t *player, mmplayer_signal_type_e
 }
 
 int
-_mmplayer_change_videosink(MMHandleType handle, MMDisplaySurfaceType surface_type, void *display_overlay)
+_mmplayer_change_videosink(MMHandleType handle, MMDisplaySurfaceType surface_type, int wl_surface_id)
 {
        mmplayer_t *player = 0;
        int prev_display_surface_type = 0;
-       void *prev_display_overlay = NULL;
 
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(handle, MM_ERROR_COMMON_INVALID_ARGUMENT);
-       MMPLAYER_RETURN_VAL_IF_FAIL(display_overlay, MM_ERROR_COMMON_INVALID_ARGUMENT);
 
        player = MM_PLAYER_CAST(handle);
 
        /* check video sinkbin is created */
-       if (__mmplayer_video_param_check_video_sink_bin(player) == MM_ERROR_NONE) {
-               LOGE("Videosink is already created");
+       if (_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_NUM)) {
+               LOGW("Videosink is already created");
                return MM_ERROR_NONE;
        }
 
@@ -7773,7 +8000,6 @@ _mmplayer_change_videosink(MMHandleType handle, MMDisplaySurfaceType surface_typ
        /* load previous attributes */
        if (player->attrs) {
                mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &prev_display_surface_type);
-               mm_attrs_get_data_by_name(player->attrs, "display_overlay", &prev_display_overlay);
                LOGD("[0: Video surface, 4: EVAS surface] previous surface type(%d), new surface type(%d)", prev_display_surface_type, surface_type);
                if (prev_display_surface_type == surface_type) {
                        LOGD("incoming display surface type is same as previous one, do nothing..");
@@ -7788,13 +8014,8 @@ _mmplayer_change_videosink(MMHandleType handle, MMDisplaySurfaceType surface_typ
 
        /* videobin is not created yet, so we just set attributes related to display surface */
        LOGD("store display attribute for given surface type(%d)", surface_type);
-       mm_attrs_set_int_by_name(player->attrs, "display_surface_type", surface_type);
-       mm_attrs_set_data_by_name(player->attrs, "display_overlay", display_overlay, sizeof(display_overlay));
-       if (mm_attrs_commit_all(player->attrs)) {
-               LOGE("failed to commit attribute");
-               MMPLAYER_FLEAVE();
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
+       mm_player_set_attribute(handle, NULL, "display_surface_type", surface_type,
+                       "display_overlay", wl_surface_id, NULL);
 
        MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
@@ -7891,7 +8112,7 @@ _mmplayer_sync_subtitle_pipeline(mmplayer_t *player)
        LOGD("seek time = %"G_GINT64_FORMAT", rate = %f", time, player->playback_rate);
        event = gst_event_new_seek(player->playback_rate, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_FLUSH), GST_SEEK_TYPE_SET, time, GST_SEEK_TYPE_NONE, -1);
        if (event) {
-               __mmplayer_gst_send_event_to_sink(player, event);
+               _mmplayer_gst_send_event_to_sink(player, event);
        } else {
                result = MM_ERROR_PLAYER_INTERNAL;
                LOGE("gst_event_new_seek failed"); /* pipeline will got error and can not be recovered */
@@ -7971,22 +8192,22 @@ __mmplayer_change_external_subtitle_language(mmplayer_t *player, const char *fil
                goto EXIT;
        }
 
-       if (!util_get_storage_info(filepath, &player->storage_info[MMPLAYER_PATH_TEXT])) {
+       if (!_mmplayer_get_storage_info(filepath, &player->storage_info[MMPLAYER_PATH_TEXT])) {
                LOGE("failed to get storage info of subtitle path");
                result = MM_ERROR_PLAYER_INVALID_URI;
                goto EXIT;
        }
 
-       LOGD("old subtitle file path is [%s]", subtitle_uri);
-       LOGD("new subtitle file path is [%s]", filepath);
+       SECURE_LOGD("old subtitle file path is [%s]", subtitle_uri);
+       SECURE_LOGD("new subtitle file path is [%s]", filepath);
 
        if (!strcmp(filepath, subtitle_uri)) {
-               LOGD("No need to swtich subtitle, as input filepath is same as current filepath");
+               LOGD("subtitle path is not changed");
                goto EXIT;
        } else {
-               mm_attrs_set_string_by_name(player->attrs, "subtitle_uri", filepath);
-               if (mm_attrs_commit_all(player->attrs)) {
-                       LOGE("failed to commit.");
+               if (mm_player_set_attribute((MMHandleType)player, NULL,
+                               "subtitle_uri", filepath, strlen(filepath), NULL) != MM_ERROR_NONE) {
+                       LOGE("failed to set attribute");
                        goto EXIT;
                }
        }
@@ -8021,7 +8242,7 @@ __mmplayer_change_external_subtitle_language(mmplayer_t *player, const char *fil
 
        g_object_set(G_OBJECT(mainbin[MMPLAYER_M_SUBSRC].gst), "location", filepath, NULL);
 
-       charset = util_get_charset(filepath);
+       charset = _mmplayer_get_charset(filepath);
        if (charset) {
                LOGD("detected charset is %s", charset);
                g_object_set(G_OBJECT(mainbin[MMPLAYER_M_SUBPARSE].gst), "subtitle-encoding", charset, NULL);
@@ -8051,9 +8272,9 @@ _mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char *filepath)
        if (filepath) {
                /* check file path */
                if ((path = strstr(filepath, "file://")))
-                       result = util_exist_file_path(path + 7);
+                       result = _mmplayer_exist_file_path(path + 7);
                else
-                       result = util_exist_file_path(filepath);
+                       result = _mmplayer_exist_file_path(filepath);
 
                if (result != MM_ERROR_NONE) {
                        LOGE("invalid subtitle path 0x%X", result);
@@ -8063,9 +8284,9 @@ _mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char *filepath)
 
        if (!player->pipeline) {
                /* IDLE state */
-               mm_attrs_set_string_by_name(player->attrs, "subtitle_uri", filepath);
-               if (mm_attrs_commit_all(player->attrs)) {
-                       LOGE("failed to commit");       /* subtitle path will not be created */
+               if (mm_player_set_attribute(hplayer, NULL, "subtitle_uri", filepath,
+                               (filepath)?(strlen(filepath)):(0), NULL) != MM_ERROR_NONE) {
+                       LOGE("failed to set attribute");
                        return MM_ERROR_PLAYER_INTERNAL;
                }
        } else {
@@ -8074,13 +8295,13 @@ _mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char *filepath)
                MMPLAYER_RETURN_VAL_IF_FAIL(filepath, MM_ERROR_COMMON_INVALID_ARGUMENT);
 
                if (!__mmplayer_check_subtitle(player)) {
-                       mm_attrs_set_string_by_name(player->attrs, "subtitle_uri", filepath);
-                       if (mm_attrs_commit_all(player->attrs)) {
-                               LOGE("failed to commit");
+                       if (mm_player_set_attribute(hplayer, NULL, "subtitle_uri",
+                                       filepath, strlen(filepath), NULL) != MM_ERROR_NONE) {
+                               LOGE("failed to set attribute");
                                return MM_ERROR_PLAYER_INTERNAL;
                        }
 
-                       if (MM_ERROR_NONE != __mmplayer_gst_create_text_pipeline(player)) {
+                       if (__mmplayer_gst_create_text_pipeline(player) != MM_ERROR_NONE) {
                                LOGE("fail to create text pipeline");
                                return MM_ERROR_PLAYER_INTERNAL;
                        }
@@ -8107,6 +8328,44 @@ _mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char *filepath)
 }
 
 static int
+__mmplayer_switch_stream(mmplayer_t *player, mmplayer_track_type_e type, int index)
+{
+       guint active_idx = 0;
+       GstStream *stream = NULL;
+       GList *streams = NULL;
+       GstEvent *ev = NULL;
+       GstCaps *caps = NULL;
+
+       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) {
+                       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));
+                       LOGD("Selecting %d type stream : %s\n", i, gst_stream_get_stream_id(stream));
+
+                       if (i == MM_PLAYER_TRACK_TYPE_AUDIO) {
+                               caps = gst_stream_get_caps(stream);
+                               if (caps) {
+                                       _mmplayer_set_audio_attrs(player, caps);
+                                       gst_caps_unref(caps);
+                               }
+                       }
+               }
+       }
+
+       ev = gst_event_new_select_streams(streams);
+       gst_element_send_event(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, ev);
+       g_list_free(streams);
+
+       return MM_ERROR_NONE;
+}
+
+static int
 __mmplayer_change_selector_pad(mmplayer_t *player, mmplayer_track_type_e type, int index)
 {
        int result = MM_ERROR_NONE;
@@ -8142,7 +8401,7 @@ __mmplayer_change_selector_pad(mmplayer_t *player, mmplayer_track_type_e type, i
                goto EXIT;
        }
 
-       total_track_num = player->selector[type].total_track_num;
+       total_track_num = player->track[type].total_track_num;
        if (total_track_num <= 0) {
                result = MM_ERROR_PLAYER_NO_OP;
                LOGD("Language list is not available");
@@ -8182,7 +8441,10 @@ __mmplayer_change_selector_pad(mmplayer_t *player, mmplayer_track_type_e type, i
                gst_object_unref(sinkpad);
 
        if (type == MM_PLAYER_TRACK_TYPE_AUDIO)
-               __mmplayer_set_audio_attrs(player, caps);
+               _mmplayer_set_audio_attrs(player, caps);
+
+       if (caps)
+               gst_caps_unref(caps);
 
 EXIT:
        MMPLAYER_FREEIF(change_pad_name);
@@ -8199,7 +8461,6 @@ _mmplayer_change_track_language(MMHandleType hplayer, mmplayer_track_type_e type
        gint current_active_index = 0;
 
        GstState current_state = GST_STATE_VOID_PENDING;
-       GstEvent *event = NULL;
        gint64 time = 0;
 
        MMPLAYER_FENTER();
@@ -8210,13 +8471,13 @@ _mmplayer_change_track_language(MMHandleType hplayer, mmplayer_track_type_e type
        if (!player->pipeline) {
                LOGE("Track %d pre setting -> %d", type, index);
 
-               player->selector[type].active_pad_index = index;
+               player->track[type].active_track_index = index;
                goto EXIT;
        }
 
        mainbin = player->pipeline->mainbin;
 
-       current_active_index = player->selector[type].active_pad_index;
+       current_active_index = player->track[type].active_track_index;
 
        /*If index is same as running index no need to change the pad*/
        if (current_active_index == index)
@@ -8234,23 +8495,30 @@ _mmplayer_change_track_language(MMHandleType hplayer, mmplayer_track_type_e type
                goto EXIT;
        }
 
-       result = __mmplayer_change_selector_pad(player, type, index);
+       if (MMPLAYER_USE_DECODEBIN(player))
+               result = __mmplayer_change_selector_pad(player, type, index);
+       else
+               result = __mmplayer_switch_stream(player, type, index);
+
        if (result != MM_ERROR_NONE) {
-               LOGE("change selector pad error");
+               LOGE("failed to change track");
                goto EXIT;
        }
 
-       player->selector[type].active_pad_index = index;
+       player->track[type].active_track_index = index;
 
-       if (current_state == GST_STATE_PLAYING) {
-               event = gst_event_new_seek(player->playback_rate, GST_FORMAT_TIME,
-                       (GstSeekFlags)(GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SKIP),
-                       GST_SEEK_TYPE_SET, time, GST_SEEK_TYPE_NONE, -1);
-               if (event) {
-                       __mmplayer_gst_send_event_to_sink(player, event);
-               } else {
-                       result = MM_ERROR_PLAYER_INTERNAL;
-                       goto EXIT;
+       if (MMPLAYER_USE_DECODEBIN(player)) {
+               GstEvent *event = NULL;
+               if (current_state == GST_STATE_PLAYING) {
+                       event = gst_event_new_seek(player->playback_rate, GST_FORMAT_TIME,
+                               (GstSeekFlags)(GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SKIP),
+                               GST_SEEK_TYPE_SET, time, GST_SEEK_TYPE_NONE, -1);
+                       if (event) {
+                               _mmplayer_gst_send_event_to_sink(player, event);
+                       } else {
+                               result = MM_ERROR_PLAYER_INTERNAL;
+                               goto EXIT;
+                       }
                }
        }
 
@@ -8331,11 +8599,13 @@ __mmplayer_dump_buffer_probe_cb(GstPad *pad,  GstPadProbeInfo *info, gpointer u_
        MMPLAYER_RETURN_VAL_IF_FAIL(dump_data, GST_PAD_PROBE_PASS);
 
        gst_buffer_map(buffer, &probe_info, GST_MAP_READ);
-
-//     LOGD("buffer timestamp = %" GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
-
+#ifdef __DEBUG__
+       LOGD("buffer timestamp = %" GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
+#endif
        fwrite(probe_info.data, 1, probe_info.size , dump_data);
 
+       gst_buffer_unmap(buffer, &probe_info);
+
        return GST_PAD_PROBE_OK;
 }
 
@@ -8386,7 +8656,9 @@ _mm_player_video_stream_internal_buffer_unref(void *buffer)
 {
        MMPLAYER_FENTER();
        if (buffer) {
-               // LOGD("unref internal gst buffer %p", buffer);
+#ifdef __DEBUG__
+               LOGD("unref internal gst buffer %p", buffer);
+#endif
                gst_buffer_unref((GstBuffer *)buffer);
                buffer = NULL;
        }
@@ -8414,25 +8686,6 @@ _mmplayer_get_timeout(MMHandleType hplayer, int *timeout)
        return MM_ERROR_NONE;
 }
 
-int
-_mmplayer_get_num_of_video_out_buffers(MMHandleType hplayer, int *num, int *extra_num)
-{
-       mmplayer_t *player = (mmplayer_t *)hplayer;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(num && extra_num, MM_ERROR_COMMON_INVALID_ARGUMENT);
-
-       *num = player->video_num_buffers;
-       *extra_num = player->video_extra_num_buffers;
-
-       LOGD("state %d, num %d(%d)", MMPLAYER_CURRENT_STATE(player), *num, *extra_num);
-
-       MMPLAYER_FLEAVE();
-       return MM_ERROR_NONE;
-}
-
 static void
 __mmplayer_initialize_storage_info(mmplayer_t *player, mmplayer_path_type_e path_type)
 {
@@ -8611,61 +8864,71 @@ _mmplayer_get_streaming_buffering_time(MMHandleType hplayer, int *prebuffer_ms,
 }
 
 int
-_mmplayer_set_codec_type(MMHandleType hplayer, mmplayer_stream_type_e stream_type, mmplayer_video_codec_type_e codec_type)
+_mmplayer_set_codec_type(MMHandleType hplayer, mmplayer_stream_type_e stream_type, mmplayer_codec_type_e codec_type)
 {
 #define IDX_FIRST_SW_CODEC 0
        mmplayer_t *player = (mmplayer_t *)hplayer;
-       const char *attr_name = (stream_type == MM_PLAYER_STREAM_TYPE_AUDIO) ? (MM_PLAYER_AUDIO_CODEC_TYPE) : (MM_PLAYER_VIDEO_CODEC_TYPE);
-       MMHandleType attrs = 0;
+       int default_codec_type = MM_PLAYER_CODEC_TYPE_DEFAULT;
+       const char *attr_name = NULL;
+       const char *default_type = NULL;
+       const char *element_hw = NULL;
+       const char *element_sw = NULL;
 
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       LOGD("ini setting : [a][h:%s][s:%s] / [v][h:%s][s:%s]",
-               player->ini.audiocodec_element_hw, player->ini.audiocodec_element_sw[IDX_FIRST_SW_CODEC],
-               player->ini.videocodec_element_hw, player->ini.videocodec_element_sw[IDX_FIRST_SW_CODEC]);
+       LOGD("stream type: %d, codec_type: %d", stream_type, codec_type);
 
+       /* FIXME: player need to know whether the decoder exist or not about required codec type since 6.0*/
        switch (stream_type) {
        case MM_PLAYER_STREAM_TYPE_AUDIO:
-       /* to support audio codec selection, codec info have to be added in ini file as below.
-          audio codec element hw = xxxx
-          audio codec element sw = avdec */
-               if (((codec_type == MM_PLAYER_CODEC_TYPE_HW) &&
-                        (!strcmp(player->ini.audiocodec_element_hw, ""))) ||
-                       ((codec_type == MM_PLAYER_CODEC_TYPE_SW) &&
-                        (!strcmp(player->ini.audiocodec_element_sw[IDX_FIRST_SW_CODEC], "")))) {
-                       LOGE("There is no audio codec info for codec_type %d", codec_type);
-                       return MM_ERROR_PLAYER_NO_OP;
-               }
-       break;
+               attr_name = MM_PLAYER_AUDIO_CODEC_TYPE;
+               default_type = player->ini.audiocodec_default_type;
+               element_hw = player->ini.audiocodec_element_hw;
+               element_sw = player->ini.audiocodec_element_sw[IDX_FIRST_SW_CODEC];
+               break;
        case MM_PLAYER_STREAM_TYPE_VIDEO:
-       /* to support video codec selection, codec info have to be added in ini file as below.
-          video codec element hw = omx
-          video codec element sw = avdec */
-               if (((codec_type == MM_PLAYER_CODEC_TYPE_HW) &&
-                        (!strcmp(player->ini.videocodec_element_hw, ""))) ||
-                       ((codec_type == MM_PLAYER_CODEC_TYPE_SW) &&
-                        (!strcmp(player->ini.videocodec_element_sw[IDX_FIRST_SW_CODEC], "")))) {
-                       LOGE("There is no video codec info for codec_type %d", codec_type);
-                       return MM_ERROR_PLAYER_NO_OP;
-               }
-       break;
+               attr_name = MM_PLAYER_VIDEO_CODEC_TYPE;
+               default_type = player->ini.videocodec_default_type;
+               element_hw = player->ini.videocodec_element_hw;
+               element_sw = player->ini.videocodec_element_sw[IDX_FIRST_SW_CODEC];
+               break;
        default:
                LOGE("Invalid stream type %s", MMPLAYER_STREAM_TYPE_GET_NAME(stream_type));
                return MM_ERROR_COMMON_INVALID_ARGUMENT;
-       break;
+               break;
        }
 
-       LOGD("update %s codec_type to %d", attr_name, codec_type);
+       LOGD("default setting: [%s][%s][h:%s][s:%s]", attr_name, default_type, element_hw, element_sw);
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       mm_attrs_set_int_by_name(attrs, attr_name, codec_type);
+       if (!strcmp(default_type, "sw"))
+               default_codec_type = MM_PLAYER_CODEC_TYPE_SW;
+       else
+               default_codec_type = MM_PLAYER_CODEC_TYPE_HW;
+
+       if (codec_type == MM_PLAYER_CODEC_TYPE_DEFAULT)
+               codec_type = default_codec_type;
+
+       /* to support codec selection, codec info have to be added in ini file.
+          in case of hw codec is selected, filter elements should be applied
+          depending on the hw capabilities. */
+       if (codec_type != default_codec_type) {
+               if (((codec_type == MM_PLAYER_CODEC_TYPE_HW) && (!strcmp(element_hw, ""))) ||
+                       ((codec_type == MM_PLAYER_CODEC_TYPE_SW) && (!strcmp(element_sw, "")))) {
+                       LOGE("There is no codec for type %d", codec_type);
+                       return MM_ERROR_PLAYER_NO_OP;
+               }
 
-       if (mm_attrs_commit_all(player->attrs)) {
-               LOGE("failed to commit codec_type attributes");
-               return MM_ERROR_PLAYER_INTERNAL;
+               LOGD("sorting is required");
+               if (stream_type == MM_PLAYER_STREAM_TYPE_AUDIO)
+                       player->need_audio_dec_sorting = TRUE;
+               else
+                       player->need_video_dec_sorting = TRUE;
        }
 
+       LOGD("update %s codec_type to %d", attr_name, codec_type);
+       mm_player_set_attribute(hplayer, NULL, attr_name, codec_type, NULL);
+
        MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
 }
@@ -8744,7 +9007,7 @@ _mmplayer_set_video_roi_area(MMHandleType hplayer, double scale_x, double scale_
 {
        mmplayer_t *player = (mmplayer_t *)hplayer;
        MMHandleType attrs = 0;
-       void *handle = NULL;
+       int handle = 0;
        int ret = MM_ERROR_NONE;
 
        MMPLAYER_FENTER();
@@ -8754,7 +9017,7 @@ _mmplayer_set_video_roi_area(MMHandleType hplayer, double scale_x, double scale_
        attrs = MMPLAYER_GET_ATTRS(player);
        MMPLAYER_RETURN_VAL_IF_FAIL(attrs, MM_ERROR_PLAYER_INTERNAL);
 
-       mm_attrs_get_data_by_name(attrs, "display_overlay", &handle);
+       mm_attrs_get_int_by_name(attrs, "display_overlay", &handle);
        if (!handle) {
                LOGE("Display handle is NULL, after setting window handle, set video roi area");
                return MM_ERROR_PLAYER_INTERNAL;
@@ -8766,7 +9029,7 @@ _mmplayer_set_video_roi_area(MMHandleType hplayer, double scale_x, double scale_
        player->video_roi.scale_height = scale_height;
 
        /* check video sinkbin is created */
-       if (__mmplayer_video_param_check_video_sink_bin(player) != MM_ERROR_NONE)
+       if (!_mmplayer_is_videosink_ready(player, MM_DISPLAY_SURFACE_NUM))
                return MM_ERROR_NONE;
 
        if (!gst_video_overlay_set_video_roi_area(
@@ -8804,6 +9067,93 @@ _mmplayer_get_video_roi_area(MMHandleType hplayer, double *scale_x, double *scal
        return ret;
 }
 
+int
+_mmplayer_set_client_pid(MMHandleType hplayer, int pid)
+{
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+
+       MMPLAYER_FENTER();
+
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       player->client_pid = pid;
+
+       LOGD("client pid[%d] %p", pid, player);
+
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_is_audio_control_available(MMHandleType hplayer, mmplayer_audio_control_opt_e opt, bool *available)
+{
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       mmplayer_codec_type_e codec_type = MM_PLAYER_CODEC_TYPE_DEFAULT;
+       enum audio_element_id elem_id = MMPLAYER_A_NUM;
+
+       MMPLAYER_FENTER();
+
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(available, MM_ERROR_INVALID_ARGUMENT);
+
+       *available = true;
+       mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_AUDIO_CODEC_TYPE, (int *)&codec_type);
+
+       LOGD("current state %d, codec_type %d", MMPLAYER_CURRENT_STATE(player), codec_type);
+
+       if (codec_type == MM_PLAYER_CODEC_TYPE_SW)
+               return MM_ERROR_NONE;
+
+       /* in case of audio codec default type is HW */
+       switch(opt) {
+               case MM_PLAYER_AUDIO_CONTROL_OPT_EFFECT:
+                       if (player->ini.support_audio_effect)
+                               return MM_ERROR_NONE;
+                       elem_id = MMPLAYER_A_FILTER;
+               break;
+               case MM_PLAYER_AUDIO_CONTROL_OPT_REPLAYGAIN:
+                       if (player->ini.support_replaygain_control)
+                               return MM_ERROR_NONE;
+                       elem_id = MMPLAYER_A_RGVOL;
+               break;
+               case MM_PLAYER_AUDIO_CONTROL_OPT_PITCH:
+                       if (player->ini.support_pitch_control)
+                               return MM_ERROR_NONE;
+                       elem_id = MMPLAYER_A_PITCH;
+               break;
+               case MM_PLAYER_AUDIO_CONTROL_OPT_PCM_EXPORTING:
+                       if (player->ini.support_audio_effect)
+                               return MM_ERROR_NONE;
+               break;
+               /* default case handling is not required */
+       }
+
+       if (MMPLAYER_CURRENT_STATE(player) < MM_PLAYER_STATE_READY) {
+               LOGW("audio control option [%d] is not available", opt);
+               *available = false;
+       } else {
+               /* setting pcm exporting option is allowed before READY state */
+               if (opt == MM_PLAYER_AUDIO_CONTROL_OPT_PCM_EXPORTING)
+                       return MM_ERROR_PLAYER_INVALID_STATE;
+
+               /* check whether the audio filter exist or not after READY state,
+                  because the sw codec could be added during auto-plugging in some cases */
+               if (!player->pipeline ||
+                       !player->pipeline->audiobin ||
+                       !player->pipeline->audiobin[elem_id].gst) {
+                       LOGW("there is no audio elem [%d]", elem_id);
+                       *available = false;
+               }
+       }
+
+       LOGD("audio control opt %d, available %d", opt, *available);
+
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
+
 static gboolean
 __mmplayer_update_duration_value(mmplayer_t *player)
 {
@@ -8823,7 +9173,7 @@ __mmplayer_update_duration_value(mmplayer_t *player)
        }
 
        /* update streaming service type */
-       player->streaming_type =  __mmplayer_get_stream_service_type(player);
+       player->streaming_type =  _mmplayer_get_stream_service_type(player);
 
        /* check duration is OK */
        if (dur_nsec == 0 && !MMPLAYER_IS_LIVE_STREAMING(player))
@@ -8844,17 +9194,25 @@ __mmplayer_update_audio_attrs(mmplayer_t *player, MMHandleType attrs)
        GstPad *pad = NULL;
        gint samplerate = 0, channels = 0;
        GstStructure *p = NULL;
+       GstElement *aconv = NULL;
 
        LOGD("try to update audio attrs");
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->audiobin, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->audiobin[MMPLAYER_A_SINK].gst, FALSE);
 
-       pad = gst_element_get_static_pad(
-                       player->pipeline->audiobin[MMPLAYER_A_CONV].gst, "sink");
+       if (player->pipeline->audiobin[MMPLAYER_A_CONV].gst) {
+               aconv = player->pipeline->audiobin[MMPLAYER_A_CONV].gst;
+       } else if (player->pipeline->audiobin[MMPLAYER_A_EXTRACT_CONV].gst) {
+               aconv = player->pipeline->audiobin[MMPLAYER_A_EXTRACT_CONV].gst;
+       } else {
+               LOGE("there is no audio converter");
+               return FALSE;
+       }
+
+       pad = gst_element_get_static_pad(aconv, "sink");
 
        if (!pad) {
-               LOGW("failed to get pad from audiosink");
+               LOGW("failed to get pad from audio converter");
                return FALSE;
        }
 
@@ -8870,10 +9228,11 @@ __mmplayer_update_audio_attrs(mmplayer_t *player, MMHandleType attrs)
        mm_attrs_get_int_by_name(attrs, "content_audio_samplerate", &samplerate);
 
        gst_structure_get_int(p, "rate", &samplerate);
-       mm_attrs_set_int_by_name(attrs, "content_audio_samplerate", samplerate);
-
        gst_structure_get_int(p, "channels", &channels);
-       mm_attrs_set_int_by_name(attrs, "content_audio_channels", channels);
+
+       mm_player_set_attribute((MMHandleType)player, NULL,
+                       "content_audio_samplerate", samplerate,
+                       "content_audio_channels", channels, NULL);
 
        SECURE_LOGD("samplerate : %d    channels : %d", samplerate, channels);
 
@@ -8918,10 +9277,10 @@ __mmplayer_update_video_attrs(mmplayer_t *player, MMHandleType attrs)
 
        p = gst_caps_get_structure(caps_v, 0);
        gst_structure_get_int(p, "width", &width);
-       mm_attrs_set_int_by_name(attrs, "content_video_width", width);
-
        gst_structure_get_int(p, "height", &height);
-       mm_attrs_set_int_by_name(attrs, "content_video_height", height);
+
+       mm_player_set_attribute((MMHandleType)player, NULL,
+                       MM_PLAYER_VIDEO_WIDTH, width, MM_PLAYER_VIDEO_HEIGHT, height, NULL);
 
        gst_structure_get_fraction(p, "framerate", &tmpNu, &tmpDe);
 
@@ -8931,7 +9290,8 @@ __mmplayer_update_video_attrs(mmplayer_t *player, MMHandleType attrs)
        gst_object_unref(pad);
 
        if (tmpDe > 0) {
-               mm_attrs_set_int_by_name(attrs, "content_video_fps", tmpNu / tmpDe);
+               mm_player_set_attribute((MMHandleType)player, NULL,
+                               MM_PLAYER_VIDEO_FPS, (tmpNu/tmpDe), NULL);
                SECURE_LOGD("fps : %d", tmpNu / tmpDe);
        }
 
@@ -8968,9 +9328,10 @@ __mmplayer_update_bitrate_attrs(mmplayer_t *player, MMHandleType attrs)
                msec_dur = GST_TIME_AS_MSECONDS(player->duration);
                if (msec_dur > 0) {
                        bitrate = data_size * 8 * 1000 / msec_dur;
-                       SECURE_LOGD("file size : %"G_GUINT64_FORMAT", video bitrate = %"G_GUINT64_FORMAT, data_size, bitrate);
-                       mm_attrs_set_int_by_name(attrs, "content_video_bitrate", bitrate);
-
+                       SECURE_LOGD("file size : %"G_GUINT64_FORMAT
+                                       ", video bitrate = %"G_GUINT64_FORMAT, data_size, bitrate);
+                       mm_player_set_attribute((MMHandleType)player, NULL,
+                                       MM_PLAYER_VIDEO_BITRATE, (int)bitrate, NULL);
                        ret = TRUE;
                } else {
                        LOGD("player duration is less than 0");
@@ -8979,7 +9340,8 @@ __mmplayer_update_bitrate_attrs(mmplayer_t *player, MMHandleType attrs)
 
        if (MMPLAYER_IS_RTSP_STREAMING(player)) {
                if (player->total_bitrate) {
-                       mm_attrs_set_int_by_name(attrs, "content_video_bitrate", player->total_bitrate);
+                       mm_player_set_attribute((MMHandleType)player, NULL,
+                                       MM_PLAYER_VIDEO_BITRATE, player->total_bitrate, NULL);
                        ret = TRUE;
                }
        }
@@ -9085,15 +9447,16 @@ __mmplayer_set_file_uri(mmplayer_parse_profile_t *data, const char *uri)
        path = (location != NULL) ? (location) : ((char *)uri);
 
 
-       ret = util_exist_file_path(path);
+       ret = _mmplayer_exist_file_path(path);
 
        /* if no protocol prefix exist. check file existence and then give file:// as it's prefix */
        if (ret == MM_ERROR_NONE) {
-               g_snprintf(data->uri,  MM_MAX_URL_LEN, "file://%s", path);
-               if (util_is_sdp_file(path)) {
+               if (_mmplayer_is_sdp_file(path)) {
                        LOGD("uri is actually a file but it's sdp file. giving it to rtspsrc");
+                       g_snprintf(data->uri,  MM_MAX_URL_LEN, "rtsp-sdp://%s", path);
                        data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
                } else {
+                       g_snprintf(data->uri,  MM_MAX_URL_LEN, "file://%s", path);
                        data->uri_type = MM_PLAYER_URI_TYPE_FILE;
                }
        } else if (ret == MM_ERROR_PLAYER_PERMISSION_DENIED) {
@@ -9118,6 +9481,7 @@ __mmplayer_create_stream_from_pad(GstPad *pad)
        mmplayer_video_decoded_data_info_t *stream = NULL;
        gint width, height;
        MMPixelFormatType format;
+       GstVideoInfo info;
 
        caps = gst_pad_get_current_caps(pad);
        if (!caps) {
@@ -9125,14 +9489,18 @@ __mmplayer_create_stream_from_pad(GstPad *pad)
                return NULL;
        }
 
-       /* MMPLAYER_LOG_GST_CAPS_TYPE(caps); */
+#ifdef __DEBUG__
+       MMPLAYER_LOG_GST_CAPS_TYPE(caps);
+#endif
        structure = gst_caps_get_structure(caps, 0);
        gst_structure_get_int(structure, "width", &width);
        gst_structure_get_int(structure, "height", &height);
        string_format = gst_structure_get_string(structure, "format");
+
        if (string_format)
                fourcc = _mmplayer_convert_fourcc_string_to_value(string_format);
-       format = util_get_pixtype(fourcc);
+       format = _mmplayer_get_pixtype(fourcc);
+       gst_video_info_from_caps(&info, caps);
        gst_caps_unref(caps);
 
        /* moved here */
@@ -9150,6 +9518,7 @@ __mmplayer_create_stream_from_pad(GstPad *pad)
        stream->width = width;
        stream->height = height;
        stream->format = format;
+       stream->plane_num = GST_VIDEO_INFO_N_PLANES(&info);
 
        return stream;
 }
@@ -9158,14 +9527,26 @@ static void
 __mmplayer_zerocopy_set_stride_elevation_bo(mmplayer_video_decoded_data_info_t *stream, GstMemory *mem)
 {
        unsigned int pitch = 0;
+       unsigned int size = 0;
        int index = 0;
        tbm_surface_h surface = gst_tizen_memory_get_surface(mem);
+       tbm_bo bo = NULL;
 
        for (index = 0; index < gst_tizen_memory_get_num_bos(mem); index++) {
-               tbm_surface_internal_get_plane_data(surface, index, NULL, NULL, &pitch);
-               stream->bo[index] = tbm_bo_ref(gst_tizen_memory_get_bos(mem, index));
+               bo = gst_tizen_memory_get_bos(mem, index);
+               if (bo)
+                       stream->bo[index] = tbm_bo_ref(bo);
+               else
+                       LOGE("failed to get bo for index %d", index);
+       }
+
+       for (index = 0; index < stream->plane_num; index++) {
+               tbm_surface_internal_get_plane_data(surface, index, &size, NULL, &pitch);
                stream->stride[index] = pitch;
-               stream->elevation[index] = stream->height;
+               if (pitch)
+                       stream->elevation[index] = size / pitch;
+               else
+                       stream->elevation[index] = stream->height;
        }
 }
 
@@ -9299,7 +9680,7 @@ __mmplayer_set_pause_state(mmplayer_t *player)
                return;
 
        /* it's first time to update all content attrs. */
-       __mmplayer_update_content_attrs(player, ATTR_ALL);
+       _mmplayer_update_content_attrs(player, ATTR_ALL);
 }
 
 static void
@@ -9322,7 +9703,7 @@ __mmplayer_set_playing_state(mmplayer_t *player)
         * c-api since c-api doesn't use _start() anymore. It may not work propery with
         * legacy mmfw-player api
         */
-       __mmplayer_update_content_attrs(player, ATTR_MISSING_ONLY);
+       _mmplayer_update_content_attrs(player, ATTR_MISSING_ONLY);
 
        if ((player->cmd == MMPLAYER_COMMAND_START)
                || (player->cmd == MMPLAYER_COMMAND_RESUME)) {
@@ -9349,10 +9730,9 @@ __mmplayer_set_playing_state(mmplayer_t *player)
                else
                        audio_codec = "unknown";
 
-               mm_attrs_set_string_by_name(player->attrs, "content_audio_codec", audio_codec);
-
-               if (mm_attrs_commit_all(player->attrs))
-                       LOGE("failed to update attributes");
+               if (mm_player_set_attribute((MMHandleType)player, NULL,
+                               "content_audio_codec", audio_codec, strlen(audio_codec), NULL) != MM_ERROR_NONE)
+                       LOGE("failed to set attribute");
 
                LOGD("set audio codec type with caps");
        }