[0.2.221] Fix crash when the player has next_uri
[platform/core/multimedia/libmm-player.git] / src / mm_player_priv.c
index 952f8fa..78ae23a 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
 
@@ -143,16 +141,9 @@ static int         __mmplayer_gst_create_video_sink_bin(mmplayer_t *player, GstCaps *ca
 static int             __mmplayer_gst_create_audio_sink_bin(mmplayer_t *player);
 static int             __mmplayer_gst_create_text_sink_bin(mmplayer_t *player);
 
-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 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);
@@ -180,7 +171,7 @@ 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_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 void __mmplayer_deactivate_old_path(mmplayer_t *player);
 static int __mmplayer_gst_create_plain_text_elements(mmplayer_t *player);
@@ -210,36 +201,6 @@ 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
@@ -305,12 +266,6 @@ _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;
@@ -433,9 +388,9 @@ _mmplayer_check_state(mmplayer_t *player, mmplayer_command_state_e command)
        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);
 
@@ -595,7 +550,7 @@ ALREADY_GOING:
        return MM_ERROR_PLAYER_NO_OP;
 }
 
-static int __mmplayer_acquire_hw_resource(mmplayer_t *player, mmplayer_resource_type_e type)
+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;
@@ -607,6 +562,9 @@ static int __mmplayer_acquire_hw_resource(mmplayer_t *player, mmplayer_resource_
                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;
@@ -707,16 +665,11 @@ __mmplayer_initialize_gapless_play(mmplayer_t *player)
                player->v_stream_caps = NULL;
        }
 
-       mm_attrs_set_int_by_name(player->attrs, "content_video_found", 0);
+       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;
        }
 
@@ -725,6 +678,16 @@ __mmplayer_initialize_gapless_play(mmplayer_t *player)
        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)
 {
@@ -741,10 +704,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;
                }
@@ -784,6 +744,42 @@ __mmplayer_remove_g_source_from_context(GMainContext *context, guint source_id)
 }
 
 void
+_mmplayer_watcher_removed_notify(gpointer data)
+{
+       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 > 0) {
+               __mmplayer_remove_g_source_from_context(player->context.thread_default, player->bus_watcher);
+               MMPLAYER_BUS_WATCHER_LOCK(player);
+               end_time = g_get_monotonic_time () + 2 * G_TIME_SPAN_SECOND;
+               while (player->bus_watcher > 0)
+                       MMPLAYER_BUS_WATCHER_WAIT_UNTIL(player, end_time);
+               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;
@@ -793,11 +789,6 @@ _mmplayer_bus_msg_thread_destroy(MMHandleType hplayer)
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       /* disconnecting bus watch */
-       if (player->bus_watcher)
-               __mmplayer_remove_g_source_from_context(player->context.thread_default, player->bus_watcher);
-       player->bus_watcher = 0;
-
        /* destroy the gst bus msg thread */
        if (player->bus_msg_thread) {
                MMPLAYER_BUS_MSG_THREAD_LOCK(player);
@@ -900,8 +891,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;
                }
 
@@ -962,16 +955,12 @@ __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);
        if (!caps_ret)
@@ -1068,11 +1057,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;
 
@@ -1174,14 +1165,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);
@@ -1222,7 +1213,9 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                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;
@@ -1235,12 +1228,12 @@ _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)) {
+               if (MMPLAYER_IS_MS_BUFF_SRC(player) || !MMPLAYER_USE_DECODEBIN(player)) {
                        __mmplayer_gst_create_sinkbin(elem, pad, player);
                        goto DONE;
                }
@@ -1259,7 +1252,7 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                gint samplerate = 0;
                gint channels = 0;
 
-               if (MMPLAYER_IS_MS_BUFF_SRC(player) || player->build_audio_offload) {
+               if (MMPLAYER_IS_MS_BUFF_SRC(player) || !MMPLAYER_USE_DECODEBIN(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);
@@ -1313,7 +1306,8 @@ _mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
                g_object_set(selector, "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);
 
 DONE:
 ERROR:
@@ -1355,9 +1349,9 @@ __mmplayer_create_sink_path(mmplayer_t *player, GstElement *selector, mmplayer_t
        __mmplayer_gst_create_sinkbin(selector, srcpad, 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) {
@@ -1372,35 +1366,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;
@@ -1427,13 +1412,14 @@ __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)) {
@@ -1459,7 +1445,7 @@ __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 */
@@ -1498,8 +1484,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;
@@ -1554,11 +1540,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();
 }
 
@@ -1649,14 +1631,16 @@ __mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
                goto ERROR;
 
        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_attrs_set_string_by_name(player->attrs, "content_audio_format", 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) {
@@ -1682,7 +1666,7 @@ __mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
                        LOGD("display_surface_type (%d)", surface_type);
 
                        if ((surface_type == MM_DISPLAY_SURFACE_OVERLAY) &&
-                               (__mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE)) {
+                               (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE)) {
                                LOGE("failed to acquire video overlay resource");
                                goto ERROR;
                        }
@@ -1745,7 +1729,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:
 
@@ -1813,20 +1797,6 @@ __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)
 {
        int display_rotation = 0;
@@ -1886,8 +1856,7 @@ _mmplayer_get_video_angle(mmplayer_t *player, int *display_angle, int *orientati
        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
@@ -1895,7 +1864,7 @@ __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);
@@ -1906,15 +1875,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);
@@ -1925,15 +1893,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);
@@ -1944,36 +1911,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;
@@ -1982,74 +1946,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;
        }
 
@@ -2070,46 +2027,8 @@ __mmplayer_update_wayland_videosink_video_param(mmplayer_t *player, char *param_
        if (update_all_param)
                __mmplayer_video_param_set_video_roi_area(player);
 
-       return MM_ERROR_NONE;
-}
-
-int
-_mmplayer_update_video_param(mmplayer_t *player, char *param_name)
-{
-       MMHandleType attrs = 0;
-       int surface_type = 0;
-       int ret = MM_ERROR_NONE;
-
-       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;
 }
 
@@ -2147,7 +2066,7 @@ _mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
                        goto ERROR;
                }
        } else {
-               if (__mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
+               if (_mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE) {
                        LOGE("failed to acquire video overlay resource");
                        goto ERROR;
                }
@@ -2318,11 +2237,7 @@ __mmplayer_gst_caps_notify_cb(GstPad *pad, GParamSpec *unused, gpointer data)
                        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_POST_MSG(player, MM_MESSAGE_VIDEO_STREAM_CHANGED, NULL);
        } else {
                LOGW("invalid caps info");
        }
@@ -2373,14 +2288,13 @@ __mmplayer_audio_stream_send_data(mmplayer_t *player, mmplayer_audio_stream_buff
 
        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;
        audio_stream.pcm_format = a_buffer->pcm_format;
-
-       /* LOGD("[%"G_GUINT64_FORMAT"] send data size:%d, %p", audio_stream.channel_mask, audio_stream.data_size, player->audio_decoded_cb_user_param); */
+#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();
@@ -2393,8 +2307,6 @@ __mmplayer_audio_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer,
        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;
@@ -2411,13 +2323,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));
 
@@ -2428,7 +2339,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;
@@ -2466,8 +2379,6 @@ __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);
@@ -2482,7 +2393,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. */
@@ -2546,8 +2459,6 @@ __mmplayer_gst_audio_deinterleave_pad_added(GstElement *elem, GstPad *pad, gpoin
                audiobin[MMPLAYER_A_SINK].gst = sink;
        }
 
-       gst_element_set_state(sink, GST_STATE_PAUSED);
-       gst_element_set_state(queue, GST_STATE_PAUSED);
 
        _mmplayer_add_signal_connection(player,
                G_OBJECT(sink),
@@ -2558,6 +2469,16 @@ __mmplayer_gst_audio_deinterleave_pad_added(GstElement *elem, GstPad *pad, gpoin
 
        __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;
 
@@ -2580,9 +2501,25 @@ ERROR:
 }
 
 void
+__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;
@@ -2597,37 +2534,48 @@ __mmplayer_gst_set_pulsesink_property(mmplayer_t *player)
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->audiobin);
 
+       audiobin = player->pipeline->audiobin;
+
+       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(player->attrs, "sound_stream_index", &stream_id);
        mm_attrs_get_string_by_name(player->attrs, "sound_stream_type", &stream_type);
 
-       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);
-       }
+       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);
 
@@ -2636,18 +2584,23 @@ __mmplayer_gst_set_pulsesink_property(mmplayer_t *player)
        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 &&
@@ -2664,6 +2617,7 @@ __mmplayer_gst_set_openalsink_property(mmplayer_t *player)
        }
 
        MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
 }
 
 static int
@@ -2729,13 +2683,15 @@ __mmplayer_gst_make_audio_playback_sink(mmplayer_t *player, GList **bucket)
        /* resampler */
        MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RESAMPLER,  player->ini.audioresampler_element, "audio resampler", *bucket, player);
 
-       /* for logical volume control */
-       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);
+       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);
 
-       if (player->sound.mute) {
-               LOGD("mute enabled");
-               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
+               if (player->sound.mute) {
+                       LOGD("mute enabled");
+                       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
+               }
        }
 
        mm_attrs_get_int_by_name(player->attrs, "content_audio_channels", &channels);
@@ -2799,10 +2755,12 @@ __mmplayer_gst_make_audio_playback_sink(mmplayer_t *player, GList **bucket)
                g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "provide-clock", FALSE,  NULL);
        }
 
-       if (g_strrstr(player->ini.audiosink_element, "pulsesink"))
+       if (g_strrstr(player->ini.audiosink_element, "pulsesink")) {
                __mmplayer_gst_set_pulsesink_property(player);
-       else if (g_strrstr(player->ini.audiosink_element, "openalsink"))
-               __mmplayer_gst_set_openalsink_property(player);
+       } else if (g_strrstr(player->ini.audiosink_element, "openalsink")) {
+               if (__mmplayer_gst_set_openalsink_property(player) != MM_ERROR_NONE)
+                       goto ERROR;
+       }
 
        /* qos on */
        g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL);       /* qos on */
@@ -2899,9 +2857,9 @@ __mmplayer_gst_make_audio_extract_sink(mmplayer_t *player, GList **bucket)
 
        /* 2. decide the extract pcm format */
        mm_attrs_multiple_get(player->attrs, NULL,
-                               "pcm_audioformat", &dst_format, &dst_len,
-                               "pcm_extraction_samplerate", &dst_samplerate,
-                               "pcm_extraction_channels", &dst_channels,
+                               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",
@@ -2951,6 +2909,9 @@ __mmplayer_gst_make_audio_extract_sink(mmplayer_t *player, GList **bucket)
                /* 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");
@@ -3176,27 +3137,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;
@@ -3252,16 +3213,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) {
@@ -3526,22 +3487,24 @@ __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);
@@ -3568,9 +3531,6 @@ __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");
@@ -3857,7 +3817,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();
@@ -4194,8 +4154,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);
@@ -4214,10 +4172,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))
+       if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
                ret = _mmplayer_gst_build_es_pipeline(player);
-       else
-               ret = _mmplayer_gst_build_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");
@@ -4240,6 +4202,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;
 }
@@ -4273,13 +4236,14 @@ __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);
@@ -4709,9 +4673,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);
@@ -4725,8 +4686,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;
@@ -4874,7 +4833,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]);
        }
 
@@ -4984,6 +4945,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");
@@ -4998,9 +4962,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);
@@ -5008,6 +4969,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);
 
@@ -5018,9 +4984,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;
@@ -5030,11 +4993,13 @@ 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;
-
+       int video_codec_type = 0;
+       int audio_codec_type = 0;
+       int default_codec_type = 0;
        MMPLAYER_FENTER();
 
        /* check player handle */
@@ -5086,7 +5051,6 @@ _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;
 
@@ -5099,8 +5063,9 @@ _mmplayer_realize(MMHandleType hplayer)
                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);
@@ -5117,6 +5082,23 @@ _mmplayer_realize(MMHandleType hplayer)
                                                                player->streamer->buffering_req.rebuffer_time);
        }
 
+       mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_AUDIO_CODEC_TYPE, &audio_codec_type);
+       if (!strcmp(player->ini.audiocodec_default_type, "hw"))
+               default_codec_type = MM_PLAYER_CODEC_TYPE_HW;
+       else
+               default_codec_type = MM_PLAYER_CODEC_TYPE_SW;
+
+       if (audio_codec_type != default_codec_type) {
+               LOGD("audio dec sorting is required");
+               player->need_audio_dec_sorting = TRUE;
+       }
+
+       mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_VIDEO_CODEC_TYPE, &video_codec_type);
+       if (video_codec_type != MM_PLAYER_CODEC_TYPE_DEFAULT) {
+               LOGD("video dec sorting is required");
+               player->need_video_dec_sorting = TRUE;
+       }
+
        /* realize pipeline */
        ret = __mmplayer_gst_realize(player);
        if (ret != MM_ERROR_NONE)
@@ -5140,6 +5122,7 @@ _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);
@@ -5155,9 +5138,14 @@ _mmplayer_unrealize(MMHandleType hplayer)
        ret = __mmplayer_gst_unrealize(player);
 
        if (!player->interrupted_by_resource) {
-               if ((__mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) ||
-                       (__mmplayer_release_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_OVERLAY) != MM_ERROR_NONE))
-                       LOGE("failed to release video resources");
+               int rm_ret = MM_ERROR_NONE;
+               mmplayer_resource_type_e res_idx = MMPLAYER_RESOURCE_TYPE_MAX;
+
+               for (res_idx = MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER; res_idx < MMPLAYER_RESOURCE_TYPE_MAX; res_idx++) {
+                       rm_ret = __mmplayer_release_hw_resource(player, res_idx);
+                       if (rm_ret != MM_ERROR_NONE)
+                               LOGE("failed to release [%d] resources", res_idx);
+               }
        }
 
        MMPLAYER_FLEAVE();
@@ -5207,10 +5195,8 @@ __mmplayer_gst_set_volume_property(mmplayer_t *player, const char *prop_name)
                return MM_ERROR_NONE;
        }
 
-       if (player->build_audio_offload) {
-               LOGD("offload pipeline");
+       if (player->build_audio_offload || g_strrstr(player->ini.audiosink_element, "pulsesink"))
                volume_elem_id = MMPLAYER_A_SINK;
-       }
 
        vol_element = player->pipeline->audiobin[volume_elem_id].gst;
        if (!vol_element) {
@@ -5319,24 +5305,6 @@ _mmplayer_get_mute(MMHandleType hplayer, bool *mute)
 }
 
 int
-_mmplayer_set_videostream_changed_cb(MMHandleType hplayer, mm_player_stream_changed_callback callback, void *user_param)
-{
-       mmplayer_t *player = (mmplayer_t *)hplayer;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       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);
-
-       MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
-}
-
-int
 _mmplayer_set_audiostream_changed_cb(MMHandleType hplayer, mm_player_stream_changed_callback callback, void *user_param)
 {
        mmplayer_t *player = (mmplayer_t *)hplayer;
@@ -5507,28 +5475,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)
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline);
+
+       MMPLAYER_RECONFIGURE_LOCK(player);
+       if (!player->gapless.reconfigure) {
+               MMPLAYER_RECONFIGURE_UNLOCK(player);
                return;
+       }
 
-       LOGW("pipeline is under construction.");
+       LOGI("reconfigure is under process");
+       MMPLAYER_RECONFIGURE_WAIT(player);
+       MMPLAYER_RECONFIGURE_UNLOCK(player);
+       LOGI("reconfigure is completed.");
 
-       MMPLAYER_PLAYBACK_LOCK(player);
-       MMPLAYER_PLAYBACK_UNLOCK(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);
 
-       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
-
-       /* 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*/
@@ -5545,9 +5517,11 @@ _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);
@@ -5581,8 +5555,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:
@@ -5636,7 +5610,7 @@ _mmplayer_pause(MMHandleType hplayer)
                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");
        }
 
@@ -5789,8 +5763,8 @@ _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);
 
@@ -5871,8 +5845,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;
@@ -5885,10 +5859,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);
 }
@@ -5941,7 +5916,6 @@ _mmplayer_typefind_have_type(GstElement *tf, guint probability,
        GstCaps *caps, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
-       GstPad *pad = NULL;
 
        MMPLAYER_FENTER();
 
@@ -5973,27 +5947,27 @@ _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;
 }
 
@@ -6018,20 +5992,24 @@ _mmplayer_gst_make_decodebin(mmplayer_t *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);
+                                               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);
+                                               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);
+                                               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);
+                                               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.*/
@@ -6040,7 +6018,7 @@ _mmplayer_gst_make_decodebin(mmplayer_t *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);
+                                               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",
@@ -6308,8 +6286,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;
 
@@ -6320,7 +6298,7 @@ __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data)
        /* remove fakesink. */
        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.
@@ -6330,8 +6308,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);
 
@@ -6396,16 +6373,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;
        }
 
@@ -6431,6 +6407,11 @@ __mmplayer_verify_gapless_play_path(mmplayer_t *player)
 
        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;
@@ -6442,7 +6423,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();
@@ -6451,12 +6435,6 @@ __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_INFINITE && count < REPEAT_COUNT_MIN))) {
@@ -6474,11 +6452,7 @@ __mmplayer_verify_gapless_play_path(mmplayer_t *player)
                        /* 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");
-
+                       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;
@@ -6501,7 +6475,7 @@ ERROR:
 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;
@@ -6572,11 +6546,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);
@@ -6610,9 +6585,7 @@ __mmplayer_deactivate_old_path(mmplayer_t *player)
                player->streamer = NULL;
        }
 
-       MMPLAYER_PLAYBACK_LOCK(player);
        MMPLAYER_GAPLESS_PLAY_THREAD_SIGNAL(player);
-
        MMPLAYER_FLEAVE();
        return;
 
@@ -6639,10 +6612,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)
@@ -6741,8 +6715,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;
@@ -6763,9 +6737,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;
@@ -6792,15 +6766,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;
@@ -6814,7 +6783,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;
@@ -6824,9 +6793,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;
        }
 
@@ -6842,9 +6810,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;
        }
 
@@ -6852,10 +6819,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++) {
@@ -6867,11 +6832,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;
 }
@@ -6896,9 +6861,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);
 
@@ -6963,6 +6926,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)
 {
@@ -6973,7 +6967,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, "")) {
@@ -6993,6 +6987,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;
 
@@ -7003,6 +7003,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;
 }
@@ -7011,8 +7014,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"))) {
@@ -7030,31 +7031,13 @@ __mmplayer_check_codec_info(mmplayer_t *player, const char *klass, GstCaps *caps
                        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;
-                       }
-               }
+               /* 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;
@@ -7063,27 +7046,6 @@ __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))) {
 
@@ -7094,7 +7056,7 @@ __mmplayer_check_codec_info(mmplayer_t *player, const char *klass, GstCaps *caps
                                goto DONE;
                        }
 
-                       if (__mmplayer_acquire_hw_resource(player, MMPLAYER_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
+                       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;
@@ -7112,6 +7074,130 @@ 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,
        GstCaps *caps, GstElementFactory *factory, gpointer data)
@@ -7242,8 +7328,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;
@@ -7266,8 +7352,8 @@ __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_decode_drained(GstElement *bin, gpointer data)
 {
        mmplayer_t *player = (mmplayer_t *)data;
        GstIterator *iter = NULL;
@@ -7279,22 +7365,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);
@@ -7324,7 +7409,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;
        }
@@ -7335,7 +7419,6 @@ __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();
 }
@@ -7359,6 +7442,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")) {
@@ -7374,7 +7467,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;
        }
@@ -7431,20 +7526,6 @@ __mmplayer_release_misc(mmplayer_t *player)
 
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       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->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;
 
@@ -7484,17 +7565,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);
 
@@ -7536,41 +7606,40 @@ __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 */
@@ -7746,22 +7815,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;
        }
 
@@ -7776,7 +7843,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..");
@@ -7791,13 +7857,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;
@@ -7980,16 +8041,16 @@ __mmplayer_change_external_subtitle_language(mmplayer_t *player, const char *fil
                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;
                }
        }
@@ -8066,9 +8127,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 {
@@ -8077,13 +8138,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;
                        }
@@ -8110,6 +8171,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;
@@ -8145,7 +8244,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");
@@ -8185,7 +8284,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);
@@ -8202,7 +8304,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();
@@ -8213,13 +8314,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)
@@ -8237,23 +8338,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;
+                       }
                }
        }
 
@@ -8334,9 +8442,9 @@ __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);
@@ -8391,7 +8499,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;
        }
@@ -8419,25 +8529,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)
 {
@@ -8616,12 +8707,11 @@ _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;
 
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
@@ -8634,7 +8724,10 @@ _mmplayer_set_codec_type(MMHandleType hplayer, mmplayer_stream_type_e stream_typ
        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 */
+          audio codec element sw = avdec
+          and in case of audio hw codec is supported and selected,
+          audio filter elements should be applied depending on the hw capabilities.
+        */
                if (((codec_type == MM_PLAYER_CODEC_TYPE_HW) &&
                         (!strcmp(player->ini.audiocodec_element_hw, ""))) ||
                        ((codec_type == MM_PLAYER_CODEC_TYPE_SW) &&
@@ -8662,14 +8755,7 @@ _mmplayer_set_codec_type(MMHandleType hplayer, mmplayer_stream_type_e stream_typ
        }
 
        LOGD("update %s codec_type to %d", attr_name, codec_type);
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       mm_attrs_set_int_by_name(attrs, attr_name, codec_type);
-
-       if (mm_attrs_commit_all(player->attrs)) {
-               LOGE("failed to commit codec_type attributes");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
+       mm_player_set_attribute(hplayer, NULL, attr_name, codec_type, NULL);
 
        MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
@@ -8749,7 +8835,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();
@@ -8759,7 +8845,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;
@@ -8771,7 +8857,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(
@@ -8809,6 +8895,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)
 {
@@ -8883,10 +9056,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);
 
@@ -8931,10 +9105,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);
 
@@ -8944,7 +9118,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);
        }
 
@@ -8981,9 +9156,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");
@@ -8992,7 +9168,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;
                }
        }
@@ -9102,11 +9279,12 @@ __mmplayer_set_file_uri(mmplayer_parse_profile_t *data, const char *uri)
 
        /* 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 (_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) {
@@ -9139,7 +9317,9 @@ __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);
@@ -9378,10 +9558,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");
        }