[0.6.185] send pcm_format info to client
[platform/core/multimedia/libmm-player.git] / src / mm_player_priv.c
old mode 100755 (executable)
new mode 100644 (file)
index e164e2f..df00ea4
@@ -27,7 +27,6 @@
 ========================================================================================== */
 #include <glib.h>
 #include <gst/gst.h>
-#include <gst/app/gstappsrc.h>
 #include <gst/video/videooverlay.h>
 #include <gst/audio/gstaudiobasesink.h>
 #include <unistd.h>
 #include <sys/time.h>
 #include <stdlib.h>
 #include <dlog.h>
+#include <gio/gio.h>
 
 #include <mm_error.h>
 #include <mm_attrs.h>
-#include <mm_attrs_private.h>
+#include <mm_sound.h>
 
 #include "mm_player_priv.h"
 #include "mm_player_ini.h"
 #include "mm_player_utils.h"
 #include "mm_player_tracks.h"
 #include "mm_player_360.h"
+#include "mm_player_gst.h"
 
 #include <system_info.h>
 #include <sound_manager.h>
+#include <gst/allocators/gsttizenmemory.h>
+#include <tbm_surface_internal.h>
 
 /*===========================================================================================
 |                                                                                                                                                                                      |
 #define DEFAULT_PLAYBACK_RATE                  1.0
 #define DEFAULT_NUM_OF_V_OUT_BUFFER            3
 
-#define MMPLAYER_USE_FILE_FOR_BUFFERING(player) \
-       (((player)->profile.uri_type != MM_PLAYER_URI_TYPE_HLS) && \
-       (player->ini.http_use_file_buffer) && \
-       (player->http_file_buffering_path) && \
-       (strlen(player->http_file_buffering_path) > 0))
-
 #define PLAYER_DISPLAY_MODE_DST_ROI            5
 
 #define ADAPTIVE_VARIANT_DEFAULT_VALUE -1 /* auto */
 
-/* For PD mode */
-#define PLAYER_PD_EXT_MAX_SIZE_BYTE            1024 * 1024 * 3
-
-#define PLAYER_BUS_MSG_DEFAULT_TIMEOUT 500 /* bus msg wait timeout */
-#define PLAYER_BUS_MSG_PREPARE_TIMEOUT 10
-
 #define PLAYER_SPHERICAL_DEFAULT_YAW   0  /* sync from video360 plugin */
 #define PLAYER_SPHERICAL_DEFAULT_PITCH 0
 #define PLAYER_SPHERICAL_DEFAULT_H_FOV 120
 #define SPATIAL_AUDIO_CAPS             "audio/x-raw,format=S16LE,channels=4"
 #define FEATURE_NAME_SPHERICAL_VIDEO   "http://tizen.org/feature/multimedia.player.spherical_video"
 
+#define FAKE_SINK_MAX_LATENESS         G_GINT64_CONSTANT(20000000) /* set 20ms as waylandsink */
+
+#define DEFAULT_PCM_OUT_FORMAT         "F32LE"
+#define DEFAULT_PCM_OUT_SAMPLERATE     44100
+#define DEFAULT_PCM_OUT_CHANNEL        2
+
 /*---------------------------------------------------------------------------
 |    LOCAL CONSTANT DEFINITIONS:                                                                                       |
 ---------------------------------------------------------------------------*/
 /*---------------------------------------------------------------------------
 |    LOCAL DATA TYPE DEFINITIONS:                                                                                      |
 ---------------------------------------------------------------------------*/
+/* NOTE : GstAutoplugSelectResult is defined in gstplay-enum.h but not exposed
+ We are defining our own and will be removed when it actually exposed */
+typedef enum {
+       GST_AUTOPLUG_SELECT_TRY,
+       GST_AUTOPLUG_SELECT_EXPOSE,
+       GST_AUTOPLUG_SELECT_SKIP
+} GstAutoplugSelectResult;
 
 /*---------------------------------------------------------------------------
 |    GLOBAL VARIABLE DEFINITIONS:                                                                                      |
@@ -132,126 +136,77 @@ static sound_stream_info_h stream_info;
 /*---------------------------------------------------------------------------
 |    LOCAL FUNCTION PROTOTYPES:                                                                                                |
 ---------------------------------------------------------------------------*/
-static int             __mmplayer_gst_create_pipeline(mm_player_t* player);
-static int             __mmplayer_gst_destroy_pipeline(mm_player_t* player);
-static int             __mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps *caps, MMDisplaySurfaceType surface_type);
-static int             __mmplayer_gst_create_audio_pipeline(mm_player_t* player);
-static int             __mmplayer_gst_create_text_pipeline(mm_player_t* player);
-static int             __mmplayer_gst_create_text_sink_bin(mm_player_t* player);
-static int             __mmplayer_gst_element_link_bucket(GList* element_bucket);
-
-static GstPadProbeReturn       __mmplayer_gst_selector_blocked(GstPad* pad, GstPadProbeInfo *info, gpointer data);
-static void            __mmplayer_gst_decode_pad_added(GstElement* elem, GstPad* pad, gpointer data);
-static void            __mmplayer_gst_decode_no_more_pads(GstElement* elem, gpointer data);
-static void            __mmplayer_gst_decode_callback(GstElement *decodebin, GstPad *pad, gpointer data);
-static void            __mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPad* pad, GstCaps *caps, gpointer data);
-static gboolean __mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPad* pad, GstCaps * caps,  gpointer data);
-static gint            __mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPad* pad, GstCaps * caps, GstElementFactory* factory, gpointer data);
-static void __mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPad* new_pad, gpointer data);
+static int             __mmplayer_gst_create_pipeline(mmplayer_t *player);
+static int             __mmplayer_gst_destroy_pipeline(mmplayer_t *player);
+static int             __mmplayer_gst_create_text_pipeline(mmplayer_t *player);
+static int             __mmplayer_gst_create_video_sink_bin(mmplayer_t *player, GstCaps *caps, MMDisplaySurfaceType surface_type);
+static int             __mmplayer_gst_create_audio_sink_bin(mmplayer_t *player);
+static int             __mmplayer_gst_create_text_sink_bin(mmplayer_t *player);
+
+static GstPadProbeReturn       __mmplayer_gst_selector_blocked(GstPad *pad, GstPadProbeInfo *info, gpointer data);
+static void            __mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data);
+static void            __mmplayer_gst_create_sinkbin(GstElement *decodebin, GstPad *pad, gpointer data);
+static void            __mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPad *pad, GstCaps *caps, gpointer data);
+static gboolean __mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPad *pad, GstCaps *caps,  gpointer data);
+static void __mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPad *new_pad, gpointer data);
 static void __mmplayer_gst_decode_drained(GstElement *bin, gpointer data);
-static void    __mmplayer_gst_element_added(GstElement* bin, GstElement* element, gpointer data);
-static GstElement * __mmplayer_create_decodebin(mm_player_t* player);
-static gboolean __mmplayer_try_to_plug_decodebin(mm_player_t* player, GstPad *srcpad, const GstCaps *caps);
-static void    __mmplayer_typefind_have_type(GstElement *tf, guint probability, GstCaps *caps, gpointer data);
 static void    __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data);
-static gboolean __mmplayer_is_midi_type(gcharstr_caps);
+static gboolean __mmplayer_is_midi_type(gchar *str_caps);
 static gboolean __mmplayer_is_only_mp3_type(gchar *str_caps);
-static void    __mmplayer_set_audio_attrs(mm_player_t* player, GstCaps* caps);
-
-static void            __mmplayer_gst_rtp_no_more_pads(GstElement *element,  gpointer data);
-static void            __mmplayer_gst_rtp_dynamic_pad(GstElement *element, GstPad *pad, gpointer data);
-static MMStreamingType __mmplayer_get_stream_service_type(mm_player_t* player);
-static gboolean        __mmplayer_update_subtitle(GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data);
-static void            __mmplayer_release_misc(mm_player_t* player);
-static void            __mmplayer_release_misc_post(mm_player_t* player);
-static gboolean        __mmplayer_init_gstreamer(mm_player_t* player);
-static GstBusSyncReply __mmplayer_bus_sync_callback(GstBus * bus, GstMessage * message, gpointer data);
-static void __mmplayer_gst_callback(GstMessage *msg, gpointer data);
-static gboolean        __mmplayer_gst_extract_tag_from_msg(mm_player_t* player, GstMessage *msg);
-static gboolean      __mmplayer_gst_handle_duration(mm_player_t* player, GstMessage* msg);
-static gboolean __mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink);
-static GstPadProbeReturn __mmplayer_audio_stream_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
-static void __mmplayer_video_stream_decoded_preroll_cb(GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data);
-static void __mmplayer_video_stream_decoded_render_cb(GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data);
+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);
+static void            __mmplayer_release_misc_post(mmplayer_t *player);
+static gboolean        __mmplayer_init_gstreamer(mmplayer_t *player);
+static void __mmplayer_video_stream_decoded_preroll_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data);
+static void __mmplayer_video_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data);
 static GstPadProbeReturn __mmplayer_subtitle_adjust_position_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);
-static int __mmplayer_change_selector_pad(mm_player_t* player, MMPlayerTrackType type, int index);
-
-static gboolean __mmplayer_check_subtitle(mm_player_t* player);
-static gboolean __mmplayer_handle_streaming_error(mm_player_t* player, GstMessage * message);
-static void            __mmplayer_handle_eos_delay(mm_player_t* player, int delay_in_ms);
-static void            __mmplayer_cancel_eos_timer(mm_player_t* player);
-static gboolean        __mmplayer_eos_timer_cb(gpointer u_data);
-static int             __mmplayer_handle_missed_plugin(mm_player_t* player);
-static int             __mmplayer_check_not_supported_codec(mm_player_t* player, const gchar* factory_class, const gchar* mime);
-static gboolean __mmplayer_configure_audio_callback(mm_player_t* player);
-static void            __mmplayer_add_sink(mm_player_t* player, GstElement* sink);
-static void            __mmplayer_del_sink(mm_player_t* player, GstElement* sink);
-static void            __mmplayer_release_signal_connection(mm_player_t* player, MMPlayerSignalType type);
-static gpointer __mmplayer_next_play_thread(gpointer data);
-static gboolean _mmplayer_update_content_attrs(mm_player_t* player, enum content_attr_flag flag);
-
-static gboolean __mmplayer_add_dump_buffer_probe(mm_player_t *player, GstElement *element);
+static int __mmplayer_change_selector_pad(mmplayer_t *player, mmplayer_track_type_e type, int index);
+
+static gboolean __mmplayer_check_subtitle(mmplayer_t *player);
+static int             __mmplayer_handle_missed_plugin(mmplayer_t *player);
+static int             __mmplayer_check_not_supported_codec(mmplayer_t *player, const gchar *factory_class, const gchar *mime);
+static void            __mmplayer_add_sink(mmplayer_t *player, GstElement *sink);
+static void            __mmplayer_del_sink(mmplayer_t *player, GstElement *sink);
+static void            __mmplayer_release_signal_connection(mmplayer_t *player, mmplayer_signal_type_e type);
+static gpointer __mmplayer_gapless_play_thread(gpointer data);
+static gboolean __mmplayer_add_dump_buffer_probe(mmplayer_t *player, GstElement *element);
 static GstPadProbeReturn __mmplayer_dump_buffer_probe_cb(GstPad *pad,  GstPadProbeInfo *info, gpointer u_data);
 static void __mmplayer_release_dump_list(GList *dump_list);
-
-static int             __gst_realize(mm_player_t* player);
-static int             __gst_unrealize(mm_player_t* player);
-static int             __gst_start(mm_player_t* player);
-static int             __gst_stop(mm_player_t* player);
-static int             __gst_pause(mm_player_t* player, gboolean async);
-static int             __gst_resume(mm_player_t* player, gboolean async);
-static gboolean        __gst_seek(mm_player_t* player, GstElement * element, gdouble rate,
-                                       GstFormat format, GstSeekFlags flags, GstSeekType cur_type,
-                                       gint64 cur, GstSeekType stop_type, gint64 stop);
-static int __gst_pending_seek(mm_player_t* player);
-
-static int             __gst_set_position(mm_player_t* player, int format, unsigned long position, gboolean internal_called);
-static int             __gst_get_position(mm_player_t* player, int format, unsigned long *position);
-static int             __gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos);
-static int             __gst_adjust_subtitle_position(mm_player_t* player, int format, int position);
-static int             __gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param);
-
-static gboolean __gst_send_event_to_sink(mm_player_t* player, GstEvent* event);
-
-static int __mmplayer_set_pcm_extraction(mm_player_t* player);
-static gboolean __mmplayer_can_extract_pcm(mm_player_t* player);
+static int             __mmplayer_gst_realize(mmplayer_t *player);
+static int             __mmplayer_gst_unrealize(mmplayer_t *player);
+static int             __mmplayer_gst_adjust_subtitle_position(mmplayer_t *player, int position);
+static int             __mmplayer_gst_set_message_callback(mmplayer_t *player, MMMessageCallback callback, gpointer user_param);
 
 /* util */
-static gboolean __is_ms_buff_src(mm_player_t* player);
-static gboolean __has_suffix(mm_player_t * player, const gchar * suffix);
-
-static int __mmplayer_realize_streaming_ext(mm_player_t* player);
-static int __mmplayer_unrealize_streaming_ext(mm_player_t *player);
-static int __mmplayer_start_streaming_ext(mm_player_t *player);
-static int __mmplayer_destroy_streaming_ext(mm_player_t* player);
-static int __mmplayer_do_change_videosink(mm_player_t* player, const int dec_index, const char *videosink_element, MMDisplaySurfaceType surface_type, void *display_overlay);
-
-static gboolean __mmplayer_verify_next_play_path(mm_player_t *player);
-static void __mmplayer_activate_next_source(mm_player_t *player, GstState target);
-static void __mmplayer_check_pipeline(mm_player_t* player);
-static gboolean __mmplayer_deactivate_selector(mm_player_t *player, MMPlayerTrackType type);
-static void __mmplayer_deactivate_old_path(mm_player_t *player);
-
-static void __mmplayer_update_buffer_setting(mm_player_t *player, GstMessage *buffering_msg);
-static GstElement *__mmplayer_element_create_and_link(mm_player_t *player, GstPad* pad, const char* name);
-
-static int __mmplayer_gst_create_plain_text_elements(mm_player_t* player);
-static guint32 _mmplayer_convert_fourcc_string_to_value(const gchar* format_name);
-static void            __gst_appsrc_feed_audio_data(GstElement *element, guint size, gpointer user_data);
-static void            __gst_appsrc_feed_video_data(GstElement *element, guint size, gpointer user_data);
-static void     __gst_appsrc_feed_subtitle_data(GstElement *element, guint size, gpointer user_data);
-static void            __gst_appsrc_enough_audio_data(GstElement *element, gpointer user_data);
-static void            __gst_appsrc_enough_video_data(GstElement *element, gpointer user_data);
-static gboolean        __gst_seek_audio_data(GstElement * appsrc, guint64 position, gpointer user_data);
-static gboolean        __gst_seek_video_data(GstElement * appsrc, guint64 position, gpointer user_data);
-static gboolean        __gst_seek_subtitle_data(GstElement * appsrc, guint64 position, gpointer user_data);
-static void            __mmplayer_gst_caps_notify_cb(GstPad * pad, GParamSpec * unused, gpointer data);
-static void            __mmplayer_audio_stream_clear_buffer(mm_player_t* player, gboolean send_all);
-static void            __mmplayer_audio_stream_send_data(mm_player_t* player, mm_player_audio_stream_buff_t *a_buffer);
-static void            __mmplayer_initialize_storage_info(mm_player_t* player, MMPlayerPathType path_type);
-static void            __mmplayer_get_metadata_360_from_tags(GstTagList *tags, mm_player_spherical_metadata_t *metadata);
+static gboolean __mmplayer_verify_gapless_play_path(mmplayer_t *player);
+static void __mmplayer_activate_next_source(mmplayer_t *player, GstState target);
+static void __mmplayer_check_pipeline(mmplayer_t *player);
+static 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);
+static guint32 _mmplayer_convert_fourcc_string_to_value(const gchar *format_name);
+static void            __mmplayer_gst_caps_notify_cb(GstPad *pad, GParamSpec *unused, gpointer data);
+static void            __mmplayer_audio_stream_send_data(mmplayer_t *player, mmplayer_audio_stream_buff_t *a_buffer);
+static void            __mmplayer_initialize_storage_info(mmplayer_t *player, mmplayer_path_type_e path_type);
 static int             __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res, void *user_data);
-
+static gboolean __mmplayer_update_duration_value(mmplayer_t *player);
+static gboolean __mmplayer_update_audio_attrs(mmplayer_t *player, MMHandleType attrs);
+static gboolean __mmplayer_update_video_attrs(mmplayer_t *player, MMHandleType attrs);
+static gboolean __mmplayer_update_bitrate_attrs(mmplayer_t *player, MMHandleType attrs);
+
+static void __mmplayer_copy_uri_and_set_type(mmplayer_parse_profile_t *data, const char *uri, int uri_type);
+static int __mmplayer_set_mem_uri(mmplayer_parse_profile_t *data, char *path, void *param);
+static int __mmplayer_set_file_uri(mmplayer_parse_profile_t *data, const char *uri);
+
+static mmplayer_video_decoded_data_info_t *__mmplayer_create_stream_from_pad(GstPad *pad);
+static void __mmplayer_zerocopy_set_stride_elevation_bo(mmplayer_video_decoded_data_info_t *stream, GstMemory *mem);
+static gboolean __mmplayer_swcodec_set_stride_elevation(mmplayer_video_decoded_data_info_t *stream);
+static gboolean __mmplayer_swcodec_set_bo(mmplayer_t *player, mmplayer_video_decoded_data_info_t *stream, GstMemory *mem);
+
+static void __mmplayer_set_pause_state(mmplayer_t *player);
+static void __mmplayer_set_playing_state(mmplayer_t *player);
 /*===========================================================================================
 |                                                                                                                                                                                      |
 |  FUNCTION DEFINITIONS                                                                                                                                                |
@@ -260,7 +215,7 @@ static int          __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_
 
 #if 0 //debug
 static void
-print_tag(const GstTagList * list, const gchar * tag, gpointer unused)
+print_tag(const GstTagList *list, const gchar *tag, gpointer unused)
 {
        gint i, count;
 
@@ -274,13 +229,14 @@ print_tag(const GstTagList * list, const gchar * tag, gpointer unused)
                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
+               } else {
                        str = g_strdup_value_contents(gst_tag_list_get_value_index(list, tag, i));
+               }
 
                if (i == 0)
-                       g_print("  %15s: %s\n", gst_tag_get_nick(tag), str);
+                       g_print("  %15s: %s", gst_tag_get_nick(tag), str);
                else
-                       g_print("                 : %s\n", str);
+                       g_print("                 : %s", str);
 
                g_free(str);
        }
@@ -290,7 +246,7 @@ print_tag(const GstTagList * list, const gchar * tag, gpointer unused)
 /* This function should be called after the pipeline goes PAUSED or higher
 state. */
 gboolean
-_mmplayer_update_content_attrs(mm_player_t* player, enum content_attr_flag flag)
+__mmplayer_update_content_attrs(mmplayer_t *player, enum content_attr_flag flag)
 {
        static gboolean has_duration = FALSE;
        static gboolean has_video_attrs = FALSE;
@@ -298,11 +254,7 @@ _mmplayer_update_content_attrs(mm_player_t* player, enum content_attr_flag flag)
        static gboolean has_bitrate = FALSE;
        gboolean missing_only = FALSE;
        gboolean all = FALSE;
-       gint64 dur_nsec = 0;
-       GstStructure* p = NULL;
        MMHandleType attrs = 0;
-       gchar *path = NULL;
-       struct stat sb;
 
        MMPLAYER_FENTER();
 
@@ -344,178 +296,21 @@ _mmplayer_update_content_attrs(mm_player_t* player, enum content_attr_flag flag)
                missing_only = FALSE;
        }
 
-       if ((flag & ATTR_DURATION) ||   (!has_duration && missing_only) || all) {
-               LOGD("try to update duration");
-               has_duration = FALSE;
-
-               if (gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &dur_nsec)) {
-                       player->duration = dur_nsec;
-                       LOGW("duration : %lld msec", GST_TIME_AS_MSECONDS(dur_nsec));
-               }
-
-               if (player->duration < 0) {
-                       LOGW("duration : %lld is Non-Initialized !!! \n", player->duration);
-                       player->duration = 0;
-               }
-
-               /* update streaming service type */
-               player->streaming_type =  __mmplayer_get_stream_service_type(player);
-
-               /* check duration is OK */
-               if (dur_nsec == 0 && !MMPLAYER_IS_LIVE_STREAMING(player)) {
-                       /* FIXIT : find another way to get duration here. */
-                       LOGE("finally it's failed to get duration from pipeline. progressbar will not work correctely!");
-               } else {
-                       /*update duration */
-                       mm_attrs_set_int_by_name(attrs, "content_duration", GST_TIME_AS_MSECONDS(dur_nsec));
-                       has_duration = TRUE;
-               }
-       }
-
-       if ((flag & ATTR_AUDIO) || (!has_audio_attrs && missing_only) || all) {
-               /* update audio params
-               NOTE : We need original audio params and it can be only obtained from src pad of audio
-               decoder. Below code only valid when we are not using 'resampler' just before
-               'audioconverter'. */
-
-               LOGD("try to update audio attrs");
-               has_audio_attrs = FALSE;
-
-               if (player->pipeline->audiobin &&
-                        player->pipeline->audiobin[MMPLAYER_A_SINK].gst) {
-                       GstCaps *caps_a = NULL;
-                       GstPad* pad = NULL;
-                       gint samplerate = 0, channels = 0;
-
-                       pad = gst_element_get_static_pad(
-                                       player->pipeline->audiobin[MMPLAYER_A_CONV].gst, "sink");
-
-                       if (pad) {
-                               caps_a = gst_pad_get_current_caps(pad);
-
-                               if (caps_a) {
-                                       p = gst_caps_get_structure(caps_a, 0);
-
-                                       mm_attrs_get_int_by_name(attrs, "content_audio_samplerate", &samplerate);
-
-                                       gst_structure_get_int(p, "rate", &samplerate);
-                                       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);
-
-                                       SECURE_LOGD("samplerate : %d    channels : %d", samplerate, channels);
-
-                                       gst_caps_unref(caps_a);
-                                       caps_a = NULL;
-
-                                       has_audio_attrs = TRUE;
-                               } else
-                                       LOGW("not ready to get audio caps");
-
-                               gst_object_unref(pad);
-                       } else
-                               LOGW("failed to get pad from audiosink");
-               }
-       }
-
-       if ((flag & ATTR_VIDEO) || (!has_video_attrs && missing_only) || all) {
-               LOGD("try to update video attrs");
-               has_video_attrs = FALSE;
-
-               if (player->pipeline->videobin &&
-                        player->pipeline->videobin[MMPLAYER_V_SINK].gst) {
-                       GstCaps *caps_v = NULL;
-                       GstPad* pad = NULL;
-                       gint tmpNu, tmpDe;
-                       gint width, height;
-
-                       pad = gst_element_get_static_pad(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "sink");
-                       if (pad) {
-                               caps_v = gst_pad_get_current_caps(pad);
-
-                               /* Use v_stream_caps, if fail to get video_sink sink pad*/
-                               if (!caps_v && player->v_stream_caps) {
-                                       caps_v = player->v_stream_caps;
-                                       gst_caps_ref(caps_v);
-                               }
-
-                               if (caps_v) {
-                                       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);
-
-                                       gst_structure_get_fraction(p, "framerate", &tmpNu, &tmpDe);
-
-                                       SECURE_LOGD("width : %d     height : %d", width, height);
-
-                                       gst_caps_unref(caps_v);
-                                       caps_v = NULL;
-
-                                       if (tmpDe > 0) {
-                                               mm_attrs_set_int_by_name(attrs, "content_video_fps", tmpNu / tmpDe);
-                                               SECURE_LOGD("fps : %d", tmpNu / tmpDe);
-                                       }
-
-                                       has_video_attrs = TRUE;
-                               } else
-                                       LOGD("no negitiated caps from videosink");
-                               gst_object_unref(pad);
-                               pad = NULL;
-                       } else
-                               LOGD("no videosink sink pad");
-               }
-       }
-
-
-       if ((flag & ATTR_BITRATE) || (!has_bitrate && missing_only) || all) {
-               has_bitrate = FALSE;
-
-               /* FIXIT : please make it clear the dependancy with duration/codec/uritype */
-               if (player->duration) {
-                       guint64 data_size = 0;
-
-                       if (!MMPLAYER_IS_STREAMING(player) && (player->can_support_codec & FOUND_PLUGIN_VIDEO)) {
-                               mm_attrs_get_string_by_name(attrs, "profile_uri", &path);
-
-                               if (stat(path, &sb) == 0)
-                                       data_size = (guint64)sb.st_size;
-                       } else if (MMPLAYER_IS_HTTP_STREAMING(player)) {
-                               data_size = player->http_content_size;
-                       }
-                       LOGD("try to update bitrate : data_size = %lld", data_size);
-
-                       if (data_size) {
-                               guint64 bitrate = 0;
-                               guint64 msec_dur = 0;
+       if ((flag & ATTR_DURATION) || (!has_duration && missing_only) || all)
+               has_duration = __mmplayer_update_duration_value(player);
 
-                               msec_dur = GST_TIME_AS_MSECONDS(player->duration);
-                               if (msec_dur > 0) {
-                                       bitrate = data_size * 8 * 1000 / msec_dur;
-                                       SECURE_LOGD("file size : %u, video bitrate = %llu", data_size, bitrate);
-                                       mm_attrs_set_int_by_name(attrs, "content_video_bitrate", bitrate);
+       if ((flag & ATTR_AUDIO) || (!has_audio_attrs && missing_only) || all)
+               has_audio_attrs = __mmplayer_update_audio_attrs(player, attrs);
 
-                                       has_bitrate = TRUE;
-                               } else {
-                                       LOGD("player duration is less than 0");
-                               }
-                       }
+       if ((flag & ATTR_VIDEO) || (!has_video_attrs && missing_only) || all)
+               has_video_attrs = __mmplayer_update_video_attrs(player, attrs);
 
-                       if (MMPLAYER_IS_RTSP_STREAMING(player)) {
-                               if (player->total_bitrate) {
-                                       mm_attrs_set_int_by_name(attrs, "content_video_bitrate", player->total_bitrate);
-                                       has_bitrate = TRUE;
-                               }
-                       }
-               }
-       }
+       if ((flag & ATTR_BITRATE) || (!has_bitrate && missing_only) || all)
+               has_bitrate = __mmplayer_update_bitrate_attrs(player, attrs);
 
        /* validate all */
-       if (mmf_attrs_commit(attrs)) {
-               LOGE("failed to update attributes\n");
+       if (mm_attrs_commit_all(attrs)) {
+               LOGE("failed to update attributes");
                return FALSE;
        }
 
@@ -524,7 +319,8 @@ _mmplayer_update_content_attrs(mm_player_t* player, enum content_attr_flag flag)
        return TRUE;
 }
 
-static MMStreamingType __mmplayer_get_stream_service_type(mm_player_t* player)
+MMStreamingType
+__mmplayer_get_stream_service_type(mmplayer_t *player)
 {
        MMStreamingType streaming_type = STREAMING_SERVICE_NONE;
 
@@ -540,9 +336,8 @@ static MMStreamingType __mmplayer_get_stream_service_type(mm_player_t* player)
        if (!MMPLAYER_IS_STREAMING(player))
                return STREAMING_SERVICE_NONE;
 
-       if (MMPLAYER_IS_HTTP_STREAMING(player))
-               streaming_type = (player->duration == 0) ?
-                       STREAMING_SERVICE_LIVE : STREAMING_SERVICE_VOD;
+       streaming_type = (player->duration == 0) ?
+               STREAMING_SERVICE_LIVE : STREAMING_SERVICE_VOD;
 
        switch (streaming_type) {
        case STREAMING_SERVICE_LIVE:
@@ -561,22 +356,20 @@ static MMStreamingType __mmplayer_get_stream_service_type(mm_player_t* player)
        return streaming_type;
 }
 
-
 /* this function sets the player state and also report
  * it to applicaton by calling callback function
  */
-int
-__mmplayer_set_state(mm_player_t* player, int state)
+void
+__mmplayer_set_state(mmplayer_t *player, int state)
 {
        MMMessageParamType msg = {0, };
-       gboolean post_bos = FALSE;
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+       MMPLAYER_RETURN_IF_FAIL(player);
 
        if (MMPLAYER_CURRENT_STATE(player) == state) {
-               LOGW("already same state(%s)\n", MMPLAYER_STATE_GET_NAME(state));
+               LOGW("already same state(%s)", MMPLAYER_STATE_GET_NAME(state));
                MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NONE;
-               return MM_ERROR_NONE;
+               return;
        }
 
        /* update player states */
@@ -593,83 +386,15 @@ __mmplayer_set_state(mm_player_t* player, int state)
        case MM_PLAYER_STATE_NULL:
        case MM_PLAYER_STATE_READY:
                break;
-
        case MM_PLAYER_STATE_PAUSED:
-               {
-                       if (!player->sent_bos) {
-                               /* rtsp case, get content attrs by GstMessage */
-                               if (!MMPLAYER_IS_RTSP_STREAMING(player)) {
-                                       /* it's first time to update all content attrs. */
-                                       _mmplayer_update_content_attrs(player, ATTR_ALL);
-                               }
-                       }
-
-                       /* add audio callback probe if condition is satisfied */
-                       if (!player->audio_cb_probe_id && player->set_mode.pcm_extraction && !player->audio_stream_render_cb_ex)
-                               __mmplayer_configure_audio_callback(player);
-
-                       /* FIXIT : handle return value */
-               }
+               __mmplayer_set_pause_state(player);
                break;
-
        case MM_PLAYER_STATE_PLAYING:
-               {
-                       /* try to get content metadata */
-                       if (!player->sent_bos) {
-                               /* NOTE : giving ATTR_MISSING_ONLY may have dependency with
-                                * c-api since c-api doesn't use _start() anymore. It may not work propery with
-                                * legacy mmfw-player api */
-                               _mmplayer_update_content_attrs(player, ATTR_MISSING_ONLY);
-                       }
-
-                       if ((player->cmd == MMPLAYER_COMMAND_START) || (player->cmd == MMPLAYER_COMMAND_RESUME)) {
-                               if (!player->sent_bos)
-                                       __mmplayer_handle_missed_plugin(player);
-                       }
-
-                       if (player->resumed_by_rewind && player->playback_rate < 0.0) {
-                               /* initialize because auto resume is done well. */
-                               player->resumed_by_rewind = FALSE;
-                               player->playback_rate = 1.0;
-                       }
-
-                       if (!player->sent_bos) {
-                               /* check audio codec field is set or not
-                                * we can get it from typefinder or codec's caps.
-                                */
-                               gchar *audio_codec = NULL;
-                               mm_attrs_get_string_by_name(player->attrs, "content_audio_codec", &audio_codec);
-
-                               /* The codec format can't be sent for audio only case like amr, mid etc.
-                                * Because, parser don't make related TAG.
-                                * So, if it's not set yet, fill it with found data.
-                                */
-                               if (!audio_codec) {
-                                       if (g_strrstr(player->type, "audio/midi"))
-                                               audio_codec = g_strdup("MIDI");
-                                       else if (g_strrstr(player->type, "audio/x-amr"))
-                                               audio_codec = g_strdup("AMR");
-                                       else if (g_strrstr(player->type, "audio/mpeg") && !g_strrstr(player->type, "mpegversion= (int)1"))
-                                               audio_codec = g_strdup("AAC");
-                                       else
-                                               audio_codec = g_strdup("unknown");
-                                       mm_attrs_set_string_by_name(player->attrs, "content_audio_codec", audio_codec);
-
-                                       MMPLAYER_FREEIF(audio_codec);
-                                       if (mmf_attrs_commit(player->attrs))
-                                               LOGE("failed to update attributes\n");
-
-                                       LOGD("set audio codec type with caps\n");
-                               }
-
-                               post_bos = TRUE;
-                       }
-               }
+               __mmplayer_set_playing_state(player);
                break;
-
        case MM_PLAYER_STATE_NONE:
        default:
-               LOGW("invalid target state, there is nothing to do.\n");
+               LOGW("invalid target state, there is nothing to do.");
                break;
        }
 
@@ -684,293 +409,264 @@ __mmplayer_set_state(mm_player_t* player, int state)
                LOGD("player reach the target state (%s)", MMPLAYER_STATE_GET_NAME(MMPLAYER_TARGET_STATE(player)));
 
                /* state changed by resource callback */
-               if (player->interrupted_by_resource) {
-                       msg.state.code = MM_PLAYER_FOCUS_CHANGED_BY_RESOURCE_CONFLICT;
+               if (player->interrupted_by_resource)
                        MMPLAYER_POST_MSG(player, MM_MESSAGE_STATE_INTERRUPTED, &msg);
-               } else { /* state changed by usecase */
+               else /* state changed by usecase */
                        MMPLAYER_POST_MSG(player, MM_MESSAGE_STATE_CHANGED, &msg);
-               }
+
        } else {
-               LOGD("intermediate state, do nothing.\n");
+               LOGD("intermediate state, do nothing.");
                MMPLAYER_PRINT_STATE(player);
-               return MM_ERROR_NONE;
+               return;
        }
 
-       if (post_bos) {
+       if (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PLAYING
+               && !player->sent_bos) {
                MMPLAYER_POST_MSG(player, MM_MESSAGE_BEGIN_OF_STREAM, NULL);
                player->sent_bos = TRUE;
        }
 
-       return MM_ERROR_NONE;
+       return;
 }
 
-static gpointer __mmplayer_next_play_thread(gpointer data)
+int
+__mmplayer_check_state(mmplayer_t *player, mmplayer_command_state_e command)
 {
-       mm_player_t* player = (mm_player_t*) data;
-       MMPlayerGstElement *mainbin = NULL;
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
+       mmplayer_state_e current_state = MM_PLAYER_STATE_NUM;
+       mmplayer_state_e pending_state = MM_PLAYER_STATE_NUM;
 
-       MMPLAYER_NEXT_PLAY_THREAD_LOCK(player);
-       while (!player->next_play_thread_exit) {
-               LOGD("next play thread started. waiting for signal.\n");
-               MMPLAYER_NEXT_PLAY_THREAD_WAIT(player);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-               LOGD("reconfigure pipeline for gapless play.\n");
+       //LOGD("incomming command : %d ", command);
 
-               if (player->next_play_thread_exit) {
-                       if (player->gapless.reconfigure) {
-                               player->gapless.reconfigure = false;
-                               MMPLAYER_PLAYBACK_UNLOCK(player);
-                       }
-                       LOGD("exiting gapless play thread\n");
-                       break;
-               }
+       current_state = MMPLAYER_CURRENT_STATE(player);
+       pending_state = MMPLAYER_PENDING_STATE(player);
 
-               mainbin = player->pipeline->mainbin;
+       MMPLAYER_PRINT_STATE(player);
 
-               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_MUXED_S_BUFFER);
-               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_ID3DEMUX);
-               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_AUTOPLUG);
-               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_TYPEFIND);
-               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_SRC);
+       switch (command) {
+       case MMPLAYER_COMMAND_CREATE:
+       {
+               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_NULL;
 
-               __mmplayer_activate_next_source(player, GST_STATE_PLAYING);
+               if (current_state == MM_PLAYER_STATE_NULL ||
+                       current_state == MM_PLAYER_STATE_READY ||
+                       current_state == MM_PLAYER_STATE_PAUSED ||
+                       current_state == MM_PLAYER_STATE_PLAYING)
+                       goto NO_OP;
        }
-       MMPLAYER_NEXT_PLAY_THREAD_UNLOCK(player);
+       break;
 
-       return NULL;
-}
+       case MMPLAYER_COMMAND_DESTROY:
+       {
+               /* destroy can called anytime */
 
-static void
-__mmplayer_update_buffer_setting(mm_player_t *player, GstMessage *buffering_msg)
-{
-       MMHandleType attrs = 0;
-       guint64 data_size = 0;
-       gchar* path = NULL;
-       unsigned long pos_msec = 0;
-       struct stat sb;
+               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_NONE;
+       }
+       break;
 
-       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
+       case MMPLAYER_COMMAND_REALIZE:
+       {
+               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_READY;
 
-       __gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, &pos_msec);       // update last_position
+               if (pending_state != MM_PLAYER_STATE_NONE) {
+                       goto INVALID_STATE;
+               } else {
+                       /* need ready state to realize */
+                       if (current_state == MM_PLAYER_STATE_READY)
+                               goto NO_OP;
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if (!attrs) {
-               LOGE("fail to get attributes.\n");
-               return;
+                       if (current_state != MM_PLAYER_STATE_NULL)
+                               goto INVALID_STATE;
+               }
        }
+       break;
 
-       if (!MMPLAYER_IS_STREAMING(player) && (player->can_support_codec & FOUND_PLUGIN_VIDEO)) {
-               mm_attrs_get_string_by_name(attrs, "profile_uri", &path);
+       case MMPLAYER_COMMAND_UNREALIZE:
+       {
+               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_NULL;
 
-               if (stat(path, &sb) == 0)
-                       data_size = (guint64)sb.st_size;
-       } else if (MMPLAYER_IS_HTTP_STREAMING(player))
-               data_size = player->http_content_size;
+               if (current_state == MM_PLAYER_STATE_NULL)
+                       goto NO_OP;
+       }
+       break;
 
-       __mm_player_streaming_buffering(player->streamer,
-                                                                               buffering_msg,
-                                                                               data_size,
-                                                                               player->last_position,
-                                                                               player->duration);
+       case MMPLAYER_COMMAND_START:
+       {
+               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PLAYING;
 
-       __mm_player_streaming_sync_property(player->streamer, player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst);
+               if (pending_state == MM_PLAYER_STATE_NONE) {
+                       if (current_state == MM_PLAYER_STATE_PLAYING)
+                               goto NO_OP;
+                       else if (current_state  != MM_PLAYER_STATE_READY &&
+                               current_state != MM_PLAYER_STATE_PAUSED)
+                               goto INVALID_STATE;
+               } else if (pending_state == MM_PLAYER_STATE_PLAYING) {
+                       goto ALREADY_GOING;
+               } else if (pending_state == MM_PLAYER_STATE_PAUSED) {
+                       LOGD("player is going to paused state, just change the pending state as playing");
+               } else {
+                       goto INVALID_STATE;
+               }
+       }
+       break;
 
-       return;
-}
+       case MMPLAYER_COMMAND_STOP:
+       {
+               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_READY;
 
-static int
-__mmplayer_handle_buffering_message(mm_player_t* player)
-{
-       int ret = MM_ERROR_NONE;
-       MMPlayerStateType prev_state = MM_PLAYER_STATE_NONE;
-       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
-       MMPlayerStateType target_state = MM_PLAYER_STATE_NONE;
-       MMPlayerStateType pending_state = MM_PLAYER_STATE_NONE;
+               if (current_state == MM_PLAYER_STATE_READY)
+                       goto NO_OP;
 
-       if (!player || !player->streamer || (MMPLAYER_IS_LIVE_STREAMING(player) && MMPLAYER_IS_RTSP_STREAMING(player))) {
-               LOGW("do nothing for buffering msg\n");
-               ret = MM_ERROR_PLAYER_INVALID_STATE;
-               goto exit;
+               /* need playing/paused state to stop */
+               if (current_state != MM_PLAYER_STATE_PLAYING &&
+                        current_state != MM_PLAYER_STATE_PAUSED)
+                       goto INVALID_STATE;
        }
+       break;
 
-       prev_state = MMPLAYER_PREV_STATE(player);
-       current_state = MMPLAYER_CURRENT_STATE(player);
-       target_state = MMPLAYER_TARGET_STATE(player);
-       pending_state = MMPLAYER_PENDING_STATE(player);
+       case MMPLAYER_COMMAND_PAUSE:
+       {
+               if (MMPLAYER_IS_LIVE_STREAMING(player))
+                       goto NO_OP;
 
-       LOGD("player state : prev %s, current %s, pending %s, target %s, buffering %d",
-               MMPLAYER_STATE_GET_NAME(prev_state),
-               MMPLAYER_STATE_GET_NAME(current_state),
-               MMPLAYER_STATE_GET_NAME(pending_state),
-               MMPLAYER_STATE_GET_NAME(target_state),
-               player->streamer->is_buffering);
-
-       if (!player->streamer->is_buffering) {
-               /* NOTE : if buffering has done, player has to go to target state. */
-               switch (target_state) {
-               case MM_PLAYER_STATE_PAUSED:
-                       {
-                               switch (pending_state) {
-                               case MM_PLAYER_STATE_PLAYING:
-                                       __gst_pause(player, TRUE);
-                                       break;
-
-                               case MM_PLAYER_STATE_PAUSED:
-                                       LOGD("player is already going to paused state, there is nothing to do.\n");
-                                       break;
-
-                               case MM_PLAYER_STATE_NONE:
-                               case MM_PLAYER_STATE_NULL:
-                               case MM_PLAYER_STATE_READY:
-                               default:
-                                       LOGW("invalid pending state [%s].\n", MMPLAYER_STATE_GET_NAME(pending_state));
-                                       break;
-                               }
-                       }
-                       break;
+               if (player->seek_state == MMPLAYER_SEEK_IN_PROGRESS)
+                       goto NOT_COMPLETED_SEEK;
 
-               case MM_PLAYER_STATE_PLAYING:
-                       {
-                               switch (pending_state) {
-                               case MM_PLAYER_STATE_NONE:
-                                       {
-                                               if (current_state != MM_PLAYER_STATE_PLAYING)
-                                                       __gst_resume(player, TRUE);
-                                       }
-                                       break;
-
-                               case MM_PLAYER_STATE_PAUSED:
-                                       /* NOTE: It should be worked as asynchronously.
-                                        * Because, buffering can be completed during autoplugging when pipeline would try to go playing state directly.
-                                        */
-                                       if (current_state == MM_PLAYER_STATE_PLAYING) {
-                                               /* NOTE: If the current state is PLAYING, it means, async __gst_pause() is not completed yet.
-                                                * The current state should be changed to paused purposely to prevent state conflict.
-                                                */
-                                               MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PAUSED);
-                                       }
-                                       __gst_resume(player, TRUE);
-                                       break;
-
-                               case MM_PLAYER_STATE_PLAYING:
-                                       LOGD("player is already going to playing state, there is nothing to do.\n");
-                                       break;
-
-                               case MM_PLAYER_STATE_NULL:
-                               case MM_PLAYER_STATE_READY:
-                               default:
-                                       LOGW("invalid pending state [%s].\n", MMPLAYER_STATE_GET_NAME(pending_state));
-                                       break;
-                               }
-                       }
-                       break;
+               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PAUSED;
 
-               case MM_PLAYER_STATE_NULL:
-               case MM_PLAYER_STATE_READY:
-               case MM_PLAYER_STATE_NONE:
-               default:
-                       LOGW("invalid target state [%s].\n", MMPLAYER_STATE_GET_NAME(target_state));
-                       break;
+               if (pending_state == MM_PLAYER_STATE_NONE) {
+                       if (current_state == MM_PLAYER_STATE_PAUSED)
+                               goto NO_OP;
+                       else if (current_state != MM_PLAYER_STATE_PLAYING && current_state != MM_PLAYER_STATE_READY) // support loading state of broswer
+                               goto INVALID_STATE;
+               } else if (pending_state == MM_PLAYER_STATE_PAUSED) {
+                       goto ALREADY_GOING;
+               } else if (pending_state == MM_PLAYER_STATE_PLAYING) {
+                       if (current_state == MM_PLAYER_STATE_PAUSED)
+                               LOGD("player is PAUSED going to PLAYING, just change the pending state as PAUSED");
+                       else
+                               goto INVALID_STATE;
                }
-       } else {
-               /* NOTE : during the buffering, pause the player for stopping pipeline clock.
-                *      it's for stopping the pipeline clock to prevent dropping the data in sink element.
-                */
-               switch (pending_state) {
-               case MM_PLAYER_STATE_NONE:
-                       {
-                               if (current_state != MM_PLAYER_STATE_PAUSED) {
-                                       /* rtsp streaming pause makes rtsp server stop sending data. */
-                                       if (!MMPLAYER_IS_RTSP_STREAMING(player)) {
-                                               LOGD("set pause state during buffering\n");
-                                               __gst_pause(player, TRUE);
-                                       }
-                               }
-                       }
-                       break;
+       }
+       break;
 
-               case MM_PLAYER_STATE_PLAYING:
-                       /* rtsp streaming pause makes rtsp server stop sending data. */
-                       if (!MMPLAYER_IS_RTSP_STREAMING(player))
-                               __gst_pause(player, TRUE);
-                       break;
+       case MMPLAYER_COMMAND_RESUME:
+       {
+               if (player->seek_state == MMPLAYER_SEEK_IN_PROGRESS)
+                       goto NOT_COMPLETED_SEEK;
 
-               case MM_PLAYER_STATE_PAUSED:
-                       break;
+               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PLAYING;
 
-               case MM_PLAYER_STATE_NULL:
-               case MM_PLAYER_STATE_READY:
-               default:
-                       LOGW("invalid pending state [%s].\n", MMPLAYER_STATE_GET_NAME(pending_state));
-                       break;
+               if (pending_state == MM_PLAYER_STATE_NONE) {
+                       if (current_state == MM_PLAYER_STATE_PLAYING)
+                               goto NO_OP;
+                       else if (current_state != MM_PLAYER_STATE_PAUSED)
+                               goto INVALID_STATE;
+               } else if (pending_state == MM_PLAYER_STATE_PLAYING) {
+                       goto ALREADY_GOING;
+               } else if (pending_state == MM_PLAYER_STATE_PAUSED) {
+                       LOGD("player is going to paused state, just change the pending state as playing");
+               } else {
+                       goto INVALID_STATE;
                }
        }
+               break;
 
-exit:
-       return ret;
-}
+       default:
+               break;
+       }
+       player->cmd = command;
 
-static void
-__mmplayer_drop_subtitle(mm_player_t* player, gboolean is_drop)
-{
-       MMPlayerGstElement *textbin;
-       MMPLAYER_FENTER();
+       return MM_ERROR_NONE;
 
-       MMPLAYER_RETURN_IF_FAIL(player &&
-                                       player->pipeline &&
-                                       player->pipeline->textbin);
+INVALID_STATE:
+       LOGW("since player is in wrong state(%s). it's not able to apply the command(%d)",
+               MMPLAYER_STATE_GET_NAME(current_state), command);
+       return MM_ERROR_PLAYER_INVALID_STATE;
 
-       MMPLAYER_RETURN_IF_FAIL(player->pipeline->textbin[MMPLAYER_T_IDENTITY].gst);
+NOT_COMPLETED_SEEK:
+       LOGW("not completed seek");
+       return MM_ERROR_PLAYER_DOING_SEEK;
 
-       textbin = player->pipeline->textbin;
+NO_OP:
+       LOGW("player is in the desired state(%s). doing noting", MMPLAYER_STATE_GET_NAME(current_state));
+       return MM_ERROR_PLAYER_NO_OP;
 
-       if (is_drop) {
-               LOGD("Drop subtitle text after getting EOS\n");
+ALREADY_GOING:
+       LOGW("player is already going to %s, doing nothing", MMPLAYER_STATE_GET_NAME(pending_state));
+       return MM_ERROR_PLAYER_NO_OP;
+}
 
-               g_object_set(textbin[MMPLAYER_T_FAKE_SINK].gst, "async", FALSE, NULL);
-               g_object_set(textbin[MMPLAYER_T_IDENTITY].gst, "drop-probability", (gfloat)1.0, NULL);
+static gpointer
+__mmplayer_gapless_play_thread(gpointer data)
+{
+       mmplayer_t *player = (mmplayer_t *)data;
+       mmplayer_gst_element_t *mainbin = NULL;
 
-               player->is_subtitle_force_drop = TRUE;
-       } else {
-               if (player->is_subtitle_force_drop == TRUE) {
-                       LOGD("Enable subtitle data path without drop\n");
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
 
-                       g_object_set(textbin[MMPLAYER_T_IDENTITY].gst, "drop-probability", (gfloat)0.0, NULL);
-                       g_object_set(textbin[MMPLAYER_T_FAKE_SINK].gst, "async", TRUE, NULL);
+       MMPLAYER_GAPLESS_PLAY_THREAD_LOCK(player);
+       while (!player->gapless_play_thread_exit) {
+               LOGD("gapless play thread started. waiting for signal.");
+               MMPLAYER_GAPLESS_PLAY_THREAD_WAIT(player);
 
-                       LOGD("non-connected with external display");
+               LOGD("reconfigure pipeline for gapless play.");
 
-                       player->is_subtitle_force_drop = FALSE;
+               if (player->gapless_play_thread_exit) {
+                       if (player->gapless.reconfigure) {
+                               player->gapless.reconfigure = false;
+                               MMPLAYER_PLAYBACK_UNLOCK(player);
+                       }
+                       LOGD("exiting gapless play thread");
+                       break;
                }
+
+               mainbin = player->pipeline->mainbin;
+
+               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_MUXED_S_BUFFER);
+               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_ID3DEMUX);
+               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_AUTOPLUG);
+               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_TYPEFIND);
+               MMPLAYER_RELEASE_ELEMENT(player, mainbin, MMPLAYER_M_SRC);
+
+               __mmplayer_activate_next_source(player, GST_STATE_PLAYING);
        }
+       MMPLAYER_GAPLESS_PLAY_THREAD_UNLOCK(player);
+
+       return NULL;
 }
 
-static VariantData *
-__mmplayer_adaptive_var_info(const VariantData *self, gpointer user_data)
+static void
+__mmplayer_remove_g_source_from_context(GMainContext *context, guint source_id)
 {
-       VariantData *var_info = NULL;
-       g_return_val_if_fail(self != NULL, NULL);
+       GSource *source = NULL;
+
+       MMPLAYER_FENTER();
+
+       source = g_main_context_find_source_by_id(context, source_id);
+       if (source != NULL) {
+               LOGW("context: %p, source id: %d, source: %p", context, source_id, source);
+               g_source_destroy(source);
+       }
 
-       var_info = g_new0(VariantData, 1);
-       if (!var_info) return NULL;
-       var_info->bandwidth = self->bandwidth;
-       var_info->width = self->width;
-       var_info->height = self->height;
-       return var_info;
+       MMPLAYER_FLEAVE();
 }
 
-void _mmplayer_bus_msg_thread_destroy(MMHandleType hplayer)
+void
+__mmplayer_bus_msg_thread_destroy(MMHandleType hplayer)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        GstMessage *msg = NULL;
        GQueue *queue = NULL;
 
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       player->bus_msg_timeout = PLAYER_BUS_MSG_DEFAULT_TIMEOUT;
+       /* 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) {
@@ -991,6 +687,10 @@ void _mmplayer_bus_msg_thread_destroy(MMHandleType hplayer)
        queue = player->bus_msg_q;
        while (!g_queue_is_empty(queue)) {
                msg = (GstMessage *)g_queue_pop_head(queue);
+               if (!msg) {
+                       LOGW("msg is null");
+                       continue;
+               }
                LOGW("remove remained %s msg", GST_MESSAGE_TYPE_NAME(msg));
                gst_message_unref(msg);
        }
@@ -999,7102 +699,3725 @@ void _mmplayer_bus_msg_thread_destroy(MMHandleType hplayer)
        MMPLAYER_FLEAVE();
 }
 
-gboolean __mmplayer_gst_msg_push(GstBus *bus, GstMessage *msg, gpointer data)
+gboolean
+__mmplayer_gst_remove_fakesink(mmplayer_t *player, mmplayer_gst_element_t *fakesink)
 {
-       mm_player_t *player = (mm_player_t *) data;
+       GstElement *parent = NULL;
 
-       g_return_val_if_fail(player, FALSE);
-       g_return_val_if_fail(msg && GST_IS_MESSAGE(msg), FALSE);
-
-       gst_message_ref(msg);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, FALSE);
+       MMPLAYER_RETURN_VAL_IF_FAIL(fakesink && fakesink->gst, TRUE);
 
-       g_mutex_lock(&player->bus_msg_q_lock);
-       g_queue_push_tail(player->bus_msg_q, msg);
-       g_mutex_unlock(&player->bus_msg_q_lock);
+       /* lock */
+       MMPLAYER_FSINK_LOCK(player);
 
-       MMPLAYER_BUS_MSG_THREAD_LOCK(player);
-       MMPLAYER_BUS_MSG_THREAD_SIGNAL(player);
-       MMPLAYER_BUS_MSG_THREAD_UNLOCK(player);
-       return TRUE;
-}
+       /* get parent of fakesink */
+       parent = (GstElement *)gst_object_get_parent((GstObject *)fakesink->gst);
+       if (!parent) {
+               LOGD("fakesink already removed");
+               goto ERROR;
+       }
 
-static gpointer __mmplayer_gst_bus_msg_thread(gpointer data)
-{
-       mm_player_t *player = (mm_player_t*)(data);
-       GstMessage *msg = NULL;
-       GstBus *bus = NULL;
+       gst_element_set_locked_state(fakesink->gst, TRUE);
 
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player &&
-                                               player->pipeline &&
-                                               player->pipeline->mainbin &&
-                                               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
-                                               NULL);
+       /* setting the state to NULL never returns async
+        * so no need to wait for completion of state transiton
+        */
+       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(fakesink->gst, GST_STATE_NULL))
+               LOGE("fakesink state change failure!");
+               /* FIXIT : should I return here? or try to proceed to next? */
+               /* return FALSE; */
 
-       bus = gst_pipeline_get_bus(GST_PIPELINE(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
-       if (!bus) {
-               LOGE("cannot get BUS from the pipeline");
-               return NULL;
-       }
+       /* remove fakesink from it's parent */
+       if (!gst_bin_remove(GST_BIN(parent), fakesink->gst)) {
+               LOGE("failed to remove fakesink");
 
-       MMPLAYER_BUS_MSG_THREAD_LOCK(player);
+               gst_object_unref(parent);
 
-       LOGD("[handle: %p] gst bus msg thread will be started.", player);
-       while (!player->bus_msg_thread_exit) {
-               g_mutex_lock(&player->bus_msg_q_lock);
-               msg = g_queue_pop_head(player->bus_msg_q);
-               g_mutex_unlock(&player->bus_msg_q_lock);
-               if (msg == NULL) {
-                       MMPLAYER_BUS_MSG_THREAD_WAIT(player);
-                       continue;
-               }
-               MMPLAYER_BUS_MSG_THREAD_UNLOCK(player);
-               /* handle the gst msg */
-               __mmplayer_gst_callback(msg, player);
-               MMPLAYER_BUS_MSG_THREAD_LOCK(player);
-               gst_message_unref(msg);
+               goto ERROR;
        }
 
-       MMPLAYER_BUS_MSG_THREAD_UNLOCK(player);
-       gst_object_unref(GST_OBJECT(bus));
-
-       MMPLAYER_FLEAVE();
-       return NULL;
-}
+       gst_object_unref(parent);
 
-static void
-__mmplayer_gst_callback(GstMessage *msg, gpointer data)
-{
-       mm_player_t* player = (mm_player_t*)(data);
-       static gboolean async_done = FALSE;
+       LOGD("state-holder removed");
 
-       MMPLAYER_RETURN_IF_FAIL(player);
-       MMPLAYER_RETURN_IF_FAIL(msg && GST_IS_MESSAGE(msg));
+       gst_element_set_locked_state(fakesink->gst, FALSE);
 
-       switch (GST_MESSAGE_TYPE(msg)) {
-       case GST_MESSAGE_UNKNOWN:
-               LOGD("unknown message received\n");
-               break;
+       MMPLAYER_FSINK_UNLOCK(player);
+       return TRUE;
 
-       case GST_MESSAGE_EOS:
-               {
-                       MMHandleType attrs = 0;
-                       gint count = 0;
+ERROR:
+       if (fakesink->gst)
+               gst_element_set_locked_state(fakesink->gst, FALSE);
 
-                       LOGD("GST_MESSAGE_EOS received\n");
+       MMPLAYER_FSINK_UNLOCK(player);
+       return FALSE;
+}
 
-                       /* NOTE : EOS event is comming multiple time. watch out it */
-                       /* check state. we only process EOS when pipeline state goes to PLAYING */
-                       if (!(player->cmd == MMPLAYER_COMMAND_START || player->cmd == MMPLAYER_COMMAND_RESUME)) {
-                               LOGD("EOS received on non-playing state. ignoring it\n");
-                               break;
-                       }
+static GstPadProbeReturn
+__mmplayer_gst_selector_blocked(GstPad *pad, GstPadProbeInfo *info, gpointer data)
+{
+       LOGD("pad(%s:%s) is blocked", GST_DEBUG_PAD_NAME(pad));
+       return GST_PAD_PROBE_OK;
+}
 
-                       if (player->pipeline) {
-                               if (player->pipeline->textbin)
-                                       __mmplayer_drop_subtitle(player, TRUE);
+static void
+__mmplayer_gst_selector_update_start_time(mmplayer_t *player, mmplayer_track_type_e stream_type)
+{
+       gint64 stop_running_time = 0;
+       gint64 position_running_time = 0;
+       gint64 position = 0;
+       gint idx = 0;
 
-                               if ((player->audio_stream_cb) && (player->set_mode.pcm_extraction) && (!player->audio_stream_render_cb_ex)) {
-                                       GstPad *pad = NULL;
+       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); */
+                       continue;
+               }
 
-                                       pad = gst_element_get_static_pad(player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
+               if (GST_CLOCK_TIME_IS_VALID(player->gapless.segment[idx].stop)) {
+                       stop_running_time =
+                               gst_segment_to_running_time(&player->gapless.segment[idx],
+                                               GST_FORMAT_TIME, player->gapless.segment[idx].stop);
+               } else if (GST_CLOCK_TIME_IS_VALID(player->gapless.segment[idx].duration)) {
+                       stop_running_time =
+                               gst_segment_to_running_time(&player->gapless.segment[idx],
+                                               GST_FORMAT_TIME, player->gapless.segment[idx].duration);
+               } else {
+                       LOGD("duration: %"GST_TIME_FORMAT, GST_TIME_ARGS(player->duration));
+                       stop_running_time =
+                               gst_segment_to_running_time(&player->gapless.segment[idx],
+                                               GST_FORMAT_TIME, player->duration);
+               }
 
-                                       LOGD("release audio callback\n");
+               position_running_time =
+                       gst_segment_to_running_time(&player->gapless.segment[idx],
+                       GST_FORMAT_TIME, player->gapless.segment[idx].position);
 
-                                       /* release audio callback */
-                                       gst_pad_remove_probe(pad, player->audio_cb_probe_id);
-                                       player->audio_cb_probe_id = 0;
-                                       /* audio callback should be free because it can be called even though probe remove.*/
-                                       player->audio_stream_cb = NULL;
-                                       player->audio_stream_cb_user_param = NULL;
+               LOGD("[type:%d] time info %" GST_TIME_FORMAT " , %"
+                       GST_TIME_FORMAT" , %" GST_TIME_FORMAT,
+                       idx,
+                       GST_TIME_ARGS(stop_running_time),
+                       GST_TIME_ARGS(position_running_time),
+                       GST_TIME_ARGS(gst_segment_to_running_time(&player->gapless.segment[idx],
+                       GST_FORMAT_TIME, player->gapless.segment[idx].start)));
 
-                               }
-                       }
-                       if ((player->audio_stream_render_cb_ex) && (!player->audio_stream_sink_sync))
-                               __mmplayer_audio_stream_clear_buffer(player, TRUE);
+               position_running_time = MAX(position_running_time, stop_running_time);
+               position_running_time -= gst_segment_to_running_time(&player->gapless.segment[idx],
+                                                                               GST_FORMAT_TIME, player->gapless.segment[idx].start);
+               position_running_time = MAX(0, position_running_time);
+               position = MAX(position, position_running_time);
+       }
 
-                       /* rewind if repeat count is greater then zero */
-                       /* get play count */
-                       attrs = MMPLAYER_GET_ATTRS(player);
+       if (position != 0) {
+               LOGD("[%d]GST_EVENT_STREAM_START: start_time from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
+                       stream_type, GST_TIME_ARGS(player->gapless.start_time[stream_type]),
+                       GST_TIME_ARGS(player->gapless.start_time[stream_type] + position));
 
-                       if (attrs) {
-                               mm_attrs_get_int_by_name(attrs, "profile_play_count", &count);
+               player->gapless.start_time[stream_type] += position;
+       }
 
-                               LOGD("play count: %d, playback rate: %f\n", count, player->playback_rate);
+       return;
+}
 
-                               if (count == -1 || player->playback_rate < 0.0) /* default value is 1 */ {
-                                       if (player->playback_rate < 0.0) {
-                                               player->resumed_by_rewind = TRUE;
-                                               _mmplayer_set_mute((MMHandleType)player, 0);
-                                               MMPLAYER_POST_MSG(player, MM_MESSAGE_RESUMED_BY_REW, NULL);
-                                       }
+static GstPadProbeReturn
+__mmplayer_gst_selector_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer data)
+{
+       GstPadProbeReturn ret = GST_PAD_PROBE_OK;
+       GstEvent *event = GST_PAD_PROBE_INFO_DATA(info);
+       mmplayer_t *player = (mmplayer_t *)data;
+       GstCaps *caps = NULL;
+       GstStructure *str = NULL;
+       const gchar *name = NULL;
+       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) {
+               return ret;
+       } else if (GST_EVENT_IS_UPSTREAM(event) &&
+                          GST_EVENT_TYPE(event) != GST_EVENT_QOS) {
+               return ret;
+       }
 
-                                       __mmplayer_handle_eos_delay(player, player->ini.delay_before_repeat);
+       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
+       if (!caps_ret)
+               goto ERROR;
 
-                                       /* initialize */
-                                       player->sent_bos = FALSE;
+       if (strstr(name, "audio")) {
+               stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
+       } else if (strstr(name, "video")) {
+               stream_type = MM_PLAYER_TRACK_TYPE_VIDEO;
+       } else {
+               /* text track is not supportable */
+               LOGE("invalid name %s", name);
+               goto ERROR;
+       }
 
-                                       /* not posting eos when repeating */
-                                       break;
-                               }
+       switch (GST_EVENT_TYPE(event)) {
+       case GST_EVENT_EOS:
+               {
+                       /* in case of gapless, drop eos event not to send it to sink */
+                       if (player->gapless.reconfigure && !player->msg_posted) {
+                               LOGD("[%d] %s:%s EOS received but will be drop", stream_type, GST_DEBUG_PAD_NAME(pad));
+                               ret = GST_PAD_PROBE_DROP;
                        }
-
-                       if (player->pipeline)
-                               MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-eos");
-
-                       /* post eos message to application */
-                       __mmplayer_handle_eos_delay(player, player->ini.eos_delay);
-
-                       /* reset last position */
-                       player->last_position = 0;
+                       break;
                }
-               break;
-
-       case GST_MESSAGE_ERROR:
+       case GST_EVENT_STREAM_START:
                {
-                       GError *error = NULL;
-                       gchar* debug = NULL;
-
-                       /* generating debug info before returning error */
-                       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-error");
-
-                       /* get error code */
-                       gst_message_parse_error(msg, &error, &debug);
-
-                       if (gst_structure_has_name(gst_message_get_structure(msg), "streaming_error")) {
-                               /* Note : the streaming error from the streaming source is handled
-                                *   using __mmplayer_handle_streaming_error.
-                                */
-                               __mmplayer_handle_streaming_error(player, msg);
-
-                               /* dump state of all element */
-                               __mmplayer_dump_pipeline_state(player);
-                       } else {
-                               /* traslate gst error code to msl error code. then post it
-                                * to application if needed
-                                */
-                               __mmplayer_handle_gst_error(player, msg, error);
+                       __mmplayer_gst_selector_update_start_time(player, stream_type);
+                       break;
+               }
+       case GST_EVENT_FLUSH_STOP:
+               {
+                       LOGD("[%d] GST_EVENT_FLUSH_STOP", stream_type);
+                       gst_segment_init(&player->gapless.segment[stream_type], GST_FORMAT_UNDEFINED);
+                       player->gapless.start_time[stream_type] = 0;
+                       break;
+               }
+       case GST_EVENT_SEGMENT:
+               {
+                       GstSegment segment;
+                       GstEvent *tmpev;
 
-                               if (debug)
-                                       LOGE("error debug : %s", debug);
-                       }
+                       LOGD("[%d] GST_EVENT_SEGMENT", stream_type);
+                       gst_event_copy_segment(event, &segment);
 
-                       if (MMPLAYER_IS_HTTP_PD(player))
-                               _mmplayer_unrealize_pd_downloader((MMHandleType)player);
+                       if (segment.format != GST_FORMAT_TIME)
+                               break;
 
-                       MMPLAYER_FREEIF(debug);
-                       g_error_free(error);
-               }
-               break;
+                       LOGD("segment base:%" GST_TIME_FORMAT ", offset:%" GST_TIME_FORMAT
+                                ", start:%" GST_TIME_FORMAT ", stop: %" GST_TIME_FORMAT
+                                ", time: %" GST_TIME_FORMAT ", pos: %" GST_TIME_FORMAT ", dur: %" GST_TIME_FORMAT,
+                               GST_TIME_ARGS(segment.base), GST_TIME_ARGS(segment.offset),
+                               GST_TIME_ARGS(segment.start), GST_TIME_ARGS(segment.stop),
+                               GST_TIME_ARGS(segment.time), GST_TIME_ARGS(segment.position), GST_TIME_ARGS(segment.duration));
 
-       case GST_MESSAGE_WARNING:
-               {
-                       char* debug = NULL;
-                       GError* error = NULL;
+                       /* keep the all the segment ev to cover the seeking */
+                       gst_segment_copy_into(&segment, &player->gapless.segment[stream_type]);
+                       player->gapless.update_segment[stream_type] = TRUE;
 
-                       gst_message_parse_warning(msg, &error, &debug);
+                       if (!player->gapless.running)
+                               break;
 
-                       LOGD("warning : %s\n", error->message);
-                       LOGD("debug : %s\n", debug);
+                       player->gapless.segment[stream_type].base = player->gapless.start_time[stream_type];
 
-                       MMPLAYER_POST_MSG(player, MM_MESSAGE_WARNING, NULL);
+                       LOGD("[%d] new base: %" GST_TIME_FORMAT, stream_type, GST_TIME_ARGS(player->gapless.segment[stream_type].base));
 
-                       MMPLAYER_FREEIF(debug);
-                       g_error_free(error);
-               }
-               break;
+                       tmpev = gst_event_new_segment(&player->gapless.segment[stream_type]);
+                       gst_event_set_seqnum(tmpev, gst_event_get_seqnum(event));
+                       gst_event_unref(event);
+                       GST_PAD_PROBE_INFO_DATA(info) = tmpev;
 
-       case GST_MESSAGE_TAG:
-               {
-                       LOGD("GST_MESSAGE_TAG\n");
-                       if (!__mmplayer_gst_extract_tag_from_msg(player, msg))
-                               LOGW("failed to extract tags from gstmessage\n");
+                       break;
                }
-               break;
-
-       case GST_MESSAGE_BUFFERING:
+       case GST_EVENT_QOS:
                {
-                       MMMessageParamType msg_param = {0, };
-                       int bRet = MM_ERROR_NONE;
+                       gdouble proportion = 0.0;
+                       GstClockTimeDiff diff = 0;
+                       GstClockTime timestamp = 0;
+                       gint64 running_time_diff = -1;
+                       GstQOSType type = 0;
+                       GstEvent *tmpev = NULL;
 
-                       if (!(player->pipeline && player->pipeline->mainbin)) {
-                               LOGE("player pipeline handle is null");
-                               break;
-                       }
+                       running_time_diff = player->gapless.segment[stream_type].base;
 
-                       if (!MMPLAYER_IS_STREAMING(player))
+                       if (running_time_diff <= 0) /* don't need to adjust */
                                break;
 
-                       if (player->pd_mode == MM_PLAYER_PD_MODE_URI) {
-                               if (!MMPLAYER_CMD_TRYLOCK(player)) {
-                                       /* skip the playback control by buffering msg while user request is handled. */
-                                       gint per = 0;
-
-                                       LOGW("[PD mode] can't get cmd lock, only post buffering msg");
-
-                                       gst_message_parse_buffering(msg, &per);
-                                       LOGD("[PD mode][%s] buffering %d %%....", GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)), per);
+                       gst_event_parse_qos(event, &type, &proportion, &diff, &timestamp);
+                       gst_event_unref(event);
 
-                                       msg_param.connection.buffering = per;
-                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
-                                       break;
-                               }
-                       } else {
-                               MMPLAYER_CMD_LOCK(player);
+                       if (timestamp < running_time_diff) {
+                               LOGW("QOS event from previous group");
+                               ret = GST_PAD_PROBE_DROP;
+                               break;
                        }
 
-                       /* ignore the prev buffering message */
-                       if ((player->streamer) && (player->streamer->is_buffering == FALSE)
-                               && (player->streamer->is_buffering_done == TRUE)) {
-                               gint buffer_percent = 0;
+                       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));
 
-                               gst_message_parse_buffering(msg, &buffer_percent);
+                       timestamp -= running_time_diff;
 
-                               if (buffer_percent == MAX_BUFFER_PERCENT) {
-                                       LOGD("Ignored all the previous buffering msg!(got %d%%)\n", buffer_percent);
-                                       player->streamer->is_buffering_done = FALSE;
-                               }
-                               MMPLAYER_CMD_UNLOCK(player);
+                       /* That case is invalid for QoS events */
+                       if (diff < 0 && -diff > timestamp) {
+                               LOGW("QOS event from previous group");
+                               ret = GST_PAD_PROBE_DROP;
                                break;
                        }
 
-                       __mmplayer_update_buffer_setting(player, msg);
-
-                       bRet = __mmplayer_handle_buffering_message(player);
-
-                       if (bRet == MM_ERROR_NONE) {
-                               msg_param.connection.buffering = player->streamer->buffering_percent;
-                               MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
+                       tmpev = gst_event_new_qos(GST_QOS_TYPE_UNDERFLOW, proportion, diff, timestamp);
+                       GST_PAD_PROBE_INFO_DATA(info) = tmpev;
 
-                               if (MMPLAYER_IS_RTSP_STREAMING(player) &&
-                                       player->pending_resume &&
-                                       (player->streamer->buffering_percent >= MAX_BUFFER_PERCENT)) {
+                       break;
+               }
+       default:
+               break;
+       }
 
-                                       player->is_external_subtitle_added_now = FALSE;
-                                       player->pending_resume = FALSE;
-                                       _mmplayer_resume((MMHandleType)player);
-                               }
+ERROR:
+       if (caps)
+               gst_caps_unref(caps);
+       return ret;
+}
 
-                               if (MMPLAYER_IS_RTSP_STREAMING(player) &&
-                                       (player->streamer->buffering_percent >= MAX_BUFFER_PERCENT)) {
+/* create fakesink for audio or video path witout audiobin or videobin */
+static void
+__mmplayer_gst_make_fakesink(mmplayer_t *player, GstPad *pad, const gchar *name)
+{
+       GstElement *pipeline = NULL;
+       GstElement *fakesink = NULL;
+       GstPad *sinkpad = NULL;
 
-                                       if (player->doing_seek) {
-                                               if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PAUSED) {
-                                                       player->doing_seek = FALSE;
-                                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
-                                               } else if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PLAYING) {
-                                                       async_done = TRUE;
-                                               }
-                                       }
-                               }
-                       } else if (bRet == MM_ERROR_PLAYER_INVALID_STATE) {
-                               if (!player->streamer) {
-                                       LOGW("player->streamer is NULL, so discarding the buffering percent update\n");
-                                       MMPLAYER_CMD_UNLOCK(player);
-                                       break;
-                               }
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
 
-                               if ((MMPLAYER_IS_LIVE_STREAMING(player)) && (MMPLAYER_IS_RTSP_STREAMING(player))) {
+       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
 
-                                       LOGD("player->last_position=%lld , player->streamer->buffering_percent=%d \n",
-                                                       GST_TIME_AS_SECONDS(player->last_position), player->streamer->buffering_percent);
+       /* fake sink */
+       fakesink = gst_element_factory_make("fakesink", NULL);
+       if (fakesink == NULL) {
+               LOGE("failed to create fakesink");
+               goto EXIT;
+       }
 
-                                       if ((GST_TIME_AS_SECONDS(player->last_position) <= 0) && (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PAUSED)) {
-                                               msg_param.connection.buffering = player->streamer->buffering_percent;
-                                               MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
-                                       } else {
-                                               LOGD("Not updating Buffering Message for Live RTSP case !!!\n");
-                                       }
-                               } else {
-                                       msg_param.connection.buffering = player->streamer->buffering_percent;
-                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
-                               }
-                       }
-                       MMPLAYER_CMD_UNLOCK(player);
-               }
-               break;
+       /* store it as it's sink element */
+       __mmplayer_add_sink(player, fakesink);
 
-       case GST_MESSAGE_STATE_CHANGED:
-               {
-                       MMPlayerGstElement *mainbin;
-                       const GValue *voldstate, *vnewstate, *vpending;
-                       GstState oldstate = GST_STATE_NULL;
-                       GstState newstate = GST_STATE_NULL;
-                       GstState pending = GST_STATE_NULL;
-
-                       if (!(player->pipeline && player->pipeline->mainbin)) {
-                               LOGE("player pipeline handle is null");
-                               break;
-                       }
+       gst_bin_add(GST_BIN(pipeline), fakesink);
 
-                       mainbin = player->pipeline->mainbin;
+       /* link */
+       sinkpad = gst_element_get_static_pad(fakesink, "sink");
 
-                       /* we only handle messages from pipeline */
-                       if (msg->src != (GstObject *)mainbin[MMPLAYER_M_PIPE].gst)
-                               break;
+       LOGD("pad link %s:%s - %s:%s", GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(sinkpad));
 
-                       /* get state info from msg */
-                       voldstate = gst_structure_get_value(gst_message_get_structure(msg), "old-state");
-                       vnewstate = gst_structure_get_value(gst_message_get_structure(msg), "new-state");
-                       vpending = gst_structure_get_value(gst_message_get_structure(msg), "pending-state");
+       if (gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) {
+               LOGE("failed to link fakesink");
+               gst_object_unref(GST_OBJECT(fakesink));
+               goto EXIT;
+       }
 
-                       if (!voldstate || !vnewstate) {
-                               LOGE("received msg has wrong format.");
-                               break;
-                       }
+       if (strstr(name, "video")) {
+               if (player->v_stream_caps) {
+                       gst_caps_unref(player->v_stream_caps);
+                       player->v_stream_caps = NULL;
+               }
+               if (player->ini.set_dump_element_flag)
+                       __mmplayer_add_dump_buffer_probe(player, fakesink);
+       }
 
-                       oldstate = (GstState)voldstate->data[0].v_int;
-                       newstate = (GstState)vnewstate->data[0].v_int;
-                       if (vpending)
-                               pending = (GstState)vpending->data[0].v_int;
+       g_object_set(G_OBJECT(fakesink), "sync", TRUE, NULL);
+       gst_element_set_state(fakesink, GST_STATE_PAUSED);
 
-                       LOGD("state changed [%s] : %s ---> %s     final : %s\n",
-                               GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)),
-                               gst_element_state_get_name((GstState)oldstate),
-                               gst_element_state_get_name((GstState)newstate),
-                               gst_element_state_get_name((GstState)pending));
+EXIT:
+       if (sinkpad)
+               gst_object_unref(GST_OBJECT(sinkpad));
 
-                       if (newstate == GST_STATE_PLAYING) {
-                               if ((MMPLAYER_IS_RTSP_STREAMING(player)) && (player->pending_seek.is_pending)) {
+       MMPLAYER_FLEAVE();
+       return;
+}
 
-                                       int retVal = MM_ERROR_NONE;
-                                       LOGD("trying to play from (%lu) pending position\n", player->pending_seek.pos);
+static GstElement *
+__mmplayer_gst_make_selector(mmplayer_t *player, main_element_id_e elem_idx, mmplayer_track_type_e stream_type)
+{
+       GstElement *pipeline = NULL;
+       GstElement *selector = NULL;
+       GstPad *srcpad = NULL;
 
-                                       retVal = __gst_set_position(player, player->pending_seek.format, player->pending_seek.pos, TRUE);
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, NULL);
 
-                                       if (MM_ERROR_NONE != retVal)
-                                               LOGE("failed to seek pending postion. just keep staying current position.\n");
+       selector = gst_element_factory_make("input-selector", NULL);
+       if (!selector) {
+               LOGE("failed to create input-selector");
+               return NULL;
+       }
+       g_object_set(selector, "sync-streams", TRUE, NULL);
 
-                                       player->pending_seek.is_pending = FALSE;
-                               }
-                       }
+       player->pipeline->mainbin[elem_idx].id = elem_idx;
+       player->pipeline->mainbin[elem_idx].gst = selector;
 
-                       if (oldstate == newstate) {
-                               LOGD("pipeline reports state transition to old state");
-                               break;
-                       }
+       /* player->selector[stream_type].active_pad_index = DEFAULT_TRACK; */
 
-                       switch (newstate) {
-                       case GST_STATE_VOID_PENDING:
-                               break;
+       srcpad = gst_element_get_static_pad(selector, "src");
 
-                       case GST_STATE_NULL:
-                               break;
+       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,
+               __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,
+               __mmplayer_gst_selector_event_probe, player, NULL);
 
-                       case GST_STATE_READY:
-                               break;
+       gst_element_set_state(selector, GST_STATE_PAUSED);
 
-                       case GST_STATE_PAUSED:
-                               {
-                                       gboolean prepare_async = FALSE;
-                                       player->bus_msg_timeout = PLAYER_BUS_MSG_DEFAULT_TIMEOUT;
+       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
+       gst_bin_add(GST_BIN(pipeline), selector);
 
-                                       if (!player->audio_cb_probe_id && player->set_mode.pcm_extraction && !player->audio_stream_render_cb_ex)
-                                               __mmplayer_configure_audio_callback(player);
+       gst_object_unref(GST_OBJECT(srcpad));
 
-                                       if (!player->sent_bos && oldstate == GST_STATE_READY) {
-                                               // managed prepare async case
-                                               mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &prepare_async);
-                                               LOGD("checking prepare mode for async transition - %d", prepare_async);
-                                       }
+       MMPLAYER_FLEAVE();
+       return selector;
+}
 
-                                       if (MMPLAYER_IS_STREAMING(player) || MMPLAYER_IS_MS_BUFF_SRC(player) || prepare_async) {
-                                               MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PAUSED);
+void
+__mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
+{
+       mmplayer_t *player = (mmplayer_t *)data;
+       GstElement *selector = NULL;
+       GstCaps *caps = NULL;
+       GstStructure *str = NULL;
+       const gchar *name = NULL;
+       GstPad *sinkpad = NULL;
+       gboolean first_track = FALSE;
+       gboolean caps_ret = TRUE;
 
-                                               if (MMPLAYER_IS_STREAMING(player) && (player->streamer))
-                                                       __mm_player_streaming_set_content_bitrate(player->streamer,
-                                                               player->total_maximum_bitrate, player->total_bitrate);
+       main_element_id_e elem_idx = MMPLAYER_M_NUM;
+       mmplayer_track_type_e stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
 
-                                               if (player->pending_seek.is_pending) {
-                                                       LOGW("trying to do pending seek");
-                                                       MMPLAYER_CMD_LOCK(player);
-                                                       __gst_pending_seek(player);
-                                                       MMPLAYER_CMD_UNLOCK(player);
-                                               }
-                                       }
-                               }
-                               break;
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(elem && pad);
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
 
-                       case GST_STATE_PLAYING:
-                               {
-                                       player->bus_msg_timeout = PLAYER_BUS_MSG_DEFAULT_TIMEOUT;
+       LOGD("pad-added signal handling");
 
-                                       if (MMPLAYER_IS_STREAMING(player)) {
-                                               // managed prepare async case when buffering is completed
-                                               // pending state should be reset otherwise, it's still playing even though it's resumed after bufferging.
-                                               if ((MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING) ||
-                                                       (MMPLAYER_PENDING_STATE(player) == MM_PLAYER_STATE_PLAYING))
-                                                       MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PLAYING);
+       /* get mimetype from caps */
+       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
+       if (!caps_ret)
+               goto ERROR;
 
-                                               if (MMPLAYER_IS_RTSP_STREAMING(player) && (MMPLAYER_IS_LIVE_STREAMING(player))) {
+       MMPLAYER_LOG_GST_CAPS_TYPE(caps);
+       /* LOGD("detected mimetype : %s", name); */
 
-                                                       LOGD("Current Buffering Percent = %d", player->streamer->buffering_percent);
-                                                       if (player->streamer->buffering_percent < 100) {
+       if (strstr(name, "video")) {
+               gint stype = 0;
+               gchar *caps_str = NULL;
 
-                                                               MMMessageParamType msg_param = {0, };
-                                                               LOGW("Posting Buffering Completed Message to Application !!!");
+               caps_str = gst_caps_to_string(caps);
+               if (caps_str && (strstr(caps_str, "ST12") || strstr(caps_str, "SN12") ||
+                       strstr(caps_str, "SN21") || strstr(caps_str, "S420") || strstr(caps_str, "SR32")))
+                       player->set_mode.video_zc = true;
 
-                                                               msg_param.connection.buffering = 100;
-                                                               MMPLAYER_POST_MSG(player, MM_MESSAGE_BUFFERING, &msg_param);
-                                                       }
-                                               }
-                                       }
+               MMPLAYER_FREEIF(caps_str);
 
-                                       if (player->gapless.stream_changed) {
-                                               _mmplayer_update_content_attrs(player, ATTR_ALL);
-                                               player->gapless.stream_changed = FALSE;
-                                       }
+               mm_attrs_set_int_by_name(player->attrs, "content_video_found", TRUE);
+               mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype);
 
-                                       if (player->doing_seek && async_done) {
-                                               player->doing_seek = FALSE;
-                                               async_done = FALSE;
-                                               MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
-                                       }
-                               }
-                               break;
+               LOGD("surface type : %d", stype);
 
-                       default:
-                               break;
-                       }
+               if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
+                       __mmplayer_gst_create_sinkbin(elem, pad, player);
+                       goto DONE;
                }
-               break;
 
-       case GST_MESSAGE_CLOCK_LOST:
-                       {
-                               GstClock *clock = NULL;
-                               gboolean need_new_clock = FALSE;
+               /* in case of exporting video frame, it requires the 360 video filter.
+                * it will be handled in _no_more_pads(). */
+               if ((stype == MM_DISPLAY_SURFACE_NULL) && (!player->set_mode.video_export)) {
+                       __mmplayer_gst_make_fakesink(player, pad, name);
+                       goto DONE;
+               }
 
-                               gst_message_parse_clock_lost(msg, &clock);
-                               LOGD("GST_MESSAGE_CLOCK_LOST : %s\n", (clock ? GST_OBJECT_NAME(clock) : "NULL"));
+               LOGD("video selector is required");
+               elem_idx = MMPLAYER_M_V_INPUT_SELECTOR;
+               stream_type = MM_PLAYER_TRACK_TYPE_VIDEO;
+       } else if (strstr(name, "audio")) {
+               gint samplerate = 0;
+               gint channels = 0;
 
-                               if (!player->videodec_linked)
-                                       need_new_clock = TRUE;
-                               else if (!player->ini.use_system_clock)
-                                       need_new_clock = TRUE;
+               if (MMPLAYER_IS_MS_BUFF_SRC(player) || player->build_audio_offload) {
+                       if (player->build_audio_offload)
+                               player->no_more_pad = TRUE; /* remove state holder */
+                       __mmplayer_gst_create_sinkbin(elem, pad, player);
+                       goto DONE;
+               }
 
-                               if (need_new_clock) {
-                                       LOGD("Provide clock is TRUE, do pause->resume\n");
-                                       __gst_pause(player, FALSE);
-                                       __gst_resume(player, FALSE);
-                               }
-                       }
-                       break;
+               gst_structure_get_int(str, "rate", &samplerate);
+               gst_structure_get_int(str, "channels", &channels);
 
-       case GST_MESSAGE_NEW_CLOCK:
-                       {
-                               GstClock *clock = NULL;
-                               gst_message_parse_new_clock(msg, &clock);
-                               LOGD("GST_MESSAGE_NEW_CLOCK : %s\n", (clock ? GST_OBJECT_NAME(clock) : "NULL"));
-                       }
-                       break;
+               if ((channels > 0 && samplerate == 0)) { /* exclude audio decoding */
+                       __mmplayer_gst_make_fakesink(player, pad, name);
+                       goto DONE;
+               }
 
-       case GST_MESSAGE_ELEMENT:
-                       {
-                               const gchar *structure_name;
-                               gint count = 0, idx = 0;
-                               MMHandleType attrs = 0;
+               LOGD("audio selector is required");
+               elem_idx = MMPLAYER_M_A_INPUT_SELECTOR;
+               stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
 
-                               attrs = MMPLAYER_GET_ATTRS(player);
-                               if (!attrs) {
-                                       LOGE("cannot get content attribute");
-                                       break;
-                               }
+       } else if (strstr(name, "text")) {
+               LOGD("text selector is required");
+               elem_idx = MMPLAYER_M_T_INPUT_SELECTOR;
+               stream_type = MM_PLAYER_TRACK_TYPE_TEXT;
+       } else {
+               LOGE("invalid caps info");
+               goto ERROR;
+       }
 
-                               if (gst_message_get_structure(msg) == NULL)
-                                       break;
+       /* check selector and create it */
+       if (!(selector = player->pipeline->mainbin[elem_idx].gst)) {
+               selector = __mmplayer_gst_make_selector(player, elem_idx, stream_type);
+               if (!selector)
+                       goto ERROR;
+               first_track = TRUE;
+       } else {
+               LOGD("input-selector is already created.");
+       }
 
-                               structure_name = gst_structure_get_name(gst_message_get_structure(msg));
-                               if (!structure_name)
-                                       break;
+       /* link */
+       sinkpad = gst_element_get_request_pad(selector, "sink_%u");
 
-                               LOGD("GST_MESSAGE_ELEMENT %s from %s", structure_name, GST_OBJECT_NAME(GST_MESSAGE_SRC(msg)));
+       LOGD("pad link: %s:%s - %s:%s", GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(sinkpad));
 
-                               if (!strcmp(structure_name, "adaptive-streaming-variant")) {
-                                       const GValue *var_info = NULL;
+       if (gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) {
+               LOGE("failed to link selector");
+               gst_object_unref(GST_OBJECT(selector));
+               goto ERROR;
+       }
 
-                                       var_info = gst_structure_get_value(gst_message_get_structure(msg), "video-variant-info");
-                                       if (var_info != NULL) {
-                                               if (player->adaptive_info.var_list)
-                                                       g_list_free_full(player->adaptive_info.var_list, g_free);
+       if (first_track) {
+               LOGD("this track will be activated");
+               g_object_set(selector, "active-pad", sinkpad, NULL);
+       }
 
-                                               /* share addr or copy the list */
-                                               player->adaptive_info.var_list =
-                                                       g_list_copy_deep((GList *)g_value_get_pointer(var_info), (GCopyFunc)__mmplayer_adaptive_var_info, NULL);
+       __mmplayer_track_update_selector_info(player, stream_type, sinkpad);
 
-                                               count = g_list_length(player->adaptive_info.var_list);
-                                               if (count > 0) {
-                                                       VariantData *temp = NULL;
+DONE:
+ERROR:
 
-                                                       /* print out for debug */
-                                                       LOGD("num of variant_info %d", count);
-                                                       for (idx = 0; idx < count; idx++) {
-                                                               temp = g_list_nth_data(player->adaptive_info.var_list, idx);
-                                                               if (temp)
-                                                                       LOGD("variant(%d) [b]%d [w]%d [h]%d ", idx, temp->bandwidth, temp->width, temp->height);
-                                                       }
-                                               }
-                                       }
-                               }
+       if (caps)
+               gst_caps_unref(caps);
 
-                               if (!strcmp(structure_name, "prepare-decode-buffers")) {
-                                       gint num_buffers = 0;
-                                       gint extra_num_buffers = 0;
+       if (sinkpad) {
+               gst_object_unref(GST_OBJECT(sinkpad));
+               sinkpad = NULL;
+       }
 
-                                       if (gst_structure_get_int(gst_message_get_structure(msg), "num_buffers", &num_buffers)) {
-                                               player->video_num_buffers = num_buffers;
-                                               LOGD("video_num_buffers : %d", player->video_num_buffers);
-                                       }
+       return;
+}
 
-                                       if (gst_structure_get_int(gst_message_get_structure(msg), "extra_num_buffers", &extra_num_buffers)) {
-                                               player->video_extra_num_buffers = extra_num_buffers;
-                                               LOGD("num_of_vout_extra num buffers : %d", extra_num_buffers);
-                                       }
-                                       break;
-                               }
+static gboolean
+__mmplayer_create_sink_path(mmplayer_t *player, GstElement *selector, mmplayer_track_type_e type)
+{
+       GstPad *srcpad = NULL;
 
-                               if (!strcmp(structure_name, "Language_list")) {
-                                       const GValue *lang_list = NULL;
-                                       lang_list = gst_structure_get_value(gst_message_get_structure(msg), "lang_list");
-                                       if (lang_list != NULL) {
-                                               count = g_list_length((GList *)g_value_get_pointer(lang_list));
-                                               if (count > 1)
-                                                       LOGD("Total audio tracks(from parser) = %d \n", count);
-                                       }
-                               }
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, FALSE);
 
-                               if (!strcmp(structure_name, "Ext_Sub_Language_List")) {
-                                       const GValue *lang_list = NULL;
-                                       MMPlayerLangStruct *temp = NULL;
-
-                                       lang_list = gst_structure_get_value(gst_message_get_structure(msg), "lang_list");
-                                       if (lang_list != NULL) {
-                                               count = g_list_length((GList *)g_value_get_pointer(lang_list));
-                                               if (count) {
-                                                       MMPLAYER_SUBTITLE_INFO_LOCK(player);
-                                                       player->subtitle_language_list = (GList *)g_value_get_pointer(lang_list);
-                                                       mm_attrs_set_int_by_name(attrs, "content_text_track_num", (gint)count);
-                                                       if (mmf_attrs_commit(attrs))
-                                                               LOGE("failed to commit.\n");
-                                                       LOGD("Total subtitle tracks = %d \n", count);
-
-                                                       while (count) {
-                                                               temp = g_list_nth_data(player->subtitle_language_list, count - 1);
-                                                               if (temp)
-                                                                       LOGD("value of lang_key is %s and lang_code is %s",
-                                                                                               temp->language_key, temp->language_code);
-                                                               count--;
-                                                       }
-                                                       MMPLAYER_SUBTITLE_INFO_SIGNAL(player);
-                                                       MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
-                                               }
-                                       }
-                               }
+       LOGD("type %d", type);
 
-                               /* custom message */
-                               if (!strcmp(structure_name, "audio_codec_not_supported")) {
-                                       MMMessageParamType msg_param = {0,};
-                                       msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
-                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
-                               }
+       if (!selector) {
+               LOGD("there is no %d track", type);
+               return TRUE;
+       }
 
-                               /* custom message for RTSP attribute :
-                                   RTSP case, buffer is not come from server before PLAYING state. However,we have to get attribute after PAUSE state chaged.
-                                   sdp which has contents info is received when rtsp connection is opened.
-                                   extract duration ,codec info , resolution from sdp and get it by GstMessage */
-                               if (!strcmp(structure_name, "rtspsrc_properties")) {
+       srcpad = gst_element_get_static_pad(selector, "src");
+       if (!srcpad) {
+               LOGE("failed to get srcpad from selector");
+               return FALSE;
+       }
 
-                                       gchar *audio_codec = NULL;
-                                       gchar *video_codec = NULL;
-                                       gchar *video_frame_size = NULL;
+       LOGD("got pad %s:%s from selector", GST_DEBUG_PAD_NAME(srcpad));
 
-                                       gst_structure_get(gst_message_get_structure(msg), "rtsp_duration", G_TYPE_UINT64, &player->duration, NULL);
-                                       LOGD("rtsp duration : %lld msec", GST_TIME_AS_MSECONDS(player->duration));
-                                       player->streaming_type = __mmplayer_get_stream_service_type(player);
-                                       mm_attrs_set_int_by_name(attrs, "content_duration", GST_TIME_AS_MSECONDS(player->duration));
+       __mmplayer_gst_create_sinkbin(selector, srcpad, player);
 
-                                       gst_structure_get(gst_message_get_structure(msg), "rtsp_audio_codec", G_TYPE_STRING, &audio_codec, NULL);
-                                       LOGD("rtsp_audio_codec : %s", audio_codec);
-                                       if (audio_codec)
-                                               mm_attrs_set_string_by_name(player->attrs, "content_audio_codec", audio_codec);
+       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;
+       }
 
-                                       gst_structure_get(gst_message_get_structure(msg), "rtsp_video_codec", G_TYPE_STRING, &video_codec, NULL);
-                                       LOGD("rtsp_video_codec : %s", video_codec);
-                                       if (video_codec)
-                                               mm_attrs_set_string_by_name(player->attrs, "content_video_codec", video_codec);
+       if (srcpad) {
+               gst_object_unref(GST_OBJECT(srcpad));
+               srcpad = NULL;
+       }
 
-                                       gst_structure_get(gst_message_get_structure(msg), "rtsp_video_frame_size", G_TYPE_STRING, &video_frame_size, NULL);
-                                       LOGD("rtsp_video_frame_size : %s", video_frame_size);
-                                       if (video_frame_size) {
+       MMPLAYER_FLEAVE();
+       return TRUE;
+}
 
-                                               char *seperator = strchr(video_frame_size, '-');
-                                               if (seperator) {
+static void
+__mmplayer_set_decode_track_info(mmplayer_t *player, mmplayer_track_type_e type)
+{
+       MMHandleType attrs = 0;
+       gint active_index = 0;
 
-                                                       char video_width[10] = {0,};
-                                                       int frame_size_len = strlen(video_frame_size);
-                                                       int separtor_len = strlen(seperator);
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player);
 
-                                                       strncpy(video_width, video_frame_size, (frame_size_len - separtor_len));
-                                                       mm_attrs_set_int_by_name(attrs, "content_video_width", atoi(video_width));
+       LOGD("type: %d, the num of track: %d", type, player->selector[type].total_track_num);
 
-                                                       seperator++;
-                                                       mm_attrs_set_int_by_name(attrs, "content_video_height", atoi(seperator));
-                                               }
-                                       }
+       /* change track to active pad */
+       active_index = player->selector[type].active_pad_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;
+               return;
+       }
 
-                                       if (mmf_attrs_commit(attrs))
-                                               LOGE("failed to commit.\n");
-                               }
-                       }
-                       break;
+       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);
 
-       case GST_MESSAGE_DURATION_CHANGED:
-               {
-                       LOGD("GST_MESSAGE_DURATION_CHANGED\n");
-                       if (!__mmplayer_gst_handle_duration(player, msg))
-                               LOGW("failed to update duration");
+                       if (mm_attrs_commit_all(attrs))
+                               LOGW("failed to commit attrs.");
+               } else {
+                       LOGW("cannot get content attribute");
                }
+       }
 
-               break;
-
-       case GST_MESSAGE_ASYNC_START:
-                       LOGD("GST_MESSAGE_ASYNC_START : %s\n", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg)));
-               break;
+       MMPLAYER_FLEAVE();
+       return;
+}
 
-       case GST_MESSAGE_ASYNC_DONE:
-               {
-                       LOGD("GST_MESSAGE_ASYNC_DONE : %s\n", GST_ELEMENT_NAME(GST_MESSAGE_SRC(msg)));
+static gboolean
+__mmplayer_create_audio_sink_path(mmplayer_t *player, GstElement *audio_selector)
+{
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, FALSE);
 
-                       /* we only handle messages from pipeline */
-                       if (msg->src != (GstObject *)player->pipeline->mainbin[MMPLAYER_M_PIPE].gst)
-                               break;
+       if (!audio_selector) {
+               LOGD("there is no audio track, num_dynamic_pad %d", player->num_dynamic_pad);
 
-                       if (player->doing_seek) {
-                               if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PAUSED) {
-                                       player->doing_seek = FALSE;
-                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
-                               } else if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PLAYING) {
-                                       if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
-                                               (player->streamer) &&
-                                               (player->streamer->streaming_buffer_type == BUFFER_TYPE_MUXED) &&
-                                               (player->streamer->is_buffering == FALSE)) {
-                                               GstQuery *query = NULL;
-                                               gboolean busy = FALSE;
-                                               gint percent = 0;
-
-                                               if (player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer) {
-                                                       query = gst_query_new_buffering(GST_FORMAT_PERCENT);
-                                                       if (gst_element_query(player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer, query))
-                                                               gst_query_parse_buffering_percent(query, &busy, &percent);
-                                                       gst_query_unref(query);
-
-                                                       LOGD("buffered percent(%s): %d\n",
-                                                               GST_ELEMENT_NAME(player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffer), percent);
-                                               }
+               /* in case the source is changed, output can be changed. */
+               if ((player->pipeline->audiobin) && (player->pipeline->audiobin[MMPLAYER_A_BIN].gst)) {
+                       LOGD("remove previous audiobin if it exist");
 
-                                               if (percent >= 100) {
-                                                       player->streamer->is_buffering = FALSE;
-                                                       __mmplayer_handle_buffering_message(player);
-                                               }
-                                       }
+                       __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_AUDIOBIN);
+                       __mmplayer_del_sink(player, player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
 
-                                       async_done = TRUE;
-                               }
-                       }
+                       MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->audiobin, MMPLAYER_A_BIN);
+                       MMPLAYER_FREEIF(player->pipeline->audiobin);
                }
-               break;
 
-       #if 0 /* delete unnecessary logs */
-       case GST_MESSAGE_REQUEST_STATE:         LOGD("GST_MESSAGE_REQUEST_STATE\n"); break;
-       case GST_MESSAGE_STEP_START:            LOGD("GST_MESSAGE_STEP_START\n"); break;
-       case GST_MESSAGE_QOS:                           LOGD("GST_MESSAGE_QOS\n"); break;
-       case GST_MESSAGE_PROGRESS:                      LOGD("GST_MESSAGE_PROGRESS\n"); break;
-       case GST_MESSAGE_ANY:                           LOGD("GST_MESSAGE_ANY\n"); break;
-       case GST_MESSAGE_INFO:                          LOGD("GST_MESSAGE_STATE_DIRTY\n"); break;
-       case GST_MESSAGE_STATE_DIRTY:           LOGD("GST_MESSAGE_STATE_DIRTY\n"); break;
-       case GST_MESSAGE_STEP_DONE:                     LOGD("GST_MESSAGE_STEP_DONE\n"); break;
-       case GST_MESSAGE_CLOCK_PROVIDE:         LOGD("GST_MESSAGE_CLOCK_PROVIDE\n"); break;
-       case GST_MESSAGE_STRUCTURE_CHANGE:      LOGD("GST_MESSAGE_STRUCTURE_CHANGE\n"); break;
-       case GST_MESSAGE_STREAM_STATUS:         LOGD("GST_MESSAGE_STREAM_STATUS\n"); break;
-       case GST_MESSAGE_APPLICATION:           LOGD("GST_MESSAGE_APPLICATION\n"); break;
-       case GST_MESSAGE_SEGMENT_START:         LOGD("GST_MESSAGE_SEGMENT_START\n"); break;
-       case GST_MESSAGE_SEGMENT_DONE:          LOGD("GST_MESSAGE_SEGMENT_DONE\n"); break;
-       case GST_MESSAGE_LATENCY:                               LOGD("GST_MESSAGE_LATENCY\n"); break;
-       #endif
+               if (player->num_dynamic_pad == 0) /* FIXME: num_dynamic_pad is only for rtsp? */
+                       __mmplayer_pipeline_complete(NULL, player);
 
-       default:
-               break;
+               return TRUE;
        }
 
-       /* should not call 'gst_message_unref(msg)' */
-       return;
+       /* apply the audio track information */
+       __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)) {
+               LOGE("failed to create audio sink path");
+               return FALSE;
+       }
+
+       MMPLAYER_FLEAVE();
+       return TRUE;
 }
 
 static gboolean
-__mmplayer_gst_handle_duration(mm_player_t* player, GstMessage* msg)
+__mmplayer_create_text_sink_path(mmplayer_t *player, GstElement *text_selector)
 {
-       gint64 bytes = 0;
-
        MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && text_selector, FALSE);
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL(msg, FALSE);
+       if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
+               LOGD("text path is not supproted");
+               return TRUE;
+       }
 
-       if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
-               (msg->src) && (msg->src == (GstObject *)player->pipeline->mainbin[MMPLAYER_M_SRC].gst)) {
-               LOGD("msg src : [%s]", GST_ELEMENT_NAME(GST_ELEMENT_CAST(msg->src)));
+       /* apply the text track information */
+       __mmplayer_set_decode_track_info(player, MM_PLAYER_TRACK_TYPE_TEXT);
 
-               if (gst_element_query_duration(GST_ELEMENT_CAST(msg->src), GST_FORMAT_BYTES, &bytes)) {
-                       LOGD("data total size of http content: %lld", bytes);
-                       player->http_content_size = (bytes > 0) ? (bytes) : (0);
-               }
-       } else
-               /* handling audio clip which has vbr. means duration is keep changing */
-               _mmplayer_update_content_attrs(player, ATTR_DURATION);
+       if (player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num > 0)
+               player->has_closed_caption = TRUE;
 
-       MMPLAYER_FLEAVE();
+       /* create text decode path */
+       player->no_more_pad = TRUE;
 
-       return TRUE;
-}
+       if (!__mmplayer_create_sink_path(player, text_selector, MM_PLAYER_TRACK_TYPE_TEXT)) {
+               LOGE("failed to create text sink path");
+               return FALSE;
+       }
 
-static void __mmplayer_get_metadata_360_from_tags(GstTagList *tags,
-               mm_player_spherical_metadata_t *metadata) {
-       gst_tag_list_get_int(tags, "is_spherical", &metadata->is_spherical);
-       gst_tag_list_get_int(tags, "is_stitched", &metadata->is_stitched);
-       gst_tag_list_get_string(tags, "stitching_software",
-                       &metadata->stitching_software);
-       gst_tag_list_get_string(tags, "projection_type",
-                       &metadata->projection_type_string);
-       gst_tag_list_get_string(tags, "stereo_mode", &metadata->stereo_mode_string);
-       gst_tag_list_get_int(tags, "source_count", &metadata->source_count);
-       gst_tag_list_get_int(tags, "init_view_heading",
-                       &metadata->init_view_heading);
-       gst_tag_list_get_int(tags, "init_view_pitch", &metadata->init_view_pitch);
-       gst_tag_list_get_int(tags, "init_view_roll", &metadata->init_view_roll);
-       gst_tag_list_get_int(tags, "timestamp", &metadata->timestamp);
-       gst_tag_list_get_int(tags, "full_pano_width_pixels",
-                       &metadata->full_pano_width_pixels);
-       gst_tag_list_get_int(tags, "full_pano_height_pixels",
-                       &metadata->full_pano_height_pixels);
-       gst_tag_list_get_int(tags, "cropped_area_image_width",
-                       &metadata->cropped_area_image_width);
-       gst_tag_list_get_int(tags, "cropped_area_image_height",
-                       &metadata->cropped_area_image_height);
-       gst_tag_list_get_int(tags, "cropped_area_left",
-                       &metadata->cropped_area_left);
-       gst_tag_list_get_int(tags, "cropped_area_top", &metadata->cropped_area_top);
-       gst_tag_list_get_int(tags, "ambisonic_type", &metadata->ambisonic_type);
-       gst_tag_list_get_int(tags, "ambisonic_format", &metadata->ambisonic_format);
-       gst_tag_list_get_int(tags, "ambisonic_order", &metadata->ambisonic_order);
+       MMPLAYER_FLEAVE();
+       return TRUE;
 }
 
 static gboolean
-__mmplayer_gst_extract_tag_from_msg(mm_player_t* player, GstMessage* msg)
-{
-
-/* macro for better code readability */
-#define MMPLAYER_UPDATE_TAG_STRING(gsttag, attribute, playertag) \
-if (gst_tag_list_get_string(tag_list, gsttag, &string)) {\
-       if (string != NULL) { \
-               SECURE_LOGD("update tag string : %s\n", string); \
-               if (strlen(string) > MM_MAX_STRING_LENGTH) { \
-                       char *new_string = malloc(MM_MAX_STRING_LENGTH); \
-                       strncpy(new_string, string, MM_MAX_STRING_LENGTH-1); \
-                       new_string[MM_MAX_STRING_LENGTH-1] = '\0'; \
-                       mm_attrs_set_string_by_name(attribute, playertag, new_string); \
-                       g_free(new_string); \
-                       new_string = NULL; \
-               } else { \
-                       mm_attrs_set_string_by_name(attribute, playertag, string); \
-               } \
-               g_free(string); \
-               string = NULL; \
-       } \
-}
-
-#define MMPLAYER_UPDATE_TAG_IMAGE(gsttag, attribute, playertag) \
-do {   \
-       GstSample *sample = NULL;\
-       if (gst_tag_list_get_sample_index(tag_list, gsttag, index, &sample)) {\
-               GstMapInfo info = GST_MAP_INFO_INIT;\
-               buffer = gst_sample_get_buffer(sample);\
-               if (!gst_buffer_map(buffer, &info, GST_MAP_READ)) {\
-                       LOGD("failed to get image data from tag");\
-                       gst_sample_unref(sample);\
-                       return FALSE;\
-               } \
-               SECURE_LOGD("update album cover data : %p, size : %d\n", info.data, info.size);\
-               MMPLAYER_FREEIF(player->album_art);\
-               player->album_art = (gchar *)g_malloc(info.size);\
-               if (player->album_art) {\
-                       memcpy(player->album_art, info.data, info.size);\
-                       mm_attrs_set_data_by_name(attribute, playertag, (void *)player->album_art, info.size);\
-                       if (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) {\
-                               msg_param.data = (void *)player->album_art;\
-                               msg_param.size = info.size;\
-                               MMPLAYER_POST_MSG(player, MM_MESSAGE_IMAGE_BUFFER, &msg_param);\
-                               SECURE_LOGD("post message image buffer data : %p, size : %d\n", info.data, info.size);\
-                       } \
-               } \
-               gst_buffer_unmap(buffer, &info);\
-               gst_sample_unref(sample);\
-       }       \
-} while (0)
-
-#define MMPLAYER_UPDATE_TAG_UINT(gsttag, attribute, playertag) \
-do {   \
-       if (gst_tag_list_get_uint(tag_list, gsttag, &v_uint)) { \
-               if (v_uint) { \
-                       int i = 0; \
-                       gchar *tag_list_str = NULL; \
-                       MMPlayerTrackType track_type = MM_PLAYER_TRACK_TYPE_AUDIO; \
-                       if (strstr(GST_OBJECT_NAME(msg->src), "audio")) \
-                               track_type = MM_PLAYER_TRACK_TYPE_AUDIO; \
-                       else if (strstr(GST_OBJECT_NAME(msg->src), "video")) \
-                               track_type = MM_PLAYER_TRACK_TYPE_VIDEO; \
-                       else \
-                               track_type = MM_PLAYER_TRACK_TYPE_TEXT; \
-                       if (!strncmp(gsttag, GST_TAG_BITRATE, strlen(GST_TAG_BITRATE))) { \
-                               if (track_type == MM_PLAYER_TRACK_TYPE_AUDIO) \
-                                       mm_attrs_set_int_by_name(attribute, "content_audio_bitrate", v_uint); \
-                               player->bitrate[track_type] = v_uint; \
-                               player->total_bitrate = 0; \
-                               for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++) \
-                                       player->total_bitrate += player->bitrate[i]; \
-                               mm_attrs_set_int_by_name(attribute, playertag, player->total_bitrate); \
-                               SECURE_LOGD("update bitrate %d[bps] of stream #%d.\n", v_uint, (int)track_type); \
-                       } else if (!strncmp(gsttag, GST_TAG_MAXIMUM_BITRATE, strlen(GST_TAG_MAXIMUM_BITRATE))) { \
-                               player->maximum_bitrate[track_type] = v_uint; \
-                               player->total_maximum_bitrate = 0; \
-                               for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++) \
-                                       player->total_maximum_bitrate += player->maximum_bitrate[i]; \
-                               mm_attrs_set_int_by_name(attribute, playertag, player->total_maximum_bitrate);\
-                               SECURE_LOGD("update maximum bitrate %d[bps] of stream #%d\n", v_uint, (int)track_type);\
-                       } else { \
-                               mm_attrs_set_int_by_name(attribute, playertag, v_uint); \
-                       } \
-                       v_uint = 0;\
-                       g_free(tag_list_str); \
-               } \
-       } \
-} while (0)
-
-#define MMPLAYER_UPDATE_TAG_DATE(gsttag, attribute, playertag) \
-if (gst_tag_list_get_date(tag_list, gsttag, &date)) {\
-       if (date != NULL) {\
-               string = g_strdup_printf("%d", g_date_get_year(date));\
-               mm_attrs_set_string_by_name(attribute, playertag, string);\
-               SECURE_LOGD("metainfo year : %s\n", string);\
-               MMPLAYER_FREEIF(string);\
-               g_date_free(date);\
-       } \
-}
-
-#define MMPLAYER_UPDATE_TAG_DATE_TIME(gsttag, attribute, playertag) \
-if (gst_tag_list_get_date_time(tag_list, gsttag, &datetime)) {\
-       if (datetime != NULL) {\
-               string = g_strdup_printf("%d", gst_date_time_get_year(datetime));\
-               mm_attrs_set_string_by_name(attribute, playertag, string);\
-               SECURE_LOGD("metainfo year : %s\n", string);\
-               MMPLAYER_FREEIF(string);\
-               gst_date_time_unref(datetime);\
-       } \
-}
-
-#define MMPLAYER_UPDATE_TAG_UINT64(gsttag, attribute, playertag) \
-if (gst_tag_list_get_uint64(tag_list, gsttag, &v_uint64)) {\
-       if (v_uint64) {\
-               /* FIXIT : don't know how to store date */\
-               g_assert(1);\
-               v_uint64 = 0;\
-       } \
-}
-
-#define MMPLAYER_UPDATE_TAG_DOUBLE(gsttag, attribute, playertag) \
-if (gst_tag_list_get_double(tag_list, gsttag, &v_double)) {\
-       if (v_double) {\
-               /* FIXIT : don't know how to store date */\
-               g_assert(1);\
-               v_double = 0;\
-       } \
-}
-
-       /* function start */
-       GstTagList* tag_list = NULL;
+__mmplayer_gst_set_queue2_buffering(mmplayer_t *player)
+{
+       gint64 dur_bytes = 0L;
 
-       MMHandleType attrs = 0;
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+               player->pipeline->mainbin && player->streamer, FALSE);
 
-       char *string = NULL;
-       guint v_uint = 0;
-       GDate *date = NULL;
-       GstDateTime *datetime = NULL;
-       /* album cover */
-       GstBuffer *buffer = NULL;
-       gint index = 0;
-       MMMessageParamType msg_param = {0, };
+       if (!gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
+               LOGE("fail to get duration.");
 
-       /* currently not used. but those are needed for above macro */
-       //guint64 v_uint64 = 0;
-       //gdouble v_double = 0;
+       /* there is no mq, enable use-buffering on queue2 (ex) wav streaming
+        * use file information was already set on Q2 when it was created. */
+       __mm_player_streaming_set_queue2(player->streamer,
+                                       player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst,
+                                       TRUE,                                                           /* use_buffering */
+                                       MUXED_BUFFER_TYPE_MAX,                          /* use previous buffer type setting */
+                                       ((dur_bytes > 0) ? ((guint64)dur_bytes) : 0));
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && msg, FALSE);
+       MMPLAYER_FLEAVE();
+       return TRUE;
+}
 
-       attrs = MMPLAYER_GET_ATTRS(player);
+static void
+__mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data)
+{
+       mmplayer_t *player = NULL;
+       GstElement *video_selector = NULL;
+       GstElement *audio_selector = NULL;
+       GstElement *text_selector = NULL;
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(attrs, FALSE);
-
-       /* get tag list from gst message */
-       gst_message_parse_tag(msg, &tag_list);
-
-       /* store tags to player attributes */
-       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_TITLE, attrs, "tag_title");
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_TITLE_SORTNAME, ?, ?); */
-       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ARTIST, attrs, "tag_artist");
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ARTIST_SORTNAME, ?, ?); */
-       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ALBUM, attrs, "tag_album");
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ALBUM_SORTNAME, ?, ?); */
-       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COMPOSER, attrs, "tag_author");
-       MMPLAYER_UPDATE_TAG_DATE(GST_TAG_DATE, attrs, "tag_date");
-       MMPLAYER_UPDATE_TAG_DATE_TIME(GST_TAG_DATE_TIME, attrs, "tag_date");
-       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_GENRE, attrs, "tag_genre");
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COMMENT, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_EXTENDED_COMMENT, ?, ?); */
-       MMPLAYER_UPDATE_TAG_UINT(GST_TAG_TRACK_NUMBER, attrs, "tag_track_num");
-       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_TRACK_COUNT, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_ALBUM_VOLUME_NUMBER, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_ALBUM_VOLUME_COUNT, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LOCATION, ?, ?); */
-       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_DESCRIPTION, attrs, "tag_description");
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_VERSION, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ISRC, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ORGANIZATION, ?, ?); */
-       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COPYRIGHT, attrs, "tag_copyright");
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_COPYRIGHT_URI, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_CONTACT, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LICENSE, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LICENSE_URI, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_PERFORMER, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_UINT64(GST_TAG_DURATION, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_CODEC, ?, ?); */
-       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_VIDEO_CODEC, attrs, "content_video_codec");
-       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_AUDIO_CODEC, attrs, "content_audio_codec");
-       MMPLAYER_UPDATE_TAG_UINT(GST_TAG_BITRATE, attrs, "content_bitrate");
-       MMPLAYER_UPDATE_TAG_UINT(GST_TAG_MAXIMUM_BITRATE, attrs, "content_max_bitrate");
-       MMPLAYER_UPDATE_TAG_LOCK(player);
-       MMPLAYER_UPDATE_TAG_IMAGE(GST_TAG_IMAGE, attrs, "tag_album_cover");
-       MMPLAYER_UPDATE_TAG_UNLOCK(player);
-       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_NOMINAL_BITRATE, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_MINIMUM_BITRATE, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_SERIAL, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_ENCODER, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_UINT(GST_TAG_ENCODER_VERSION, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_TRACK_GAIN, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_TRACK_PEAK, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_ALBUM_GAIN, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_ALBUM_PEAK, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_REFERENCE_LEVEL, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_STRING(GST_TAG_LANGUAGE_CODE, ?, ?); */
-       /* MMPLAYER_UPDATE_TAG_DOUBLE(GST_TAG_BEATS_PER_MINUTE, ?, ?); */
-       MMPLAYER_UPDATE_TAG_STRING(GST_TAG_IMAGE_ORIENTATION, attrs, "content_video_orientation");
-
-       if (strstr(GST_OBJECT_NAME(msg->src), "demux")) {
-               if (player->video360_metadata.is_spherical == -1) {
-                       __mmplayer_get_metadata_360_from_tags(tag_list, &player->video360_metadata);
-                       mm_attrs_set_int_by_name(attrs, "content_video_is_spherical",
-                                       player->video360_metadata.is_spherical);
-                       if (player->video360_metadata.is_spherical == 1) {
-                               LOGD("This is spherical content for 360 playback.");
-                               player->is_content_spherical = TRUE;
-                       } else {
-                               LOGD("This is not spherical content");
-                               player->is_content_spherical = FALSE;
-                       }
+       MMPLAYER_FENTER();
+       player = (mmplayer_t *)data;
 
-                       if (player->video360_metadata.projection_type_string) {
-                               if (!strcmp(player->video360_metadata.projection_type_string, "equirectangular")) {
-                                       player->video360_metadata.projection_type = VIDEO360_PROJECTION_TYPE_EQUIRECTANGULAR;
-                               } else {
-                                       LOGE("Projection %s: code not implemented.\n", player->video360_metadata.projection_type_string);
-                                       player->is_content_spherical = player->is_video360_enabled = FALSE;
-                               }
-                       }
+       LOGD("no-more-pad signal handling");
 
-                       if (player->video360_metadata.stereo_mode_string) {
-                               if (!strcmp(player->video360_metadata.stereo_mode_string, "mono")) {
-                                       player->video360_metadata.stereo_mode = VIDEO360_MODE_MONOSCOPIC;
-                               } else if (!strcmp(player->video360_metadata.stereo_mode_string, "left-right")) {
-                                       player->video360_metadata.stereo_mode = VIDEO360_MODE_STEREOSCOPIC_LEFT_RIGHT;
-                               } else if (!strcmp(player->video360_metadata.stereo_mode_string, "top-bottom")) {
-                                       player->video360_metadata.stereo_mode = VIDEO360_MODE_STEREOSCOPIC_TOP_BOTTOM;
-                               } else {
-                                       LOGE("Stereo mode %s: code not implemented.\n", player->video360_metadata.stereo_mode_string);
-                                       player->is_content_spherical = player->is_video360_enabled = FALSE;
-                               }
-                       }
+       if ((player->cmd == MMPLAYER_COMMAND_DESTROY) ||
+               (player->cmd == MMPLAYER_COMMAND_UNREALIZE)) {
+               LOGW("player is shutting down");
+               goto EXIT;
+       }
+
+       if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
+               (!player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst) &&
+               (player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst)) {
+               if (!__mmplayer_gst_set_queue2_buffering(player)) {
+                       LOGE("failed to set queue2 buffering");
+                       goto EXIT;
                }
        }
 
-       if (mmf_attrs_commit(attrs))
-               LOGE("failed to commit.\n");
+       video_selector = player->pipeline->mainbin[MMPLAYER_M_V_INPUT_SELECTOR].gst;
+       audio_selector = player->pipeline->mainbin[MMPLAYER_M_A_INPUT_SELECTOR].gst;
+       text_selector = player->pipeline->mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst;
 
-       gst_tag_list_free(tag_list);
+       if (!video_selector && !audio_selector && !text_selector) {
+               LOGW("there is no selector");
+               player->no_more_pad = TRUE;
+               goto EXIT;
+       }
 
-       return TRUE;
-}
+       /* create video path followed by video-select */
+       if (video_selector && !audio_selector && !text_selector)
+               player->no_more_pad = TRUE;
 
-static void
-__mmplayer_gst_rtp_no_more_pads(GstElement *element,  gpointer data)
-{
-       mm_player_t* player = (mm_player_t*) data;
+       if (!__mmplayer_create_sink_path(player, video_selector, MM_PLAYER_TRACK_TYPE_VIDEO))
+               goto EXIT;
 
-       MMPLAYER_FENTER();
+       /* create audio path followed by audio-select */
+       if (audio_selector && !text_selector)
+               player->no_more_pad = TRUE;
 
-       /* NOTE : we can remove fakesink here if there's no rtp_dynamic_pad. because whenever
-         * we connect autoplugging element to the pad which is just added to rtspsrc, we increase
-         * num_dynamic_pad. and this is no-more-pad situation which means no more pad will be added.
-         * So we can say this. if num_dynamic_pad is zero, it must be one of followings
-
-         * [1] audio and video will be dumped with filesink.
-         * [2] autoplugging is done by just using pad caps.
-         * [3] typefinding has happend in audio but audiosink is created already before no-more-pad signal
-         * and the video will be dumped via filesink.
-         */
-       if (player->num_dynamic_pad == 0) {
-               LOGD("it seems pad caps is directely used for autoplugging. removing fakesink now\n");
-
-               if (!__mmplayer_gst_remove_fakesink(player,
-                       &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK]))
-                       /* NOTE : __mmplayer_pipeline_complete() can be called several time. because
-                        * signaling mechanism(pad-added, no-more-pad, new-decoded-pad) from various
-                        * source element are not same. To overcome this situation, this function will called
-                        * several places and several times. Therefore, this is not an error case.
-                        */
-                       return;
-       }
+       if (!__mmplayer_create_audio_sink_path(player, audio_selector))
+               goto EXIT;
 
-       /* create dot before error-return. for debugging */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-no-more-pad");
+       /* create text path followed by text-select */
+       __mmplayer_create_text_sink_path(player, text_selector);
 
-       player->no_more_pad = TRUE;
+EXIT:
+       if (player->gapless.reconfigure) {
+               player->gapless.reconfigure = FALSE;
+               MMPLAYER_PLAYBACK_UNLOCK(player);
+       }
 
        MMPLAYER_FLEAVE();
 }
 
 static gboolean
-__mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink)
+__mmplayer_gst_add_sinkbin_to_pipeline(mmplayer_t *player, GstElement *sinkbin, GstPad *pad, gboolean reusing, gchar *sink_pad_name)
 {
-       GstElement* parent = NULL;
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, FALSE);
-
-       /* if we have no fakesink. this meas we are using decodebin which doesn'
-       t need to add extra fakesink */
-       MMPLAYER_RETURN_VAL_IF_FAIL(fakesink, TRUE);
+       gboolean ret = FALSE;
+       GstElement *pipeline = NULL;
+       GstPad *sinkpad = NULL;
 
-       /* lock */
-       MMPLAYER_FSINK_LOCK(player);
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(sinkbin && pad, FALSE);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, FALSE);
 
-       if (!fakesink->gst)
-               goto ERROR;
+       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
 
-       /* get parent of fakesink */
-       parent = (GstElement*)gst_object_get_parent((GstObject*)fakesink->gst);
-       if (!parent) {
-               LOGD("fakesink already removed\n");
-               goto ERROR;
+       sinkpad = gst_element_get_static_pad(GST_ELEMENT(sinkbin), sink_pad_name);
+       if (!sinkpad) {
+               LOGE("failed to get pad from sinkbin");
+               goto EXIT;
        }
 
-       gst_element_set_locked_state(fakesink->gst, TRUE);
-
-       /* setting the state to NULL never returns async
-        * so no need to wait for completion of state transiton
-        */
-       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(fakesink->gst, GST_STATE_NULL))
-               LOGE("fakesink state change failure!\n");
-               /* FIXIT : should I return here? or try to proceed to next? */
-               /* return FALSE; */
+       if (reusing) {
+               /* link only */
+               if (gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) {
+                       LOGE("failed to link sinkbin for reusing");
+                       goto EXIT; /* exit either pass or fail */
+               }
+       } else {
+               /* warm up */
+               if (gst_element_set_state(sinkbin, GST_STATE_READY) == GST_STATE_CHANGE_FAILURE) {
+                       LOGE("failed to set state(READY) to sinkbin");
+                       goto EXIT;
+               }
 
-       /* remove fakesink from it's parent */
-       if (!gst_bin_remove(GST_BIN(parent), fakesink->gst)) {
-               LOGE("failed to remove fakesink\n");
+               /* add */
+               if (!gst_bin_add(GST_BIN(pipeline), sinkbin)) {
+                       LOGE("failed to add sinkbin to pipeline");
+                       goto EXIT;
+               }
 
-               gst_object_unref(parent);
+               /* link */
+               if (gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) {
+                       LOGE("failed to link %s:%s - %s:%s", GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(sinkpad));
+                       goto EXIT;
+               }
 
-               goto ERROR;
+               /* run */
+               if (gst_element_set_state(sinkbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
+                       LOGE("failed to set state(PAUSED) to sinkbin");
+                       goto EXIT;
+               }
        }
 
-       gst_object_unref(parent);
-
-       LOGD("state-holder removed\n");
-
-       gst_element_set_locked_state(fakesink->gst, FALSE);
+       ret = TRUE;
 
-       MMPLAYER_FSINK_UNLOCK(player);
-       return TRUE;
-
-ERROR:
-       if (fakesink->gst)
-               gst_element_set_locked_state(fakesink->gst, FALSE);
+EXIT:
+       if (sinkpad)
+               gst_object_unref(GST_OBJECT(sinkpad));
+       sinkpad = NULL;
 
-       MMPLAYER_FSINK_UNLOCK(player);
-       return FALSE;
+       MMPLAYER_FLEAVE();
+       return ret;
 }
 
-
 static void
-__mmplayer_gst_rtp_dynamic_pad(GstElement *element, GstPad *pad, gpointer data)
+__mmplayer_gst_create_sinkbin(GstElement *elem, GstPad *pad, gpointer data)
 {
-       GstPad *sinkpad = NULL;
-       GstCaps* caps = NULL;
-       GstElement* new_element = NULL;
-       GstStructure* str = NULL;
-       const gchar* name = NULL;
+       mmplayer_t *player = NULL;
+       GstCaps *caps = NULL;
+       gchar *caps_str = NULL;
+       GstStructure *str = NULL;
+       const gchar *name = NULL;
+       GstElement *sinkbin = NULL;
+       gboolean reusing = FALSE;
+       gboolean caps_ret = TRUE;
+       gchar *sink_pad_name = "sink";
 
-       mm_player_t* player = (mm_player_t*) data;
+       /* check handles */
+       player = (mmplayer_t *)data;
 
        MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(elem && pad);
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && MMPLAYER_GET_ATTRS(player));
 
-       MMPLAYER_RETURN_IF_FAIL(element && pad);
-       MMPLAYER_RETURN_IF_FAIL(player &&
-                                       player->pipeline &&
-                                       player->pipeline->mainbin);
-
-
-       /* payload type is recognizable. increase num_dynamic and wait for sinkbin creation.
-        * num_dynamic_pad will decreased after creating a sinkbin.
-        */
-       player->num_dynamic_pad++;
-       LOGD("stream count inc : %d\n", player->num_dynamic_pad);
+       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
+       if (!caps_ret)
+               goto ERROR;
 
-       caps = gst_pad_query_caps(pad, NULL);
+       caps_str = gst_caps_to_string(caps);
 
-       MMPLAYER_CHECK_NULL(caps);
+       /* LOGD("detected mimetype : %s", name); */
+       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);
+                       }
 
-       /* clear  previous result*/
-       player->have_dynamic_pad = FALSE;
+                       if (__mmplayer_gst_create_audio_sink_bin(player) != MM_ERROR_NONE) {
+                               LOGE("failed to create audiobin. continuing without audio");
+                               goto ERROR;
+                       }
 
-       str = gst_caps_get_structure(caps, 0);
+                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
+                       LOGD("creating audiobin success");
+               } else {
+                       reusing = TRUE;
+                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
+                       LOGD("reusing audiobin");
+                       __mmplayer_update_content_attrs(player, ATTR_AUDIO);
+               }
+       } else if (strstr(name, "video")) {
+               /* 1. zero copy is updated at _decode_pad_added()
+                * 2. NULL surface type is handled in _decode_pad_added() */
+               LOGD("zero copy %d", player->set_mode.video_zc);
+               if (player->pipeline->videobin == NULL) {
+                       int surface_type = 0;
+                       mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
+                       LOGD("display_surface_type (%d)", surface_type);
 
-       if (!str) {
-               LOGE("cannot get structure from caps.\n");
-               goto ERROR;
-       }
+                       if (surface_type == MM_DISPLAY_SURFACE_OVERLAY && player->video_overlay_resource == NULL) {
+                               LOGD("mark video overlay for acquire");
+                               if (mm_resource_manager_mark_for_acquire(player->resource_manager,
+                                               MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY,
+                                               MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
+                                               &player->video_overlay_resource)
+                                               != MM_RESOURCE_MANAGER_ERROR_NONE) {
+                                       LOGE("could not mark video_overlay resource for acquire");
+                                       goto ERROR;
+                               }
+                       }
 
-       name = gst_structure_get_name(str);
-       if (!name) {
-               LOGE("cannot get mimetype from structure.\n");
-               goto ERROR;
-       }
+                       player->interrupted_by_resource = FALSE;
 
-       if (strstr(name, "video")) {
-               gint stype = 0;
-               mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype);
+                       if (mm_resource_manager_commit(player->resource_manager) !=
+                                       MM_RESOURCE_MANAGER_ERROR_NONE) {
+                               LOGE("could not acquire resources for video playing");
+                               goto ERROR;
+                       }
 
-               if (stype == MM_DISPLAY_SURFACE_NULL || stype == MM_DISPLAY_SURFACE_REMOTE) {
-                       if (player->v_stream_caps) {
-                               gst_caps_unref(player->v_stream_caps);
-                               player->v_stream_caps = NULL;
+                       if (__mmplayer_gst_create_video_sink_bin(player, caps, surface_type) != MM_ERROR_NONE) {
+                               LOGE("failed to create videobin. continuing without video");
+                               goto ERROR;
                        }
 
-                       new_element = gst_element_factory_make("fakesink", NULL);
-                       player->num_dynamic_pad--;
-                       goto NEW_ELEMENT;
+                       sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
+                       LOGD("creating videosink bin success");
+               } else {
+                       reusing = TRUE;
+                       sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
+                       LOGD("re-using videobin");
+                       __mmplayer_update_content_attrs(player, ATTR_VIDEO);
                }
-       }
-
-       /* clear  previous result*/
-       player->have_dynamic_pad = FALSE;
+       } else if (strstr(name, "text")) {
+               if (player->pipeline->textbin == NULL) {
+                       if (__mmplayer_gst_create_text_sink_bin(player) != MM_ERROR_NONE) {
+                               LOGE("failed to create text sink bin. continuing without text");
+                               goto ERROR;
+                       }
 
-       if (!__mmplayer_try_to_plug_decodebin(player, pad, caps)) {
-               LOGE("failed to autoplug for caps");
+                       sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
+                       player->textsink_linked  = 1;
+                       LOGD("creating textsink bin success");
+               } else {
+                       if (!player->textsink_linked) {
+                               LOGD("re-using textbin");
+                               reusing = TRUE;
+                               sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
+                               player->textsink_linked  = 1;
+                       } else {
+                               /* linked textbin exist which means that the external subtitle path exist already */
+                               LOGW("ignoring internal subtutle since external subtitle is available");
+                       }
+               }
+               sink_pad_name = "text_sink";
+       } else {
+               LOGW("unknown mime type %s, ignoring it", name);
                goto ERROR;
        }
 
-       /* check if there's dynamic pad*/
-       if (player->have_dynamic_pad) {
-               LOGE("using pad caps assums there's no dynamic pad !\n");
+       if (!__mmplayer_gst_add_sinkbin_to_pipeline(player, sinkbin, pad, reusing, sink_pad_name))
                goto ERROR;
-       }
 
-       gst_caps_unref(caps);
-       caps = NULL;
+       LOGD("[handle: %p] success to create and link sink bin", player);
 
-NEW_ELEMENT:
+       /* FIXIT : we cannot hold callback for 'no-more-pad' signal because signal was emitted in
+        * streaming task. if the task blocked, then buffer will not flow to the next element
+        *(autoplugging element). so this is special hack for streaming. please try to remove it
+        */
+       /* dec stream count. we can remove fakesink if it's zero */
+       if (player->num_dynamic_pad)
+               player->num_dynamic_pad--;
 
-       /* excute new_element if created*/
-       if (new_element) {
-               LOGD("adding new element to pipeline\n");
+       LOGD("no more pads: %d, stream count dec : %d(num of dynamic pad)", player->no_more_pad, player->num_dynamic_pad);
 
-               /* set state to READY before add to bin */
-               MMPLAYER_ELEMENT_SET_STATE(new_element, GST_STATE_READY);
+       if ((player->no_more_pad) && (player->num_dynamic_pad == 0))
+               __mmplayer_pipeline_complete(NULL, player);
 
-               /* add new element to the pipeline */
-               if (FALSE == gst_bin_add(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), new_element)) {
-                       LOGE("failed to add autoplug element to bin\n");
-                       goto ERROR;
-               }
+ERROR:
 
-               /* get pad from element */
-               sinkpad = gst_element_get_static_pad(GST_ELEMENT(new_element), "sink");
-               if (!sinkpad) {
-                       LOGE("failed to get sinkpad from autoplug element\n");
-                       goto ERROR;
-               }
+       MMPLAYER_FREEIF(caps_str);
 
-               /* link it */
-               if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
-                       LOGE("failed to link autoplug element\n");
-                       goto ERROR;
-               }
+       if (caps)
+               gst_caps_unref(caps);
 
-               gst_object_unref(sinkpad);
-               sinkpad = NULL;
+       return;
+}
 
-               /* run. setting PLAYING here since streamming source is live source */
-               MMPLAYER_ELEMENT_SET_STATE(new_element, GST_STATE_PLAYING);
-       }
+static gboolean
+__mmplayer_get_property_value_for_rotation(mmplayer_t *player, int display_angle, int orientation, int *value)
+{
+       int required_angle = 0; /* Angle required for straight view */
+       int rotation_angle = 0;
 
-       if (caps)
-               gst_caps_unref(caps);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+       MMPLAYER_RETURN_VAL_IF_FAIL(value, FALSE);
 
-       MMPLAYER_FLEAVE();
+       /* Counter clockwise */
+       switch (orientation) {
+       case 0:
+               required_angle = 0;
+               break;
+       case 90:
+               required_angle = 270;
+               break;
+       case 180:
+               required_angle = 180;
+               break;
+       case 270:
+               required_angle = 90;
+               break;
+       }
 
-       return;
+       rotation_angle = display_angle + required_angle;
+       if (rotation_angle >= 360)
+               rotation_angle -= 360;
 
-STATE_CHANGE_FAILED:
-ERROR:
-       /* FIXIT : take care if new_element has already added to pipeline */
-       if (new_element)
-               gst_object_unref(GST_OBJECT(new_element));
+       /* chech if supported or not */
+       if (rotation_angle % 90) {
+               LOGD("not supported rotation angle = %d", rotation_angle);
+               return FALSE;
+       }
 
-       if (sinkpad)
-               gst_object_unref(GST_OBJECT(sinkpad));
+       switch (rotation_angle) {
+       case 0:
+               *value = MM_DISPLAY_ROTATION_NONE;
+               break;
+       case 90:
+               *value = MM_DISPLAY_ROTATION_90;
+               break;
+       case 180:
+               *value = MM_DISPLAY_ROTATION_180;
+               break;
+       case 270:
+               *value = MM_DISPLAY_ROTATION_270;
+               break;
+       }
 
-       if (caps)
-               gst_caps_unref(caps);
+       LOGD("setting rotation property value : %d", *value);
 
-       /* FIXIT : how to inform this error to MSL ????? */
-       /* FIXIT : I think we'd better to use g_idle_add() to destroy pipeline and
-        * then post an error to application
-        */
+       return TRUE;
 }
 
-static GstPadProbeReturn
-__mmplayer_gst_selector_blocked(GstPad* pad, GstPadProbeInfo *info, gpointer data)
+int
+__mmplayer_video_param_check_video_sink_bin(mmplayer_t *player)
 {
-       LOGD("pad(%s:%s) is blocked", GST_DEBUG_PAD_NAME(pad));
-       return GST_PAD_PROBE_OK;
+       /* 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;
 }
 
-static GstPadProbeReturn
-__mmplayer_gst_selector_event_probe(GstPad * pad, GstPadProbeInfo * info, gpointer data)
+int
+__mmplayer_get_video_angle(mmplayer_t *player, int *display_angle, int *orientation)
 {
-       GstPadProbeReturn ret = GST_PAD_PROBE_OK;
-       GstEvent *event = GST_PAD_PROBE_INFO_DATA(info);
-       mm_player_t* player = (mm_player_t*)data;
-       GstCaps* caps = NULL;
-       GstStructure* str = NULL;
-       const gchar* name = NULL;
-       MMPlayerTrackType stream_type = MM_PLAYER_TRACK_TYPE_VIDEO;
-
-
-       if (GST_EVENT_IS_DOWNSTREAM(event)) {
-               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)
-                       return ret;
-       } else if (GST_EVENT_IS_UPSTREAM(event)) {
-               if (GST_EVENT_TYPE(event) != GST_EVENT_QOS)
-                       return ret;
-       }
+       int display_rotation = 0;
+       gchar *org_orient = NULL;
+       MMHandleType attrs = MMPLAYER_GET_ATTRS(player);
 
-       caps = gst_pad_query_caps(pad, NULL);
-       if (!caps) {
-               LOGE("failed to get caps from pad[%s:%s]", GST_DEBUG_PAD_NAME(pad));
-               return ret;
+       if (!attrs) {
+               LOGE("cannot get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       str = gst_caps_get_structure(caps, 0);
-       if (!str) {
-               LOGE("failed to get structure from caps");
-               goto ERROR;
-       }
+       if (display_angle) {
+               /* update user roation */
+               mm_attrs_get_int_by_name(attrs, "display_rotation", &display_rotation);
 
-       name = gst_structure_get_name(str);
-       if (!name) {
-               LOGE("failed to get name from str");
-               goto ERROR;
+               /* Counter clockwise */
+               switch (display_rotation) {
+               case MM_DISPLAY_ROTATION_NONE:
+                       *display_angle = 0;
+                       break;
+               case MM_DISPLAY_ROTATION_90:
+                       *display_angle = 90;
+                       break;
+               case MM_DISPLAY_ROTATION_180:
+                       *display_angle = 180;
+                       break;
+               case MM_DISPLAY_ROTATION_270:
+                       *display_angle = 270;
+                       break;
+               default:
+                       LOGW("wrong angle type : %d", display_rotation);
+                       break;
+               }
+               LOGD("check user angle: %d", *display_angle);
        }
 
-       if (strstr(name, "audio")) {
-               stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
-       } else if (strstr(name, "video")) {
-               stream_type = MM_PLAYER_TRACK_TYPE_VIDEO;
-       } else {
-               /* text track is not supportable */
-               LOGE("invalid name %s", name);
-               goto ERROR;
-       }
+       if (orientation) {
+               /* Counter clockwise */
+               mm_attrs_get_string_by_name(attrs, "content_video_orientation", &org_orient);
 
-       switch (GST_EVENT_TYPE(event)) {
-       case GST_EVENT_EOS:
-               {
-                       /* in case of gapless, drop eos event not to send it to sink */
-                       if (player->gapless.reconfigure && !player->msg_posted) {
-                               LOGD("[%d] %s:%s EOS received but will be drop", stream_type, GST_DEBUG_PAD_NAME(pad));
-                               ret = GST_PAD_PROBE_DROP;
-                       }
-                       break;
+               if (org_orient) {
+                       if (!strcmp(org_orient, "rotate-90"))
+                               *orientation = 90;
+                       else if (!strcmp(org_orient, "rotate-180"))
+                               *orientation = 180;
+                       else if (!strcmp(org_orient, "rotate-270"))
+                               *orientation = 270;
+                       else
+                               LOGD("original rotation is %s", org_orient);
+               } else {
+                       LOGD("content_video_orientation get fail");
                }
-       case GST_EVENT_STREAM_START:
-               {
-                       gint64 stop_running_time = 0;
-                       gint64 position_running_time = 0;
-                       gint64 position = 0;
-                       gint idx = 0;
-
-                       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); */
-                                       continue;
-                               }
 
-                               if (GST_CLOCK_TIME_IS_VALID(player->gapless.segment[idx].stop)) {
-                                       stop_running_time =
-                                               gst_segment_to_running_time(&player->gapless.segment[idx],
-                                                               GST_FORMAT_TIME, player->gapless.segment[idx].stop);
-                               } else if (GST_CLOCK_TIME_IS_VALID(player->gapless.segment[idx].duration)) {
-                                       stop_running_time =
-                                               gst_segment_to_running_time(&player->gapless.segment[idx],
-                                                               GST_FORMAT_TIME, player->gapless.segment[idx].duration);
-                               } else {
-                                       LOGD("duration: %"GST_TIME_FORMAT, GST_TIME_ARGS(player->duration));
-                                       stop_running_time =
-                                               gst_segment_to_running_time(&player->gapless.segment[idx],
-                                                               GST_FORMAT_TIME, player->duration);
-                               }
+               LOGD("check orientation: %d", *orientation);
+       }
 
-                               position_running_time =
-                                       gst_segment_to_running_time(&player->gapless.segment[idx],
-                                       GST_FORMAT_TIME, player->gapless.segment[idx].position);
-
-                               LOGD("[type:%d] time info %" GST_TIME_FORMAT " , %"
-                                       GST_TIME_FORMAT" , %" GST_TIME_FORMAT,
-                                       idx,
-                                       GST_TIME_ARGS(stop_running_time),
-                                       GST_TIME_ARGS(position_running_time),
-                                       GST_TIME_ARGS(gst_segment_to_running_time(&player->gapless.segment[idx],
-                                       GST_FORMAT_TIME, player->gapless.segment[idx].start)));
-
-                               position_running_time = MAX(position_running_time, stop_running_time);
-                               position_running_time -= gst_segment_to_running_time(&player->gapless.segment[idx],
-                                                                                               GST_FORMAT_TIME, player->gapless.segment[idx].start);
-                               position_running_time = MAX(0, position_running_time);
-                               position = MAX(position, position_running_time);
-                       }
+       return MM_ERROR_NONE;
+}
 
-                       if (position != 0) {
-                               LOGD("[%d]GST_EVENT_STREAM_START: start_time from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
-                                       stream_type, GST_TIME_ARGS(player->gapless.start_time[stream_type]),
-                                       GST_TIME_ARGS(player->gapless.start_time[stream_type] + position));
+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
+       int display_angle = 0;
+       MMPLAYER_FENTER();
 
-                               player->gapless.start_time[stream_type] += position;
-                       }
-                       break;
-               }
-       case GST_EVENT_FLUSH_STOP:
-               {
-                       LOGD("[%d] GST_EVENT_FLUSH_STOP", stream_type);
-                       gst_segment_init(&player->gapless.segment[stream_type], GST_FORMAT_UNDEFINED);
-                       player->gapless.start_time[stream_type] = 0;
-                       break;
-               }
-       case GST_EVENT_SEGMENT:
-               {
-                       GstSegment segment;
-                       GstEvent *tmpev;
+       /* check video sinkbin is created */
+       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
+               return;
 
-                       LOGD("[%d] GST_EVENT_SEGMENT", stream_type);
-                       gst_event_copy_segment(event, &segment);
+       __mmplayer_get_video_angle(player, &display_angle, &orientations);
 
-                       if (segment.format == GST_FORMAT_TIME) {
-                               LOGD("segment base:%" GST_TIME_FORMAT ", offset:%" GST_TIME_FORMAT
-                                        ", start:%" GST_TIME_FORMAT ", stop: %" GST_TIME_FORMAT
-                                        ", time: %" GST_TIME_FORMAT ", pos: %" GST_TIME_FORMAT ", dur: %" GST_TIME_FORMAT,
-                                       GST_TIME_ARGS(segment.base), GST_TIME_ARGS(segment.offset),
-                                       GST_TIME_ARGS(segment.start), GST_TIME_ARGS(segment.stop),
-                                       GST_TIME_ARGS(segment.time), GST_TIME_ARGS(segment.position), GST_TIME_ARGS(segment.duration));
+       /* get rotation value to set */
+       __mmplayer_get_property_value_for_rotation(player, display_angle, orientations, &rotation_value);
+       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "rotate", rotation_value, NULL);
+       LOGD("set video param : rotate %d", rotation_value);
+}
 
-                               /* keep the all the segment ev to cover the seeking */
-                               gst_segment_copy_into(&segment, &player->gapless.segment[stream_type]);
-                               player->gapless.update_segment[stream_type] = TRUE;
+void
+__mmplayer_video_param_set_display_visible(mmplayer_t *player)
+{
+       MMHandleType attrs = 0;
+       int visible = 0;
+       MMPLAYER_FENTER();
 
-                               if (!player->gapless.running)
-                                       break;
+       /* check video sinkbin is created */
+       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
+               return;
 
-                               player->gapless.segment[stream_type].base = player->gapless.start_time[stream_type];
+       attrs = MMPLAYER_GET_ATTRS(player);
+       MMPLAYER_RETURN_IF_FAIL(attrs);
 
-                               LOGD("[%d] new base: %" GST_TIME_FORMAT, stream_type, GST_TIME_ARGS(player->gapless.segment[stream_type].base));
+       mm_attrs_get_int_by_name(attrs, "display_visible", &visible);
+       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "visible", visible, NULL);
+       LOGD("set video param : visible %d", visible);
+}
 
-                               tmpev = gst_event_new_segment(&player->gapless.segment[stream_type]);
-                               gst_event_set_seqnum(tmpev, gst_event_get_seqnum(event));
-                               gst_event_unref(event);
-                               GST_PAD_PROBE_INFO_DATA(info) = tmpev;
-                       }
-                       break;
-               }
-       case GST_EVENT_QOS:
-               {
-                       gdouble proportion = 0.0;
-                       GstClockTimeDiff diff = 0;
-                       GstClockTime timestamp = 0;
-                       gint64 running_time_diff = -1;
-                       GstQOSType type = 0;
-                       GstEvent *tmpev = NULL;
-
-                       running_time_diff = player->gapless.segment[stream_type].base;
-
-                       if (running_time_diff <= 0) /* don't need to adjust */
-                               break;
-
-                       gst_event_parse_qos(event, &type, &proportion, &diff, &timestamp);
-                       gst_event_unref(event);
-
-                       if (timestamp < running_time_diff) {
-                               LOGW("QOS event from previous group");
-                               ret = GST_PAD_PROBE_DROP;
-                               break;
-                       }
-
-                       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));
-
-                       timestamp -= running_time_diff;
-
-                       /* That case is invalid for QoS events */
-                       if (diff < 0 && -diff > timestamp) {
-                               LOGW("QOS event from previous group");
-                               ret = GST_PAD_PROBE_DROP;
-                               break;
-                       }
-
-                       tmpev = gst_event_new_qos(GST_QOS_TYPE_UNDERFLOW, proportion, diff, timestamp);
-                       GST_PAD_PROBE_INFO_DATA(info) = tmpev;
-
-                       break;
-               }
-       default:
-               break;
-       }
-
-ERROR:
-       if (caps)
-               gst_caps_unref(caps);
-       return ret;
-}
-
-static void
-__mmplayer_gst_decode_pad_added(GstElement *elem, GstPad *pad, gpointer data)
-{
-       mm_player_t* player = NULL;
-       GstElement* pipeline = NULL;
-       GstElement* selector = NULL;
-       GstElement* fakesink = NULL;
-       GstCaps* caps = NULL;
-       GstStructure* str = NULL;
-       const gchar* name = NULL;
-       GstPad* sinkpad = NULL;
-       GstPad* srcpad = NULL;
-       gboolean first_track = FALSE;
-
-       enum MainElementID elemId = MMPLAYER_M_NUM;
-       MMPlayerTrackType stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
-
-       /* check handles */
-       player = (mm_player_t*)data;
-
-       MMPLAYER_RETURN_IF_FAIL(elem && pad);
-       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
-
-       //LOGD("pad-added signal handling\n");
-
-       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
-
-       /* get mimetype from caps */
-       caps = gst_pad_query_caps(pad, NULL);
-       if (!caps) {
-               LOGE("cannot get caps from pad.\n");
-               goto ERROR;
-       }
-
-       str = gst_caps_get_structure(caps, 0);
-       if (!str) {
-               LOGE("cannot get structure from caps.\n");
-               goto ERROR;
-       }
-
-       name = gst_structure_get_name(str);
-       if (!name) {
-               LOGE("cannot get mimetype from structure.\n");
-               goto ERROR;
-       }
-
-       MMPLAYER_LOG_GST_CAPS_TYPE(caps);
-       //LOGD("detected mimetype : %s\n", name);
-
-       if (strstr(name, "video")) {
-               gint stype = 0;
-
-               mm_attrs_set_int_by_name(player->attrs, "content_video_found", TRUE);
-               mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &stype);
-
-               /* don't make video because of not required, and not support multiple track */
-               if (stype == MM_DISPLAY_SURFACE_NULL) {
-                       LOGD("no video sink by null surface");
-
-                       gchar *caps_str = gst_caps_to_string(caps);
-                       if (caps_str && (strstr(caps_str, "ST12") || strstr(caps_str, "SN12") ||
-                               strstr(caps_str, "SN21") || strstr(caps_str, "S420") || strstr(caps_str, "SR32")))
-                               player->set_mode.video_zc = TRUE;
-
-                       MMPLAYER_FREEIF(caps_str);
-
-                       if (player->v_stream_caps) {
-                               gst_caps_unref(player->v_stream_caps);
-                               player->v_stream_caps = NULL;
-                       }
-
-                       LOGD("create fakesink instead of videobin");
-
-                       /* fake sink */
-                       fakesink = gst_element_factory_make("fakesink", NULL);
-                       if (fakesink == NULL) {
-                               LOGE("ERROR : fakesink create error\n");
-                               goto ERROR;
-                       }
-
-                       if (player->ini.set_dump_element_flag)
-                               __mmplayer_add_dump_buffer_probe(player, fakesink);
-
-                       player->video_fakesink = fakesink;
-
-                       /* store it as it's sink element */
-                       __mmplayer_add_sink(player, player->video_fakesink);
-
-                       gst_bin_add(GST_BIN(pipeline), fakesink);
-
-                       // link
-                       sinkpad = gst_element_get_static_pad(fakesink, "sink");
-
-                       if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
-                               LOGW("failed to link fakesink\n");
-                               gst_object_unref(GST_OBJECT(fakesink));
-                               goto ERROR;
-                       }
-
-                       if (stype == MM_DISPLAY_SURFACE_REMOTE) {
-                               MMPLAYER_SIGNAL_CONNECT(player, sinkpad, MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
-                                               "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), player);
-                       }
-
-                       if (player->set_mode.media_packet_video_stream) {
-                               g_object_set(G_OBJECT(fakesink), "signal-handoffs", TRUE, NULL);
-
-                               MMPLAYER_SIGNAL_CONNECT(player,
-                                                                               G_OBJECT(fakesink),
-                                                                               MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
-                                                                               "handoff",
-                                                                               G_CALLBACK(__mmplayer_video_stream_decoded_render_cb),
-                                                                               (gpointer)player);
-
-                               MMPLAYER_SIGNAL_CONNECT(player,
-                                                                               G_OBJECT(fakesink),
-                                                                               MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
-                                                                               "preroll-handoff",
-                                                                               G_CALLBACK(__mmplayer_video_stream_decoded_preroll_cb),
-                                                                               (gpointer)player);
-                       }
-
-                       g_object_set(G_OBJECT(fakesink), "async", TRUE, "sync", TRUE, NULL);
-                       gst_element_set_state(fakesink, GST_STATE_PAUSED);
-                       goto DONE;
-               }
-
-               if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
-                       __mmplayer_gst_decode_callback(elem, pad, player);
-                       goto DONE;
-               }
-
-               LOGD("video selector \n");
-               elemId = MMPLAYER_M_V_INPUT_SELECTOR;
-               stream_type = MM_PLAYER_TRACK_TYPE_VIDEO;
-       } else {
-               if (strstr(name, "audio")) {
-                       gint samplerate = 0;
-                       gint channels = 0;
-
-                       if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
-                               __mmplayer_gst_decode_callback(elem, pad, player);
-                               goto DONE;
-                       }
-
-                       LOGD("audio selector \n");
-                       elemId = MMPLAYER_M_A_INPUT_SELECTOR;
-                       stream_type = MM_PLAYER_TRACK_TYPE_AUDIO;
-
-                       gst_structure_get_int(str, "rate", &samplerate);
-                       gst_structure_get_int(str, "channels", &channels);
-
-                       if ((channels > 0 && samplerate == 0)) {//exclude audio decoding
-                               /* fake sink */
-                               fakesink = gst_element_factory_make("fakesink", NULL);
-                               if (fakesink == NULL) {
-                                       LOGE("ERROR : fakesink create error\n");
-                                       goto ERROR;
-                               }
-
-                               gst_bin_add(GST_BIN(pipeline), fakesink);
-
-                               /* link */
-                               sinkpad = gst_element_get_static_pad(fakesink, "sink");
-
-                               if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
-                                       LOGW("failed to link fakesink\n");
-                                       gst_object_unref(GST_OBJECT(fakesink));
-                                       goto ERROR;
-                               }
-
-                               g_object_set(G_OBJECT(fakesink), "async", TRUE, NULL);
-                               g_object_set(G_OBJECT(fakesink), "sync", TRUE, NULL);
-                               gst_element_set_state(fakesink, GST_STATE_PAUSED);
-
-                               goto DONE;
-                       }
-               } else if (strstr(name, "text")) {
-                       LOGD("text selector \n");
-                       elemId = MMPLAYER_M_T_INPUT_SELECTOR;
-                       stream_type = MM_PLAYER_TRACK_TYPE_TEXT;
-               } else {
-                       LOGE("wrong elem id \n");
-                       goto ERROR;
-               }
-       }
-
-       selector = player->pipeline->mainbin[elemId].gst;
-       if (selector == NULL) {
-               selector = gst_element_factory_make("input-selector", NULL);
-               LOGD("Creating input-selector\n");
-               if (selector == NULL) {
-                       LOGE("ERROR : input-selector create error\n");
-                       goto ERROR;
-               }
-               g_object_set(selector, "sync-streams", TRUE, NULL);
-
-               player->pipeline->mainbin[elemId].id = elemId;
-               player->pipeline->mainbin[elemId].gst = selector;
-
-               first_track = TRUE;
-               // player->selector[stream_type].active_pad_index = DEFAULT_TRACK;      // default
-
-               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,
-                       __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,
-                       __mmplayer_gst_selector_event_probe, player, NULL);
-
-               gst_element_set_state(selector, GST_STATE_PAUSED);
-               gst_bin_add(GST_BIN(pipeline), selector);
-       } else
-               LOGD("input-selector is already created.\n");
-
-       // link
-       LOGD("Calling request pad with selector %p \n", selector);
-       sinkpad = gst_element_get_request_pad(selector, "sink_%u");
-
-       LOGD("got pad %s:%s from selector", GST_DEBUG_PAD_NAME(sinkpad));
-
-       if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
-               LOGW("failed to link selector\n");
-               gst_object_unref(GST_OBJECT(selector));
-               goto ERROR;
-       }
-
-       if (first_track) {
-               LOGD("this is first track --> active track \n");
-               g_object_set(selector, "active-pad", sinkpad, NULL);
-       }
-
-       _mmplayer_track_update_info(player, stream_type, sinkpad);
-
-
-DONE:
-ERROR:
-
-       if (caps)
-               gst_caps_unref(caps);
-
-       if (sinkpad) {
-               gst_object_unref(GST_OBJECT(sinkpad));
-               sinkpad = NULL;
-       }
-
-       if (srcpad) {
-               gst_object_unref(GST_OBJECT(srcpad));
-               srcpad = NULL;
-       }
-
-       return;
-}
-
-static void __mmplayer_handle_text_decode_path(mm_player_t* player, GstElement* text_selector)
+void
+__mmplayer_video_param_set_display_method(mmplayer_t *player)
 {
-       GstPad* srcpad = NULL;
        MMHandleType attrs = 0;
-       gint active_index = 0;
+       int display_method = 0;
+       MMPLAYER_FENTER();
 
-       // [link] input-selector :: textbin
-       srcpad = gst_element_get_static_pad(text_selector, "src");
-       if (!srcpad) {
-               LOGE("failed to get srcpad from selector\n");
+       /* check video sinkbin is created */
+       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
                return;
-       }
-
-       LOGD("got pad %s:%s from text selector\n", GST_DEBUG_PAD_NAME(srcpad));
-
-       active_index = player->selector[MM_PLAYER_TRACK_TYPE_TEXT].active_pad_index;
-       if ((active_index != DEFAULT_TRACK) &&
-               (__mmplayer_change_selector_pad(player, MM_PLAYER_TRACK_TYPE_TEXT, active_index) != MM_ERROR_NONE)) {
-               LOGW("failed to change text track\n");
-               player->selector[MM_PLAYER_TRACK_TYPE_TEXT].active_pad_index = DEFAULT_TRACK;
-       }
-
-       player->no_more_pad = TRUE;
-       __mmplayer_gst_decode_callback(text_selector, srcpad, player);
-
-       LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
-       if (player->selector[MM_PLAYER_TRACK_TYPE_TEXT].block_id) {
-               gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_TEXT].block_id);
-               player->selector[MM_PLAYER_TRACK_TYPE_TEXT].block_id = 0;
-       }
-
-       LOGD("Total text tracks = %d \n", player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num);
-
-       if (player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num > 0)
-               player->has_closed_caption = TRUE;
 
        attrs = MMPLAYER_GET_ATTRS(player);
-       if (attrs) {
-               mm_attrs_set_int_by_name(attrs, "content_text_track_num", (gint)player->selector[MM_PLAYER_TRACK_TYPE_TEXT].total_track_num);
-               if (mmf_attrs_commit(attrs))
-                       LOGE("failed to commit.\n");
-       } else
-               LOGE("cannot get content attribute");
-
-       if (srcpad) {
-               gst_object_unref(GST_OBJECT(srcpad));
-               srcpad = NULL;
-       }
-}
-
-static void
-__mmplayer_gst_deinterleave_pad_added(GstElement *elem, GstPad *pad, gpointer data)
-{
-       mm_player_t* player = (mm_player_t*)data;
-       GstElement* selector = NULL;
-       GstElement* queue = NULL;
-
-       GstPad* srcpad = NULL;
-       GstPad* sinkpad = NULL;
-       GstCaps* caps = NULL;
-       gchar* caps_str = NULL;
-
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
-
-       caps = gst_pad_get_current_caps(pad);
-       caps_str = gst_caps_to_string(caps);
-       LOGD("deinterleave new caps : %s\n", caps_str);
-       MMPLAYER_FREEIF(caps_str);
-       gst_caps_unref(caps);
-
-       if ((queue = __mmplayer_element_create_and_link(player, pad, "queue")) == NULL) {
-               LOGE("ERROR : queue create error\n");
-               goto ERROR;
-       }
-
-       g_object_set(G_OBJECT(queue),
-                               "max-size-buffers", 10,
-                               "max-size-bytes", 0,
-                               "max-size-time", (guint64)0,
-                               NULL);
-
-       selector = player->pipeline->mainbin[MMPLAYER_M_A_SELECTOR].gst;
-
-       if (!selector) {
-               LOGE("there is no audio channel selector.\n");
-               goto ERROR;
-       }
-
-       srcpad = gst_element_get_static_pad(queue, "src");
-       sinkpad = gst_element_get_request_pad(selector, "sink_%u");
-
-       LOGD("link(%s:%s - %s:%s)\n", GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
-
-       if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) {
-               LOGW("failed to link deinterleave - selector\n");
-               goto ERROR;
-       }
-
-       gst_element_set_state(queue, GST_STATE_PAUSED);
-       player->audio_mode.total_track_num++;
-
-ERROR:
-
-       if (srcpad) {
-               gst_object_unref(GST_OBJECT(srcpad));
-               srcpad = NULL;
-       }
-
-       if (sinkpad) {
-               gst_object_unref(GST_OBJECT(sinkpad));
-               sinkpad = NULL;
-       }
-
-       MMPLAYER_FLEAVE();
-       return;
-}
+       MMPLAYER_RETURN_IF_FAIL(attrs);
 
-static void
-__mmplayer_gst_deinterleave_no_more_pads(GstElement *elem, gpointer data)
-{
-       mm_player_t* player = NULL;
-       GstElement* selector = NULL;
-       GstPad* sinkpad = NULL;
-       gint active_index = 0;
-       gchar* change_pad_name = NULL;
-       GstCaps* caps = NULL;   // no need to unref
-       gint default_audio_ch = 0;
-
-       MMPLAYER_FENTER();
-       player = (mm_player_t*) data;
-
-       selector = player->pipeline->mainbin[MMPLAYER_M_A_SELECTOR].gst;
-
-       if (!selector) {
-               LOGE("there is no audio channel selector.\n");
-               goto ERROR;
-       }
-
-       active_index = player->audio_mode.active_pad_index;
-
-       if (active_index != default_audio_ch) {
-               gint audio_ch = default_audio_ch;
-
-               /*To get the new pad from the selector*/
-               change_pad_name = g_strdup_printf("sink%d", active_index);
-               if (change_pad_name != NULL) {
-                       sinkpad = gst_element_get_static_pad(selector, change_pad_name);
-                       if (sinkpad != NULL) {
-                               LOGD("Set Active Pad - %s:%s\n", GST_DEBUG_PAD_NAME(sinkpad));
-                               g_object_set(selector, "active-pad", sinkpad, NULL);
-
-                               audio_ch = active_index;
-
-                               caps = gst_pad_get_current_caps(sinkpad);
-                               MMPLAYER_LOG_GST_CAPS_TYPE(caps);
-
-                               __mmplayer_set_audio_attrs(player, caps);
-                               gst_caps_unref(caps);
-                       }
-                       MMPLAYER_FREEIF(change_pad_name);
-               }
-
-               player->audio_mode.active_pad_index = audio_ch;
-               LOGD("audio LR info(0:stereo) = %d\n", player->audio_mode.active_pad_index);
-       }
-
-ERROR:
-
-       if (sinkpad)
-               gst_object_unref(sinkpad);
-
-       MMPLAYER_FLEAVE();
-       return;
-}
-
-static void
-__mmplayer_gst_build_deinterleave_path(GstElement *elem, GstPad *pad, gpointer data)
-{
-       mm_player_t* player = NULL;
-       MMPlayerGstElement *mainbin = NULL;
-
-       GstElement* tee = NULL;
-       GstElement* stereo_queue = NULL;
-       GstElement* mono_queue = NULL;
-       GstElement* conv = NULL;
-       GstElement* filter = NULL;
-       GstElement* deinterleave = NULL;
-       GstElement* selector = NULL;
-
-       GstPad* srcpad = NULL;
-       GstPad* selector_srcpad = NULL;
-       GstPad* sinkpad = NULL;
-       GstCaps* caps = NULL;
-       gulong block_id = 0;
-
-       MMPLAYER_FENTER();
-
-       /* check handles */
-       player = (mm_player_t*) data;
-
-       MMPLAYER_RETURN_IF_FAIL(elem && pad);
-       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
-
-       mainbin = player->pipeline->mainbin;
-
-       /* tee */
-       if ((tee = __mmplayer_element_create_and_link(player, pad, "tee")) == NULL) {
-               LOGE("ERROR : tee create error\n");
-               goto ERROR;
-       }
-
-       mainbin[MMPLAYER_M_A_TEE].id = MMPLAYER_M_A_TEE;
-       mainbin[MMPLAYER_M_A_TEE].gst = tee;
-
-       gst_element_set_state(tee, GST_STATE_PAUSED);
-
-       /* queue */
-       srcpad = gst_element_get_request_pad(tee, "src_%u");
-       if ((stereo_queue = __mmplayer_element_create_and_link(player, srcpad, "queue")) == NULL) {
-               LOGE("ERROR : stereo queue create error\n");
-               goto ERROR;
-       }
-
-       g_object_set(G_OBJECT(stereo_queue),
-                               "max-size-buffers", 10,
-                               "max-size-bytes", 0,
-                               "max-size-time", (guint64)0,
-                               NULL);
-
-       player->pipeline->mainbin[MMPLAYER_M_A_Q1].id = MMPLAYER_M_A_Q1;
-       player->pipeline->mainbin[MMPLAYER_M_A_Q1].gst = stereo_queue;
-
-       if (srcpad) {
-               gst_object_unref(GST_OBJECT(srcpad));
-               srcpad = NULL;
-       }
-
-       srcpad = gst_element_get_request_pad(tee, "src_%u");
-
-       if ((mono_queue = __mmplayer_element_create_and_link(player, srcpad, "queue")) == NULL) {
-               LOGE("ERROR : mono queue create error\n");
-               goto ERROR;
-       }
-
-       g_object_set(G_OBJECT(mono_queue),
-                               "max-size-buffers", 10,
-                               "max-size-bytes", 0,
-                               "max-size-time", (guint64)0,
-                               NULL);
-
-       player->pipeline->mainbin[MMPLAYER_M_A_Q2].id = MMPLAYER_M_A_Q2;
-       player->pipeline->mainbin[MMPLAYER_M_A_Q2].gst = mono_queue;
-
-       gst_element_set_state(stereo_queue, GST_STATE_PAUSED);
-       gst_element_set_state(mono_queue, GST_STATE_PAUSED);
-
-       /* audioconvert */
-       srcpad = gst_element_get_static_pad(mono_queue, "src");
-       if ((conv = __mmplayer_element_create_and_link(player, srcpad, "audioconvert")) == NULL) {
-               LOGE("ERROR : audioconvert create error\n");
-               goto ERROR;
-       }
-
-       player->pipeline->mainbin[MMPLAYER_M_A_CONV].id = MMPLAYER_M_A_CONV;
-       player->pipeline->mainbin[MMPLAYER_M_A_CONV].gst = conv;
-
-       /* caps filter */
-       if (srcpad) {
-               gst_object_unref(GST_OBJECT(srcpad));
-               srcpad = NULL;
-       }
-       srcpad = gst_element_get_static_pad(conv, "src");
-
-       if ((filter = __mmplayer_element_create_and_link(player, srcpad, "capsfilter")) == NULL) {
-               LOGE("ERROR : capsfilter create error\n");
-               goto ERROR;
-       }
-
-       player->pipeline->mainbin[MMPLAYER_M_A_FILTER].id = MMPLAYER_M_A_FILTER;
-       player->pipeline->mainbin[MMPLAYER_M_A_FILTER].gst = filter;
-
-       caps = gst_caps_from_string("audio/x-raw-int, "
-                               "width = (int) 16, "
-                               "depth = (int) 16, "
-                               "channels = (int) 2");
-
-       g_object_set(GST_ELEMENT(player->pipeline->mainbin[MMPLAYER_M_A_FILTER].gst), "caps", caps, NULL);
-       gst_caps_unref(caps);
-
-       gst_element_set_state(conv, GST_STATE_PAUSED);
-       gst_element_set_state(filter, GST_STATE_PAUSED);
-
-       /* deinterleave */
-       if (srcpad) {
-               gst_object_unref(GST_OBJECT(srcpad));
-               srcpad = NULL;
-       }
-       srcpad = gst_element_get_static_pad(filter, "src");
-
-       if ((deinterleave = __mmplayer_element_create_and_link(player, srcpad, "deinterleave")) == NULL) {
-               LOGE("ERROR : deinterleave create error\n");
-               goto ERROR;
-       }
-
-       g_object_set(deinterleave, "keep-positions", TRUE, NULL);
-
-       MMPLAYER_SIGNAL_CONNECT(player, deinterleave, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
-                                                       G_CALLBACK(__mmplayer_gst_deinterleave_pad_added), player);
-
-       MMPLAYER_SIGNAL_CONNECT(player, deinterleave, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
-                                                       G_CALLBACK(__mmplayer_gst_deinterleave_no_more_pads), player);
-
-       player->pipeline->mainbin[MMPLAYER_M_A_DEINTERLEAVE].id = MMPLAYER_M_A_DEINTERLEAVE;
-       player->pipeline->mainbin[MMPLAYER_M_A_DEINTERLEAVE].gst = deinterleave;
-
-       /* selector */
-       selector = gst_element_factory_make("input-selector", "audio-channel-selector");
-       if (selector == NULL) {
-               LOGE("ERROR : audio-selector create error\n");
-               goto ERROR;
-       }
-
-       g_object_set(selector, "sync-streams", TRUE, NULL);
-       gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), selector);
-
-       player->pipeline->mainbin[MMPLAYER_M_A_SELECTOR].id = MMPLAYER_M_A_SELECTOR;
-       player->pipeline->mainbin[MMPLAYER_M_A_SELECTOR].gst = selector;
-
-       selector_srcpad = gst_element_get_static_pad(selector, "src");
-
-       LOGD("blocking %s:%s", GST_DEBUG_PAD_NAME(selector_srcpad));
-       block_id =
-               gst_pad_add_probe(selector_srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
-                       __mmplayer_gst_selector_blocked, NULL, NULL);
-
-       if (srcpad) {
-               gst_object_unref(GST_OBJECT(srcpad));
-               srcpad = NULL;
-       }
-
-       srcpad = gst_element_get_static_pad(stereo_queue, "src");
-       sinkpad = gst_element_get_request_pad(selector, "sink_%u");
-
-       if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) {
-               LOGW("failed to link queue_stereo - selector\n");
-               goto ERROR;
-       }
-
-       player->audio_mode.total_track_num++;
-
-       g_object_set(selector, "active-pad", sinkpad, NULL);
-       gst_element_set_state(deinterleave, GST_STATE_PAUSED);
-       gst_element_set_state(selector, GST_STATE_PAUSED);
-
-       __mmplayer_gst_decode_callback(selector, selector_srcpad, player);
-
-ERROR:
-
-       LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(selector_srcpad));
-       if (block_id != 0) {
-               gst_pad_remove_probe(selector_srcpad, block_id);
-               block_id = 0;
-       }
-
-       if (sinkpad) {
-               gst_object_unref(GST_OBJECT(sinkpad));
-               sinkpad = NULL;
-       }
-
-       if (srcpad) {
-               gst_object_unref(GST_OBJECT(srcpad));
-               srcpad = NULL;
-       }
-
-       if (selector_srcpad) {
-               gst_object_unref(GST_OBJECT(selector_srcpad));
-               selector_srcpad = NULL;
-       }
-
-       MMPLAYER_FLEAVE();
-       return;
-}
-
-static void
-__mmplayer_gst_decode_no_more_pads(GstElement *elem, gpointer data)
-{
-       mm_player_t* player = NULL;
-       GstPad* srcpad = NULL;
-       GstElement* video_selector = NULL;
-       GstElement* audio_selector = NULL;
-       GstElement* text_selector = NULL;
-       MMHandleType attrs = 0;
-       gint active_index = 0;
-       gint64 dur_bytes = 0L;
-
-       player = (mm_player_t*) data;
-
-       LOGD("no-more-pad signal handling\n");
-
-       if ((player->cmd == MMPLAYER_COMMAND_DESTROY) ||
-               (player->cmd == MMPLAYER_COMMAND_UNREALIZE)) {
-               LOGW("no need to go more");
-
-               if (player->gapless.reconfigure) {
-                       player->gapless.reconfigure = FALSE;
-                       MMPLAYER_PLAYBACK_UNLOCK(player);
-               }
-
-               return;
-       }
-
-       if ((!MMPLAYER_IS_HTTP_PD(player)) &&
-               (MMPLAYER_IS_HTTP_STREAMING(player)) &&
-               (!player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst) &&
-               (player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst)) {
-               #define ESTIMATED_BUFFER_UNIT (1*1024*1024)
-
-               if (NULL == player->streamer) {
-                       LOGW("invalid state for buffering");
-                       goto ERROR;
-               }
-
-               gint init_buffering_time = player->streamer->buffering_req.prebuffer_time;
-               guint buffer_bytes = (guint)(init_buffering_time/1000) * ESTIMATED_BUFFER_UNIT;
-
-               buffer_bytes = MAX(buffer_bytes, player->streamer->buffer_handle[BUFFER_TYPE_MUXED].buffering_bytes);
-               LOGD("[Decodebin2] set use-buffering on Q2(pre buffer time: %d ms, buffer size : %d)\n", init_buffering_time, buffer_bytes);
-
-               init_buffering_time = (init_buffering_time != 0) ? (init_buffering_time) : (player->ini.http_buffering_time);
-
-               if (!gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
-                       LOGE("fail to get duration.\n");
-
-               // enable use-buffering on queue2 instead of multiqueue(ex)audio only streaming
-               // use file information was already set on Q2 when it was created.
-               __mm_player_streaming_set_queue2(player->streamer,
-                                               player->pipeline->mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst,
-                                               TRUE,                                                           // use_buffering
-                                               buffer_bytes,
-                                               init_buffering_time,
-                                               1.0,                                                            // low percent
-                                               player->ini.http_buffering_limit,       // high percent
-                                               MUXED_BUFFER_TYPE_MEM_QUEUE,
-                                               NULL,
-                                               ((dur_bytes > 0) ? ((guint64)dur_bytes) : 0));
-       }
-
-       video_selector = player->pipeline->mainbin[MMPLAYER_M_V_INPUT_SELECTOR].gst;
-       audio_selector = player->pipeline->mainbin[MMPLAYER_M_A_INPUT_SELECTOR].gst;
-       text_selector = player->pipeline->mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst;
-       if (video_selector) {
-               // [link] input-selector :: videobin
-               srcpad = gst_element_get_static_pad(video_selector, "src");
-               if (!srcpad) {
-                       LOGE("failed to get srcpad from video selector\n");
-                       goto ERROR;
-               }
-
-               LOGD("got pad %s:%s from video selector\n", GST_DEBUG_PAD_NAME(srcpad));
-               if (!text_selector && !audio_selector)
-                       player->no_more_pad = TRUE;
-
-               __mmplayer_gst_decode_callback(video_selector, srcpad, player);
-
-               LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
-               if (player->selector[MM_PLAYER_TRACK_TYPE_VIDEO].block_id) {
-                       gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_VIDEO].block_id);
-                       player->selector[MM_PLAYER_TRACK_TYPE_VIDEO].block_id = 0;
-               }
-       }
-
-       if (audio_selector) {
-               active_index = player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index;
-               if ((active_index != DEFAULT_TRACK) &&
-                       (__mmplayer_change_selector_pad(player, MM_PLAYER_TRACK_TYPE_AUDIO, active_index) != MM_ERROR_NONE)) {
-                       LOGW("failed to change audio track\n");
-                       player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].active_pad_index = DEFAULT_TRACK;
-               }
-
-               // [link] input-selector :: audiobin
-               srcpad = gst_element_get_static_pad(audio_selector, "src");
-               if (!srcpad) {
-                       LOGE("failed to get srcpad from selector\n");
-                       goto ERROR;
-               }
-
-               LOGD("got pad %s:%s from selector\n", GST_DEBUG_PAD_NAME(srcpad));
-               if (!text_selector)
-                       player->no_more_pad = TRUE;
-
-               if ((player->use_deinterleave == TRUE) && (player->max_audio_channels >= 2)) {
-                       LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
-                       if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id) {
-                               gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id);
-                               player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id = 0;
-                       }
-
-                       __mmplayer_gst_build_deinterleave_path(audio_selector, srcpad, player);
-               } else {
-                       __mmplayer_gst_decode_callback(audio_selector, srcpad, player);
-
-                       LOGD("unblocking %s:%s", GST_DEBUG_PAD_NAME(srcpad));
-                       if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id) {
-                               gst_pad_remove_probe(srcpad, player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id);
-                               player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].block_id = 0;
-                       }
-               }
-
-               LOGD("Total audio tracks = %d \n", player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num);
-
-               attrs = MMPLAYER_GET_ATTRS(player);
-               if (attrs) {
-                       mm_attrs_set_int_by_name(attrs, "content_audio_track_num", (gint)player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num);
-                       if (mmf_attrs_commit(attrs))
-                               LOGE("failed to commit.\n");
-               } else
-                       LOGE("cannot get content attribute");
-       } else {
-               if ((player->pipeline->audiobin) && (player->pipeline->audiobin[MMPLAYER_A_BIN].gst)) {
-                       LOGD("There is no audio track : remove audiobin");
-
-                       __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_AUDIOBIN);
-                       __mmplayer_del_sink(player, player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
-
-                       MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->audiobin, MMPLAYER_A_BIN);
-                       MMPLAYER_FREEIF(player->pipeline->audiobin);
-               }
-
-               if (player->num_dynamic_pad == 0)
-                       __mmplayer_pipeline_complete(NULL, player);
-       }
-
-       if (!MMPLAYER_IS_MS_BUFF_SRC(player)) {
-               if (text_selector)
-                       __mmplayer_handle_text_decode_path(player, text_selector);
-       }
-
-       MMPLAYER_FLEAVE();
-
-ERROR:
-       if (srcpad) {
-               gst_object_unref(GST_OBJECT(srcpad));
-               srcpad = NULL;
-       }
-
-       if (player->gapless.reconfigure) {
-               player->gapless.reconfigure = FALSE;
-               MMPLAYER_PLAYBACK_UNLOCK(player);
-       }
-}
-
-static void
-__mmplayer_gst_decode_callback(GstElement *elem, GstPad *pad, gpointer data)
-{
-       mm_player_t* player = NULL;
-       MMHandleType attrs = 0;
-       GstElement* pipeline = NULL;
-       GstCaps* caps = NULL;
-       gchar* caps_str = NULL;
-       GstStructure* str = NULL;
-       const gchar* name = NULL;
-       GstPad* sinkpad = NULL;
-       GstElement* sinkbin = NULL;
-       gboolean reusing = FALSE;
-       GstElement *text_selector = NULL;
-
-       /* check handles */
-       player = (mm_player_t*) data;
-
-       MMPLAYER_RETURN_IF_FAIL(elem && pad);
-       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
-
-       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if (!attrs) {
-               LOGE("cannot get content attribute\n");
-               goto ERROR;
-       }
-
-       /* get mimetype from caps */
-       caps = gst_pad_query_caps(pad, NULL);
-       if (!caps) {
-               LOGE("cannot get caps from pad.\n");
-               goto ERROR;
-       }
-       caps_str = gst_caps_to_string(caps);
-
-       str = gst_caps_get_structure(caps, 0);
-       if (!str) {
-               LOGE("cannot get structure from caps.\n");
-               goto ERROR;
-       }
-
-       name = gst_structure_get_name(str);
-       if (!name) {
-               LOGE("cannot get mimetype from structure.\n");
-               goto ERROR;
-       }
-
-       //LOGD("detected mimetype : %s\n", name);
-
-       if (strstr(name, "audio")) {
-               if (player->pipeline->audiobin == NULL) {
-                       if (MM_ERROR_NONE !=  __mmplayer_gst_create_audio_pipeline(player)) {
-                               LOGE("failed to create audiobin. continuing without audio\n");
-                               goto ERROR;
-                       }
-
-                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
-                       LOGD("creating audiosink bin success\n");
-               } else {
-                       reusing = TRUE;
-                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
-                       LOGD("reusing audiobin\n");
-                       _mmplayer_update_content_attrs(player, ATTR_AUDIO);
-               }
-
-               if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num <= 0) // should not update if content have multi audio tracks
-                       mm_attrs_set_int_by_name(attrs, "content_audio_track_num", 1);
-
-               player->audiosink_linked  = 1;
-
-               sinkpad = gst_element_get_static_pad(GST_ELEMENT(sinkbin), "sink");
-               if (!sinkpad) {
-                       LOGE("failed to get pad from sinkbin\n");
-                       goto ERROR;
-               }
-       } else if (strstr(name, "video")) {
-               if (caps_str && (strstr(caps_str, "ST12") || strstr(caps_str, "SN12") ||
-                       strstr(caps_str, "SN21") || strstr(caps_str, "S420") || strstr(caps_str, "SR32")))
-                       player->set_mode.video_zc = TRUE;
-
-               if (player->pipeline->videobin == NULL) {
-                       /* NOTE : not make videobin because application dose not want to play it even though file has video stream. */
-                       /* get video surface type */
-                       int surface_type = 0;
-                       mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
-                       LOGD("display_surface_type(%d)\n", surface_type);
-
-                       if (surface_type == MM_DISPLAY_SURFACE_NULL) {
-                               LOGD("not make videobin because it dose not want\n");
-                               goto ERROR;
-                       }
-
-                       if (surface_type == MM_DISPLAY_SURFACE_OVERLAY) {
-                               /* mark video overlay for acquire */
-                               if (player->video_overlay_resource == NULL) {
-                                       if (mm_resource_manager_mark_for_acquire(player->resource_manager,
-                                                       MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY,
-                                                       MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
-                                                       &player->video_overlay_resource)
-                                                       != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                                               LOGE("could not mark video_overlay resource for acquire\n");
-                                               goto ERROR;
-                                       }
-                               }
-                       }
-
-                       player->interrupted_by_resource = FALSE;
-                       /* acquire resources for video overlay */
-                       if (mm_resource_manager_commit(player->resource_manager) !=
-                                       MM_RESOURCE_MANAGER_ERROR_NONE) {
-                               LOGE("could not acquire resources for video playing\n");
-                               goto ERROR;
-                       }
-
-                       if (MM_ERROR_NONE !=  __mmplayer_gst_create_video_pipeline(player, caps, surface_type)) {
-                               LOGE("failed to create videobin. continuing without video\n");
-                               goto ERROR;
-                       }
-
-                       sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
-                       LOGD("creating videosink bin success\n");
-               } else {
-                       reusing = TRUE;
-                       sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
-                       LOGD("re-using videobin\n");
-                       _mmplayer_update_content_attrs(player, ATTR_VIDEO);
-               }
-
-               player->videosink_linked  = 1;
-
-               sinkpad = gst_element_get_static_pad(GST_ELEMENT(sinkbin), "sink");
-               if (!sinkpad) {
-                       LOGE("failed to get pad from sinkbin\n");
-                       goto ERROR;
-               }
-       } else if (strstr(name, "text")) {
-               if (player->pipeline->textbin == NULL) {
-                       MMPlayerGstElement* mainbin = NULL;
-
-                       if (MM_ERROR_NONE !=  __mmplayer_gst_create_text_sink_bin(player)) {
-                               LOGE("failed to create text sink bin. continuing without text\n");
-                               goto ERROR;
-                       }
-
-                       sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
-                       LOGD("creating textsink bin success\n");
-
-                       /* FIXIT : track number shouldn't be hardcoded */
-                       mm_attrs_set_int_by_name(attrs, "content_text_track_num", 1);
-
-                       player->textsink_linked  = 1;
-                       LOGI("player->textsink_linked set to 1\n");
-
-                       sinkpad = gst_element_get_static_pad(GST_ELEMENT(sinkbin), "text_sink");
-                       if (!sinkpad) {
-                               LOGE("failed to get pad from sinkbin\n");
-                               goto ERROR;
-                       }
-
-                       mainbin = player->pipeline->mainbin;
-
-                       if (!mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst) {
-                               /* input selector */
-                               text_selector = gst_element_factory_make("input-selector", "subtitle_inselector");
-                               if (!text_selector) {
-                                       LOGE("failed to create subtitle input selector element\n");
-                                       goto ERROR;
-                               }
-                               g_object_set(text_selector, "sync-streams", TRUE, NULL);
-
-                               mainbin[MMPLAYER_M_T_INPUT_SELECTOR].id = MMPLAYER_M_T_INPUT_SELECTOR;
-                               mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst = text_selector;
-
-                               /* warm up */
-                               if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(text_selector, GST_STATE_READY)) {
-                                       LOGE("failed to set state(READY) to sinkbin\n");
-                                       goto ERROR;
-                               }
-
-                               if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), text_selector)) {
-                                       LOGW("failed to add subtitle input selector\n");
-                                       goto ERROR;
-                               }
-
-                               LOGD("created element input-selector");
-
-                       } else {
-                               LOGD("already having subtitle input selector");
-                               text_selector = mainbin[MMPLAYER_M_T_INPUT_SELECTOR].gst;
-                       }
-               } else {
-                       if (!player->textsink_linked) {
-                               LOGD("re-using textbin\n");
-
-                               reusing = TRUE;
-                               sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
-
-                               player->textsink_linked  = 1;
-                               LOGI("player->textsink_linked set to 1\n");
-                       } else
-                               LOGD("ignoring internal subtutle since external subtitle is available");
-               }
-       } else {
-               LOGW("unknown type of elementary stream!ignoring it...\n");
-               goto ERROR;
-       }
-
-       if (sinkbin) {
-               if (!reusing) {
-                       /* warm up */
-                       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkbin, GST_STATE_READY)) {
-                               LOGE("failed to set state(READY) to sinkbin\n");
-                               goto ERROR;
-                       }
-
-                       /* Added for multi audio support to avoid adding audio bin again*/
-                       /* add */
-                       if (FALSE == gst_bin_add(GST_BIN(pipeline), sinkbin)) {
-                               LOGE("failed to add sinkbin to pipeline\n");
-                               goto ERROR;
-                       }
-               }
-
-               /* link */
-               if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
-                       LOGE("failed to get pad from sinkbin\n");
-                       goto ERROR;
-               }
-
-               if (!reusing) {
-                       /* run */
-                       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkbin, GST_STATE_PAUSED)) {
-                               LOGE("failed to set state(PAUSED) to sinkbin\n");
-                               goto ERROR;
-                       }
-
-                       if (text_selector) {
-                               if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(text_selector, GST_STATE_PAUSED)) {
-                                       LOGE("failed to set state(PAUSED) to sinkbin\n");
-                                       goto ERROR;
-                               }
-                       }
-               }
-
-               gst_object_unref(sinkpad);
-               sinkpad = NULL;
-       }
-
-       LOGD("[handle: %p] linking sink bin success", player);
-
-       /* FIXIT : we cannot hold callback for 'no-more-pad' signal because signal was emitted in
-        * streaming task. if the task blocked, then buffer will not flow to the next element
-        *(autoplugging element). so this is special hack for streaming. please try to remove it
-        */
-       /* dec stream count. we can remove fakesink if it's zero */
-       if (player->num_dynamic_pad)
-               player->num_dynamic_pad--;
-
-       LOGD("no more pads: %d stream count dec : %d(num of dynamic pad)\n", player->no_more_pad, player->num_dynamic_pad);
-
-       if ((player->no_more_pad) && (player->num_dynamic_pad == 0))
-               __mmplayer_pipeline_complete(NULL, player);
-
-ERROR:
-
-       MMPLAYER_FREEIF(caps_str);
-
-       if (caps)
-               gst_caps_unref(caps);
-
-       if (sinkpad)
-               gst_object_unref(GST_OBJECT(sinkpad));
-
-       /* flusing out new attributes */
-       if (mmf_attrs_commit(attrs))
-               LOGE("failed to comit attributes\n");
-
-       return;
-}
-
-static gboolean
-__mmplayer_get_property_value_for_rotation(mm_player_t* player, int rotation_angle, int *value)
-{
-       int pro_value = 0; // in the case of expection, default will be returned.
-       int dest_angle = rotation_angle;
-       int rotation_type = -1;
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL(value, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL(rotation_angle >= 0, FALSE);
-
-       if (rotation_angle >= 360)
-               dest_angle = rotation_angle - 360;
-
-       /* chech if supported or not */
-       if (dest_angle % 90) {
-               LOGD("not supported rotation angle = %d", rotation_angle);
-               return FALSE;
-       }
-
-       /*
-         * tizenwlsink (A)
-         * custom_convert - none (B)
-         * videoflip - none (C)
-         */
-       if (player->set_mode.video_zc) {
-               if (player->pipeline->videobin[MMPLAYER_V_CONV].gst) // B
-                       rotation_type = ROTATION_USING_CUSTOM;
-               else // A
-                       rotation_type = ROTATION_USING_SINK;
-       } else {
-               int surface_type = 0;
-               rotation_type = ROTATION_USING_FLIP;
-
-               mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
-               LOGD("check display surface type attribute: %d", surface_type);
-
-               if (surface_type == MM_DISPLAY_SURFACE_OVERLAY)
-                       rotation_type = ROTATION_USING_SINK;
-               else
-                       rotation_type = ROTATION_USING_FLIP; //C
-
-               LOGD("using %d type for rotation", rotation_type);
-       }
-
-       /* get property value for setting */
-       switch (rotation_type) {
-       case ROTATION_USING_SINK: // tizenwlsink
-               {
-                       switch (dest_angle) {
-                       case 0:
-                               break;
-                       case 90:
-                               pro_value = 3; // clockwise 90
-                               break;
-                       case 180:
-                               pro_value = 2;
-                               break;
-                       case 270:
-                               pro_value = 1; // counter-clockwise 90
-                               break;
-                       }
-               }
-               break;
-       case ROTATION_USING_CUSTOM:
-               {
-                       gchar *ename = NULL;
-                       ename = GST_OBJECT_NAME(gst_element_get_factory(player->pipeline->videobin[MMPLAYER_V_CONV].gst));
-
-                       if (g_strrstr(ename, "fimcconvert")) {
-                               switch (dest_angle) {
-                               case 0:
-                                       break;
-                               case 90:
-                                       pro_value = 90; // clockwise 90
-                                       break;
-                               case 180:
-                                       pro_value = 180;
-                                       break;
-                               case 270:
-                                       pro_value = 270; // counter-clockwise 90
-                                       break;
-                               }
-                       }
-               }
-               break;
-       case ROTATION_USING_FLIP: // videoflip
-               {
-                               switch (dest_angle) {
-                               case 0:
-                                       break;
-                               case 90:
-                                       pro_value = 1; // clockwise 90
-                                       break;
-                               case 180:
-                                       pro_value = 2;
-                                       break;
-                               case 270:
-                                       pro_value = 3; // counter-clockwise 90
-                                       break;
-                               }
-               }
-               break;
-       }
-
-       LOGD("setting rotation property value : %d, used rotation type : %d", pro_value, rotation_type);
-
-       *value = pro_value;
-
-       return TRUE;
-}
-
-int
-__mmplayer_video_param_check_video_sink_bin(mm_player_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;
-}
-
-void
-__mmplayer_video_param_set_display_rotation(mm_player_t* player)
-{
-       int rotation_value = 0;
-       int org_angle = 0; // current supported angle values are 0, 90, 180, 270
-       int user_angle = 0;
-       MMPLAYER_FENTER();
-
-       /* check video sinkbin is created */
-       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
-               return;
-
-       __mmplayer_get_video_angle(player, &user_angle, &org_angle);
-
-       /* get rotation value to set */
-       __mmplayer_get_property_value_for_rotation(player, org_angle+user_angle, &rotation_value);
-       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "rotate", rotation_value, NULL);
-       LOGD("set video param : rotate %d", rotation_value);
-}
-
-void
-__mmplayer_video_param_set_display_visible(mm_player_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))
-               return;
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       MMPLAYER_RETURN_IF_FAIL(attrs);
-
-       mm_attrs_get_int_by_name(attrs, "display_visible", &visible);
-       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "visible", visible, NULL);
-       LOGD("set video param : visible %d", visible);
-}
-
-void
-__mmplayer_video_param_set_display_method(mm_player_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))
-               return;
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       MMPLAYER_RETURN_IF_FAIL(attrs);
-
-       mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
-       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "display-geometry-method", display_method, NULL);
-       LOGD("set video param : method %d", display_method);
-}
-
-void
-__mmplayer_video_param_set_render_rectangle(mm_player_t* player)
-{
-       MMHandleType attrs = 0;
-       void *handle = NULL;
-       /*set wl_display*/
-       int wl_window_x = 0;
-       int wl_window_y = 0;
-       int wl_window_width = 0;
-       int wl_window_height = 0;
-       MMPLAYER_FENTER();
-
-       /* check video sinkbin is created */
-       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
-               return;
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       MMPLAYER_RETURN_IF_FAIL(attrs);
-
-       mm_attrs_get_data_by_name(attrs, "display_overlay", &handle);
-
-       if (handle) {
-               /*It should be set after setting window*/
-               mm_attrs_get_int_by_name(attrs, "wl_window_render_x", &wl_window_x);
-               mm_attrs_get_int_by_name(attrs, "wl_window_render_y", &wl_window_y);
-               mm_attrs_get_int_by_name(attrs, "wl_window_render_width", &wl_window_width);
-               mm_attrs_get_int_by_name(attrs, "wl_window_render_height", &wl_window_height);
-
-               /* After setting window handle, set render      rectangle */
-               gst_video_overlay_set_render_rectangle(
-                        GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
-                        wl_window_x, wl_window_y, wl_window_width, wl_window_height);
-               LOGD("set video param : render rectangle : x(%d) y(%d) width(%d) height(%d)",
-                       wl_window_x, wl_window_y, wl_window_width, wl_window_height);
-
-       }
-}
-void
-__mmplayer_video_param_set_display_overlay(mm_player_t* player)
-{
-       MMHandleType attrs = 0;
-       void *handle = NULL;
-
-       /* check video sinkbin is created */
-       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
-               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 %p", wl_surface_id, *(int*)handle);
-               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.");
-}
-
-
-int
-__mmplayer_update_wayland_videosink_video_param(mm_player_t* player, char *param_name)
-{
-       bool update_all_param = FALSE;
-       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;
-
-       if (strcmp(player->ini.videosink_element_overlay, "tizenwlsink")) {
-               LOGE("can not find tizenwlsink");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       LOGD("param_name : %s", param_name);
-       if (!g_strcmp0(param_name, "update_all_param"))
-               update_all_param = TRUE;
-
-       if (update_all_param || !g_strcmp0(param_name, "display_overlay"))
-               __mmplayer_video_param_set_display_overlay(player);
-       if (update_all_param || !g_strcmp0(param_name, "display_method"))
-               __mmplayer_video_param_set_display_method(player);
-       if (update_all_param || !g_strcmp0(param_name, "wl_window_render_x"))
-               __mmplayer_video_param_set_render_rectangle(player);
-       if (update_all_param || !g_strcmp0(param_name, "display_visible"))
-               __mmplayer_video_param_set_display_visible(player);
-       if (update_all_param || !g_strcmp0(param_name, "display_rotation"))
-               __mmplayer_video_param_set_display_rotation(player);
-
-       return MM_ERROR_NONE;
-}
-
-int
-_mmplayer_update_video_param(mm_player_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;
-}
-
-int
-_mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
-{
-       gboolean disable_overlay = FALSE;
-       mm_player_t* player = (mm_player_t*) hplayer;
-       int ret = MM_ERROR_NONE;
-
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin &&
-                                                               player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-                                                               MM_ERROR_PLAYER_NO_OP); /* invalid op */
-
-       if (!g_object_class_find_property(G_OBJECT_GET_CLASS(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "disable-overlay")) {
-               LOGW("Display control is not supported");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", &disable_overlay, NULL);
-
-       if (audio_only == (bool)disable_overlay) {
-               LOGE("It's the same with current setting: (%d)", audio_only);
-               return MM_ERROR_NONE;
-       }
-
-       if (audio_only) {
-               LOGE("disable overlay");
-               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", TRUE, NULL);
-
-               /* release overlay resource */
-               if (player->video_overlay_resource != NULL) {
-                       ret = mm_resource_manager_mark_for_release(player->resource_manager,
-                                       player->video_overlay_resource);
-                       if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                               LOGE("failed to mark overlay resource for release, ret(0x%x)\n", ret);
-                               goto ERROR;
-                       }
-                       player->video_overlay_resource = NULL;
-               }
-
-               ret = mm_resource_manager_commit(player->resource_manager);
-               if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                       LOGE("failed to commit acquiring of overlay resource, ret(0x%x)\n", ret);
-                       goto ERROR;
-               }
-       } else {
-               /* mark video overlay for acquire */
-               if (player->video_overlay_resource == NULL) {
-                       ret = mm_resource_manager_mark_for_acquire(player->resource_manager,
-                                       MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY,
-                                       MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
-                                       &player->video_overlay_resource);
-                       if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                               LOGE("could not prepare for video_overlay resource\n");
-                               goto ERROR;
-                       }
-               }
-
-               player->interrupted_by_resource = FALSE;
-               /* acquire resources for video overlay */
-               ret = mm_resource_manager_commit(player->resource_manager);
-               if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                       LOGE("could not acquire resources for video playing\n");
-                       goto ERROR;
-               }
-
-               LOGD("enable overlay");
-               __mmplayer_video_param_set_display_overlay(player);
-               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", FALSE, NULL);
-       }
-
-ERROR:
-       MMPLAYER_FLEAVE();
-       return MM_ERROR_NONE;
-}
-
-int
-_mmplayer_get_audio_only(MMHandleType hplayer, bool *paudio_only)
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       gboolean disable_overlay = FALSE;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(paudio_only, MM_ERROR_INVALID_ARGUMENT);
-       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin &&
-                                                               player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-                                                               MM_ERROR_PLAYER_NO_OP); /* invalid op */
-
-       if (!g_object_class_find_property(G_OBJECT_GET_CLASS(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "disable-overlay")) {
-               LOGW("Display control is not supported");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", &disable_overlay, NULL);
-
-       *paudio_only = (bool)(disable_overlay);
-
-       LOGD("audio_only : %d", *paudio_only);
-
-       MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
-}
-
-static int
-__mmplayer_gst_element_link_bucket(GList* element_bucket)
-{
-       GList* bucket = element_bucket;
-       MMPlayerGstElement* element = NULL;
-       MMPlayerGstElement* prv_element = NULL;
-       gint successful_link_count = 0;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(element_bucket, -1);
-
-       prv_element = (MMPlayerGstElement*)bucket->data;
-       bucket = bucket->next;
-
-       for (; bucket; bucket = bucket->next) {
-               element = (MMPlayerGstElement*)bucket->data;
-
-               if (element && element->gst) {
-                       /* If next element is audio appsrc then make a separate audio pipeline */
-                       if (!strcmp(GST_ELEMENT_NAME(GST_ELEMENT(element->gst)), "audio_appsrc") ||
-                               !strcmp(GST_ELEMENT_NAME(GST_ELEMENT(element->gst)), "subtitle_appsrc")) {
-                               prv_element = element;
-                               continue;
-                       }
-
-                       if (prv_element && prv_element->gst) {
-                               if (gst_element_link(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst))) {
-                                       LOGD("linking [%s] to [%s] success\n",
-                                               GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
-                                               GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
-                                       successful_link_count++;
-                               } else {
-                                       LOGD("linking [%s] to [%s] failed\n",
-                                               GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
-                                               GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
-                                       return -1;
-                               }
-                       }
-               }
-
-               prv_element = element;
-       }
-
-       MMPLAYER_FLEAVE();
-
-       return successful_link_count;
-}
-
-static int
-__mmplayer_gst_element_add_bucket_to_bin(GstBin* bin, GList* element_bucket)
-{
-       GList* bucket = element_bucket;
-       MMPlayerGstElement* element = NULL;
-       int successful_add_count = 0;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(element_bucket, 0);
-       MMPLAYER_RETURN_VAL_IF_FAIL(bin, 0);
-
-       for (; bucket; bucket = bucket->next) {
-               element = (MMPlayerGstElement*)bucket->data;
-
-               if (element && element->gst) {
-                       if (!gst_bin_add(bin, GST_ELEMENT(element->gst))) {
-                               LOGD("__mmplayer_gst_element_link_bucket : Adding element [%s]  to bin [%s] failed\n",
-                                       GST_ELEMENT_NAME(GST_ELEMENT(element->gst)),
-                                       GST_ELEMENT_NAME(GST_ELEMENT(bin)));
-                               return 0;
-                       }
-                       successful_add_count++;
-               }
-       }
-
-       MMPLAYER_FLEAVE();
-
-       return successful_add_count;
-}
-
-static void __mmplayer_gst_caps_notify_cb(GstPad * pad, GParamSpec * unused, gpointer data)
-{
-       mm_player_t* player = (mm_player_t*) data;
-       GstCaps *caps = NULL;
-       GstStructure *str = NULL;
-       const char *name;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_IF_FAIL(pad)
-       MMPLAYER_RETURN_IF_FAIL(unused)
-       MMPLAYER_RETURN_IF_FAIL(data)
-
-       caps = gst_pad_get_current_caps(pad);
-       if (!caps)
-               return;
-
-       str = gst_caps_get_structure(caps, 0);
-       if (!str)
-               goto ERROR;
-
-       name = gst_structure_get_name(str);
-       if (!name)
-               goto ERROR;
-
-       LOGD("name = %s\n", name);
-
-       if (strstr(name, "audio")) {
-               _mmplayer_update_content_attrs(player, ATTR_AUDIO);
-
-               if (player->audio_stream_changed_cb) {
-                       LOGE("call the audio stream changed cb\n");
-                       player->audio_stream_changed_cb(player->audio_stream_changed_cb_user_param);
-               }
-       } else if (strstr(name, "video")) {
-               if ((name = gst_structure_get_string(str, "format")))
-                       player->set_mode.video_zc = name[0] == 'S';
-
-               _mmplayer_update_content_attrs(player, ATTR_VIDEO);
-
-               if (player->video_stream_changed_cb) {
-                       LOGE("call the video stream changed cb\n");
-                       player->video_stream_changed_cb(player->video_stream_changed_cb_user_param);
-               }
-       } else
-               goto ERROR;
-
-ERROR:
-
-       gst_caps_unref(caps);
-
-       MMPLAYER_FLEAVE();
-
-       return;
-}
-
-
-
-/**
- * This function is to create audio pipeline for playing.
- *
- * @param      player          [in]    handle of player
- *
- * @return     This function returns zero on success.
- * @remark
- * @see                __mmplayer_gst_create_midi_pipeline, __mmplayer_gst_create_video_pipeline
- */
-/* macro for code readability. just for sinkbin-creation functions */
-#define MMPLAYER_CREATE_ELEMENT(x_bin, x_id, x_factory, x_name, x_add_bucket, x_player) \
-do {\
-       x_bin[x_id].id = x_id;\
-       x_bin[x_id].gst = gst_element_factory_make(x_factory, x_name);\
-       if (!x_bin[x_id].gst) {\
-               LOGE("failed to create %s \n", x_factory);\
-               goto ERROR;\
-       } else {\
-               if (x_player->ini.set_dump_element_flag)\
-                       __mmplayer_add_dump_buffer_probe(x_player, x_bin[x_id].gst);\
-       } \
-       if (x_add_bucket)\
-               element_bucket = g_list_append(element_bucket, &x_bin[x_id]);\
-} while (0);
-
-static void
-__mmplayer_audio_stream_clear_buffer(mm_player_t* player, gboolean send_all)
-{
-       GList *l = NULL;
-
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player);
-
-       if (player->audio_stream_buff_list) {
-               for (l = g_list_first(player->audio_stream_buff_list); l; l = g_list_next(l)) {
-                       mm_player_audio_stream_buff_t *tmp = (mm_player_audio_stream_buff_t *)l->data;
-                       if (tmp) {
-                               if (send_all) {
-                                       LOGD("[%lld] send remained data.", tmp->channel_mask);
-                                       __mmplayer_audio_stream_send_data(player, tmp);
-                               }
-                               if (tmp->pcm_data)
-                                       g_free(tmp->pcm_data);
-                               g_free(tmp);
-                       }
-               }
-               g_list_free(player->audio_stream_buff_list);
-               player->audio_stream_buff_list = NULL;
-       }
-
-       MMPLAYER_FLEAVE();
-}
-
-static void
-__mmplayer_audio_stream_send_data(mm_player_t* player, mm_player_audio_stream_buff_t *a_buffer)
-{
-       MMPlayerAudioStreamDataType audio_stream = { 0, };
-
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player && player->audio_stream_render_cb_ex);
-
-       audio_stream.bitrate = a_buffer->bitrate;
-       audio_stream.channel = a_buffer->channel;
-       audio_stream.depth = a_buffer->depth;
-       audio_stream.is_little_endian = a_buffer->is_little_endian;
-       audio_stream.channel_mask = a_buffer->channel_mask;
-       audio_stream.data_size = a_buffer->data_size;
-       audio_stream.data = a_buffer->pcm_data;
-
-       /* LOGD("[%lld] send data size:%d, %p", audio_stream.channel_mask, audio_stream.data_size, player->audio_stream_cb_user_param); */
-       player->audio_stream_render_cb_ex(&audio_stream, player->audio_stream_cb_user_param);
-
-       MMPLAYER_FLEAVE();
-}
-
-static void
-__mmplayer_audio_stream_decoded_render_cb(GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data)
-{
-       mm_player_t* player = (mm_player_t*) data;
-
-       gint channel = 0;
-       gint rate = 0;
-       gint depth = 0;
-       gint endianness = 0;
-       guint64 channel_mask = 0;
-       void *a_data = NULL;
-       gint a_size = 0;
-       mm_player_audio_stream_buff_t *a_buffer = NULL;
-       GstMapInfo mapinfo = GST_MAP_INFO_INIT;
-       GList *l = NULL;
-
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player && player->audio_stream_render_cb_ex);
-
-       gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
-       a_data = mapinfo.data;
-       a_size = mapinfo.size;
-
-       GstCaps *caps = gst_pad_get_current_caps(pad);
-       GstStructure *structure = gst_caps_get_structure(caps, 0);
-
-       /* MMPLAYER_LOG_GST_CAPS_TYPE(caps); */
-       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));
-
-       /* In case of the sync is false, use buffer list.              *
-        * The num of buffer list depends on the num of audio channels */
-       if (player->audio_stream_buff_list) {
-               for (l = g_list_first(player->audio_stream_buff_list); l; l = g_list_next(l)) {
-                       mm_player_audio_stream_buff_t *tmp = (mm_player_audio_stream_buff_t *)l->data;
-                       if (tmp) {
-                               if (channel_mask == tmp->channel_mask) {
-                                       /* LOGD("[%lld] total: %d, data: %d, buffer: %d", channel_mask, tmp->data_size, a_size, tmp->buff_size); */
-                                       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;
-                                       } else {
-                                               /* send data to client */
-                                               __mmplayer_audio_stream_send_data(player, tmp);
-
-                                               if (a_size > tmp->buff_size) {
-                                                       LOGD("[%lld] adj buffer size %d -> %d", channel_mask, tmp->buff_size, a_size);
-                                                       tmp->pcm_data = g_realloc(tmp->pcm_data, a_size);
-                                                       if (tmp->pcm_data == NULL) {
-                                                               LOGE("failed to realloc data.");
-                                                               goto DONE;
-                                                       }
-                                                       tmp->buff_size = a_size;
-                                               }
-                                               memset(tmp->pcm_data, 0x00, tmp->buff_size);
-                                               memcpy(tmp->pcm_data, a_data, a_size);
-                                               tmp->data_size = a_size;
-                                       }
-                                       goto DONE;
-                               }
-                       } else {
-                               LOGE("data is empty in list.");
-                               goto DONE;
-                       }
-               }
-       }
-
-       /* create new audio stream data */
-       a_buffer = (mm_player_audio_stream_buff_t*)g_malloc0(sizeof(mm_player_audio_stream_buff_t));
-       if (a_buffer == NULL) {
-               LOGE("failed to alloc data.");
-               goto DONE;
-       }
-       a_buffer->bitrate = rate;
-       a_buffer->channel = channel;
-       a_buffer->depth = depth;
-       a_buffer->is_little_endian = (endianness == 1234 ? 1 : 0);
-       a_buffer->channel_mask = channel_mask;
-       a_buffer->data_size = a_size;
-
-       if (!player->audio_stream_sink_sync) {
-               /* If sync is FALSE, use buffer list to reduce the IPC. */
-               a_buffer->buff_size = (a_size > player->ini.pcm_buffer_size) ? (a_size) : (player->ini.pcm_buffer_size);
-               a_buffer->pcm_data = g_malloc(a_buffer->buff_size);
-               if (a_buffer->pcm_data == NULL) {
-                       LOGE("failed to alloc data.");
-                       g_free(a_buffer);
-                       goto DONE;
-               }
-               memcpy(a_buffer->pcm_data, a_data, a_size);
-               /* LOGD("new [%lld] total:%d buff:%d", channel_mask, a_buffer->data_size, a_buffer->buff_size); */
-               player->audio_stream_buff_list = g_list_append(player->audio_stream_buff_list, a_buffer);
-       } else {
-               /* If sync is TRUE, send data directly. */
-               a_buffer->pcm_data = a_data;
-               __mmplayer_audio_stream_send_data(player, a_buffer);
-               g_free(a_buffer);
-       }
-
-DONE:
-       gst_buffer_unmap(buffer, &mapinfo);
-       MMPLAYER_FLEAVE();
-}
-
-static void
-__mmplayer_gst_audio_deinterleave_pad_added(GstElement *elem, GstPad *pad, gpointer data)
-{
-       mm_player_t* player = (mm_player_t*)data;
-       MMPlayerGstElement* audiobin = player->pipeline->audiobin;
-       GstPad* sinkpad = NULL;
-       GstElement *queue = NULL, *sink = NULL;
-
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
-
-       queue = gst_element_factory_make("queue", NULL);
-       if (queue == NULL) {
-               LOGD("fail make queue\n");
-               goto ERROR;
-       }
-
-       sink = gst_element_factory_make("fakesink", NULL);
-       if (sink == NULL) {
-               LOGD("fail make fakesink\n");
-               goto ERROR;
-       }
-
-       gst_bin_add_many(GST_BIN(audiobin[MMPLAYER_A_BIN].gst), queue, sink, NULL);
-
-       if (!gst_element_link_pads_full(queue, "src", sink, "sink", GST_PAD_LINK_CHECK_NOTHING)) {
-               LOGW("failed to link queue & sink\n");
-               goto ERROR;
-       }
-
-       sinkpad = gst_element_get_static_pad(queue, "sink");
-
-       if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
-               LOGW("failed to link [%s:%s] to queue\n", GST_DEBUG_PAD_NAME(pad));
-               goto ERROR;
-       }
-
-       LOGE("player->audio_stream_sink_sync: %d\n", player->audio_stream_sink_sync);
-
-       gst_object_unref(sinkpad);
-       g_object_set(sink, "sync", player->audio_stream_sink_sync, NULL);
-       g_object_set(sink, "signal-handoffs", TRUE, NULL);
-
-       gst_element_set_state(sink, GST_STATE_PAUSED);
-       gst_element_set_state(queue, GST_STATE_PAUSED);
-
-       MMPLAYER_SIGNAL_CONNECT(player,
-               G_OBJECT(sink),
-               MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
-               "handoff",
-               G_CALLBACK(__mmplayer_audio_stream_decoded_render_cb),
-               (gpointer)player);
-
-       MMPLAYER_FLEAVE();
-       return;
-
-ERROR:
-       LOGE("__mmplayer_gst_audio_deinterleave_pad_added ERROR\n");
-       if (queue) {
-               gst_object_unref(GST_OBJECT(queue));
-               queue = NULL;
-       }
-       if (sink) {
-               gst_object_unref(GST_OBJECT(sink));
-               sink = NULL;
-       }
-       if (sinkpad) {
-               gst_object_unref(GST_OBJECT(sinkpad));
-               sinkpad = NULL;
-       }
-
-       return;
-}
-
-void __mmplayer_gst_set_audiosink_property(mm_player_t* player, MMHandleType attrs)
-{
-       #define MAX_PROPS_LEN 128
-       gint latency_mode = 0;
-       gchar *stream_type = NULL;
-       gchar *latency = NULL;
-       gint stream_id = 0;
-       gchar stream_props[MAX_PROPS_LEN] = {0,};
-       GstStructure *props = NULL;
-
-       /* set volume table
-        * It should be set after player creation through attribute.
-        * But, it can not be changed during playing.
-        */
-       MMPLAYER_FENTER();
-       mm_attrs_get_int_by_name(attrs, "sound_stream_index", &stream_id);
-       mm_attrs_get_string_by_name(attrs, "sound_stream_type", &stream_type);
-
-       if (!stream_type) {
-               LOGE("stream_type is null.\n");
-       } else {
-               if (player->sound.focus_id)
-                       snprintf(stream_props, sizeof(stream_props)-1, "props,media.role=%s, media.parent_id=%d, media.focus_id=%d",
-                                       stream_type, stream_id, player->sound.focus_id);
-               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], focus_id[%d], result[%s].\n",
-                       stream_type, stream_id, player->sound.focus_id, stream_props);
-               gst_structure_free(props);
-       }
-
-       mm_attrs_get_int_by_name(attrs, "sound_latency_mode", &latency_mode);
-
-       switch (latency_mode) {
-       case AUDIO_LATENCY_MODE_LOW:
-               latency = g_strndup("low", 3);
-               break;
-       case AUDIO_LATENCY_MODE_MID:
-               latency = g_strndup("mid", 3);
-               break;
-       case AUDIO_LATENCY_MODE_HIGH:
-               latency = g_strndup("high", 4);
-               break;
-       };
-
-       g_object_set(player->pipeline->audiobin[MMPLAYER_A_SINK].gst,
-                       "latency", latency,
-                       NULL);
-
-       LOGD("audiosink property - latency=%s \n", latency);
-
-       g_free(latency);
-
-       MMPLAYER_FLEAVE();
-}
-
-static int
-__mmplayer_gst_create_audio_pipeline(mm_player_t* player)
-{
-       MMPlayerGstElement* first_element = NULL;
-       MMPlayerGstElement* audiobin = NULL;
-       MMHandleType attrs = 0;
-       GstPad *pad = NULL;
-       GstPad *ghostpad = NULL;
-       GList* element_bucket = NULL;
-       gboolean link_audio_sink_now = TRUE;
-       int i = 0;
-       GstCaps *acaps;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       /* alloc handles */
-       audiobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_A_NUM);
-       if (!audiobin) {
-               LOGE("failed to allocate memory for audiobin\n");
-               return MM_ERROR_PLAYER_NO_FREE_SPACE;
-       }
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-
-       /* create bin */
-       audiobin[MMPLAYER_A_BIN].id = MMPLAYER_A_BIN;
-       audiobin[MMPLAYER_A_BIN].gst = gst_bin_new("audiobin");
-       if (!audiobin[MMPLAYER_A_BIN].gst) {
-               LOGE("failed to create audiobin\n");
-               goto ERROR;
-       }
-
-       /* take it */
-       player->pipeline->audiobin = audiobin;
-
-       player->set_mode.pcm_extraction = __mmplayer_can_extract_pcm(player);
-
-       /* Adding audiotp plugin for reverse trickplay feature */
-//     MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TP, "audiotp", "audio trickplay", TRUE, player);
-
-       /* converter */
-       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audio converter", TRUE, player);
-
-       /* replaygain volume */
-       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RGVOL, "rgvolume", "audio rgvolume", TRUE, player);
-       if (player->sound.rg_enable)
-               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_RGVOL].gst), "enable-rgvolume", TRUE, NULL);
-       else
-               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_RGVOL].gst), "enable-rgvolume", FALSE, NULL);
-
-       /* resampler */
-       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RESAMPLER,  player->ini.audioresampler_element, "audio resampler", TRUE, player);
-
-       if (player->set_mode.pcm_extraction) {
-               // pcm extraction only and no sound output
-               if (player->audio_stream_render_cb_ex) {
-                       char *caps_str = NULL;
-                       GstCaps* caps = NULL;
-                       gchar *format = NULL;
-
-                       /* capsfilter */
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audio capsfilter", TRUE, player);
-
-                       mm_attrs_get_string_by_name(player->attrs, "pcm_audioformat", &format);
-
-                       LOGD("contents : format: %s samplerate : %d pcm_channel: %d", format, player->pcm_samplerate, player->pcm_channel);
-
-                       caps = gst_caps_new_simple("audio/x-raw",
-                                       "format", G_TYPE_STRING, format,
-                                       "rate", G_TYPE_INT, player->pcm_samplerate,
-                                       "channels", G_TYPE_INT, player->pcm_channel,
-                                       NULL);
-                       caps_str = gst_caps_to_string(caps);
-                       LOGD("new caps : %s\n", caps_str);
-
-                       g_object_set(GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL);
-
-                       /* clean */
-                       gst_caps_unref(caps);
-                       MMPLAYER_FREEIF(caps_str);
-
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_DEINTERLEAVE, "deinterleave", "deinterleave", TRUE, player);
-
-                       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_DEINTERLEAVE].gst), "keep-positions", TRUE, NULL);
-                       /* raw pad handling signal */
-                       MMPLAYER_SIGNAL_CONNECT(player,
-                               (audiobin[MMPLAYER_A_DEINTERLEAVE].gst),
-                               MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
-                                                                                               G_CALLBACK(__mmplayer_gst_audio_deinterleave_pad_added), player);
-               } else {
-                       int dst_samplerate = 0;
-                       int dst_channels = 0;
-                       int dst_depth = 0;
-                       char *caps_str = NULL;
-                       GstCaps* caps = NULL;
-
-                       /* get conf. values */
-                       mm_attrs_multiple_get(player->attrs,
-                                               NULL,
-                                               "pcm_extraction_samplerate", &dst_samplerate,
-                                               "pcm_extraction_channels", &dst_channels,
-                                               "pcm_extraction_depth", &dst_depth,
-                                               NULL);
-
-                       /* capsfilter */
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audio capsfilter", TRUE, player);
-                       caps = gst_caps_new_simple("audio/x-raw",
-                                       "rate", G_TYPE_INT, dst_samplerate,
-                                       "channels", G_TYPE_INT, dst_channels,
-                                       "depth", G_TYPE_INT, dst_depth,
-                                       NULL);
-                       caps_str = gst_caps_to_string(caps);
-                       LOGD("new caps : %s\n", caps_str);
-
-                       g_object_set(GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL);
-
-                       /* clean */
-                       gst_caps_unref(caps);
-                       MMPLAYER_FREEIF(caps_str);
-
-                       /* fake sink */
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "fakesink", "fakesink", TRUE, player);
-
-                       /* set sync */
-                       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "sync", FALSE, NULL);
-               }
-       } else {
-               // normal playback
-               //GstCaps* caps = NULL;
-               gint channels = 0;
-
-               /* for logical volume control */
-               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_VOL, "volume", "volume", TRUE, player);
-               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "volume", player->sound.volume, NULL);
-
-               if (player->sound.mute) {
-                       LOGD("mute enabled\n");
-                       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
-               }
-
-#if 0
-               /*capsfilter */
-               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audiocapsfilter", TRUE, player);
-               caps = gst_caps_from_string("audio/x-raw-int, "
-                                       "endianness = (int) LITTLE_ENDIAN, "
-                                       "signed = (boolean) true, "
-                                       "width = (int) 16, "
-                                       "depth = (int) 16");
-               g_object_set(GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL);
-               gst_caps_unref(caps);
-#endif
-
-               /* check if multi-channels */
-               if (player->pipeline->mainbin && player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst) {
-                       GstPad *srcpad = NULL;
-                       GstCaps *caps = NULL;
-
-                       if ((srcpad = gst_element_get_static_pad(player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst, "src"))) {
-                               if ((caps = gst_pad_query_caps(srcpad, NULL))) {
-                                       //MMPLAYER_LOG_GST_CAPS_TYPE(caps);
-                                       GstStructure *str = gst_caps_get_structure(caps, 0);
-                                       if (str)
-                                               gst_structure_get_int(str, "channels", &channels);
-                                       gst_caps_unref(caps);
-                               }
-                               gst_object_unref(srcpad);
-                       }
-               }
-
-               /* audio effect element. if audio effect is enabled */
-               if ((strcmp(player->ini.audioeffect_element, ""))
-                       && (channels <= 2)
-                       && (player->ini.use_audio_effect_preset || player->ini.use_audio_effect_custom)) {
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER, player->ini.audioeffect_element, "audio effect filter", TRUE, player);
-
-                       LOGD("audio effect config. bypass = %d, effect type  = %d", player->bypass_audio_effect, player->audio_effect_info.effect_type);
-
-                       if ((!player->bypass_audio_effect)
-                               && (player->ini.use_audio_effect_preset || player->ini.use_audio_effect_custom)) {
-                               if (MM_AUDIO_EFFECT_TYPE_CUSTOM == player->audio_effect_info.effect_type) {
-                                       if (!_mmplayer_audio_effect_custom_apply(player))
-                                               LOGI("apply audio effect(custom) setting success\n");
-                               }
-                       }
-
-                       if ((strcmp(player->ini.audioeffect_element_custom, ""))
-                               && (player->set_mode.rich_audio))
-                               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER_SEC, player->ini.audioeffect_element_custom, "audio effect filter custom", TRUE, player);
-               }
-
-               /* create audio sink */
-               LOGD("360 spherical %d, channels %d, ambisonic type %d, format %d, order %d",
-                               player->is_content_spherical, channels, player->video360_metadata.ambisonic_type,
-                               player->video360_metadata.ambisonic_format, player->video360_metadata.ambisonic_order);
-
-               /* Note: qtdemux converts audio metadata defaults to openalsink defaults. */
-               if (player->is_360_feature_enabled &&
-                       player->is_content_spherical &&
-                       channels == 4 &&
-                       player->video360_metadata.ambisonic_type == MMFILE_AMBISONIC_TYPE_PERIPHONIC &&
-                       player->video360_metadata.ambisonic_format == MMFILE_AMBISONIC_FORMAT_AMB &&
-                       player->video360_metadata.ambisonic_order == MMFILE_AMBISONIC_ORDER_FOA) {
-
-                       strncpy(player->ini.audiosink_element, "openalsink", PLAYER_INI_MAX_STRLEN - 1);
-
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV_BFORMAT, "audioconvert", "audio-converter-bformat", link_audio_sink_now, player);
-
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_360, "capsfilter", "audio-caps-filter", link_audio_sink_now, player);
-                       acaps = gst_caps_from_string(SPATIAL_AUDIO_CAPS);
-                       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_CAPS_360].gst), "caps", acaps, NULL);
-                       gst_caps_unref(acaps);
-
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "openalsink", "audiosink", link_audio_sink_now, player);
-                       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);
-                       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "stream-info", stream_info, NULL);
-
-                       player->is_openal_plugin_used = TRUE;
-
-                       if (player->video360_yaw_radians <= M_PI &&
-                                       player->video360_yaw_radians >= -M_PI &&
-                                       player->video360_pitch_radians <= M_PI_2 &&
-                                       player->video360_pitch_radians >= -M_PI_2) {
-                               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst),
-                                               "source-orientation-y", (int) (player->video360_yaw_radians * 180.0 / M_PI),
-                                               "source-orientation-x", (int) (player->video360_pitch_radians * 180.0 / M_PI), NULL);
-                       } else if (player->video360_metadata.init_view_heading || player->video360_metadata.init_view_pitch) {
-                               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst),
-                                               "source-orientation-y", player->video360_metadata.init_view_heading,
-                                               "source-orientation-x", player->video360_metadata.init_view_pitch, NULL);
-                       }
-               } else {
-                       if (player->is_360_feature_enabled && player->is_content_spherical)
-                               LOGW("Audio track isn't of the ambisonic type and can't be played back as a spatial sound.\n");
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.audiosink_element, "audiosink", link_audio_sink_now, player);
-               }
-
-               /* qos on */
-               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL);       /* qos on */
-               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "slave-method", GST_AUDIO_BASE_SINK_SLAVE_NONE, NULL);
-
-
-               if ((MMPLAYER_IS_RTSP_STREAMING(player)) ||
-                       (player->videodec_linked && player->ini.use_system_clock)) {
-                       LOGD("system clock will be used.\n");
-                       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "provide-clock", FALSE,  NULL);
-               }
-
-               if (g_strrstr(player->ini.audiosink_element, "pulsesink"))
-                       __mmplayer_gst_set_audiosink_property(player, attrs);
-       }
-
-       if (audiobin[MMPLAYER_A_SINK].gst) {
-               GstPad *sink_pad = NULL;
-               sink_pad = gst_element_get_static_pad(audiobin[MMPLAYER_A_SINK].gst, "sink");
-               MMPLAYER_SIGNAL_CONNECT(player, sink_pad, MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
-                                       "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), player);
-               gst_object_unref(GST_OBJECT(sink_pad));
-       }
-
-       __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst);
-
-       /* adding created elements to bin */
-       LOGD("adding created elements to bin\n");
-       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(audiobin[MMPLAYER_A_BIN].gst), element_bucket)) {
-               LOGE("failed to add elements\n");
-               goto ERROR;
-       }
-
-       /* linking elements in the bucket by added order. */
-       LOGD("Linking elements in the bucket by added order.\n");
-       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1) {
-               LOGE("failed to link elements\n");
-               goto ERROR;
-       }
-
-       /* get first element's sinkpad for creating ghostpad */
-       first_element = (MMPlayerGstElement *)element_bucket->data;
-       if (!first_element) {
-               LOGE("failed to get first elem\n");
-               goto ERROR;
-       }
-
-       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
-       if (!pad) {
-               LOGE("failed to get pad from first element of audiobin\n");
-               goto ERROR;
-       }
-
-       ghostpad = gst_ghost_pad_new("sink", pad);
-       if (!ghostpad) {
-               LOGE("failed to create ghostpad\n");
-               goto ERROR;
-       }
-
-       if (FALSE == gst_element_add_pad(audiobin[MMPLAYER_A_BIN].gst, ghostpad)) {
-               LOGE("failed to add ghostpad to audiobin\n");
-               goto ERROR;
-       }
-
-       gst_object_unref(pad);
-
-       g_list_free(element_bucket);
-       MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
-
-ERROR:
-
-       LOGD("ERROR : releasing audiobin\n");
-
-       if (pad)
-               gst_object_unref(GST_OBJECT(pad));
-
-       if (ghostpad)
-               gst_object_unref(GST_OBJECT(ghostpad));
-
-       if (element_bucket)
-               g_list_free(element_bucket);
-
-       /* release element which are not added to bin */
-       for (i = 1; i < MMPLAYER_A_NUM; i++) {
-               /* NOTE : skip bin */
-               if (audiobin[i].gst) {
-                       GstObject* parent = NULL;
-                       parent = gst_element_get_parent(audiobin[i].gst);
-
-                       if (!parent) {
-                               gst_object_unref(GST_OBJECT(audiobin[i].gst));
-                               audiobin[i].gst = NULL;
-                       } else
-                               gst_object_unref(GST_OBJECT(parent));
-               }
-       }
-
-       /* release audiobin with it's childs */
-       if (audiobin[MMPLAYER_A_BIN].gst)
-               gst_object_unref(GST_OBJECT(audiobin[MMPLAYER_A_BIN].gst));
-
-       MMPLAYER_FREEIF(audiobin);
-
-       player->pipeline->audiobin = NULL;
-
-       return MM_ERROR_PLAYER_INTERNAL;
-}
-
-static GstPadProbeReturn
-__mmplayer_audio_stream_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
-{
-       mm_player_t* player = (mm_player_t*) u_data;
-       GstBuffer *pad_buffer = gst_pad_probe_info_get_buffer(info);
-       GstMapInfo probe_info = GST_MAP_INFO_INIT;
-
-       gst_buffer_map(pad_buffer, &probe_info, GST_MAP_READ);
-
-       if (player->audio_stream_cb && probe_info.size && probe_info.data)
-               player->audio_stream_cb((void *)probe_info.data, probe_info.size, player->audio_stream_cb_user_param);
-
-       return GST_PAD_PROBE_OK;
-}
-
-static guint32 _mmplayer_convert_fourcc_string_to_value(const gchar* format_name)
-{
-       return format_name[0] | (format_name[1] << 8) | (format_name[2] << 16) | (format_name[3] << 24);
-}
-
-int _mmplayer_video_stream_release_bo(mm_player_t* player, void* bo)
-{
-       int ret = MM_ERROR_NONE;
-       GList *l = NULL;
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(bo, MM_ERROR_INVALID_ARGUMENT);
-
-       MMPLAYER_VIDEO_BO_LOCK(player);
-
-       if (player->video_bo_list) {
-               for (l = g_list_first(player->video_bo_list); l; l = g_list_next(l)) {
-                       mm_player_video_bo_info_t* tmp = (mm_player_video_bo_info_t *)l->data;
-                       if (tmp && tmp->bo == bo) {
-                               tmp->using = FALSE;
-                               LOGD("release bo %p", bo);
-                               tbm_bo_unref(tmp->bo);
-                               MMPLAYER_VIDEO_BO_UNLOCK(player);
-                               MMPLAYER_VIDEO_BO_SIGNAL(player);
-                               return ret;
-                       }
-               }
-       } else {
-               /* hw codec is running or the list was reset for DRC. */
-               LOGW("there is no bo list.");
-       }
-       MMPLAYER_VIDEO_BO_UNLOCK(player);
-
-       LOGW("failed to find bo %p", bo);
-       return ret;
-}
-
-static void
-__mmplayer_video_stream_destroy_bo_list(mm_player_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)) {
-                       mm_player_video_bo_info_t* tmp = (mm_player_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);
-               player->video_bo_list = NULL;
-       }
-       player->video_bo_size = 0;
-       MMPLAYER_VIDEO_BO_UNLOCK(player);
-
-       MMPLAYER_FLEAVE();
-       return;
-}
-
-static void*
-__mmplayer_video_stream_get_bo(mm_player_t* player, int size)
-{
-       GList *l = NULL;
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
-       gboolean ret = TRUE;
-
-       /* check DRC, if it is, destroy the prev bo list to create again */
-       if (player->video_bo_size != size) {
-               LOGD("video size is changed: %d -> %d", player->video_bo_size, size);
-               __mmplayer_video_stream_destroy_bo_list(player);
-               player->video_bo_size = size;
-       }
-
-       MMPLAYER_VIDEO_BO_LOCK(player);
-
-       if ((!player->video_bo_list) ||
-               (g_list_length(player->video_bo_list) < player->ini.num_of_video_bo)) {
-
-               /* create bo list */
-               int idx = 0;
-               LOGD("Create bo list for decoded video stream(num:%d)", player->ini.num_of_video_bo);
-
-               if (player->video_bo_list) {
-                       /* if bo list did not created all, try it again. */
-                       idx = g_list_length(player->video_bo_list);
-                       LOGD("bo list exist(len: %d)", idx);
-               }
-
-               for (; idx < player->ini.num_of_video_bo; idx++) {
-                       mm_player_video_bo_info_t* bo_info = g_new(mm_player_video_bo_info_t, 1);
-                       if (!bo_info) {
-                               LOGE("Fail to alloc bo_info.");
-                               break;
-                       }
-                       bo_info->bo = tbm_bo_alloc(player->bufmgr, size, TBM_BO_DEFAULT);
-                       if (!bo_info->bo) {
-                               LOGE("Fail to tbm_bo_alloc.");
-                               g_free(bo_info);
-                               break;
-                       }
-                       bo_info->using = FALSE;
-                       player->video_bo_list = g_list_append(player->video_bo_list, bo_info);
-               }
-
-               /* 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;
+       mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
+       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "display-geometry-method", display_method, NULL);
+       LOGD("set video param : method %d", display_method);
+}
 
-               if (idx == 0) {
-                       MMPLAYER_VIDEO_BO_UNLOCK(player);
-                       return NULL;
-               }
+void
+__mmplayer_video_param_set_video_roi_area(mmplayer_t *player)
+{
+       MMHandleType attrs = 0;
+       void *handle = NULL;
+       MMPLAYER_FENTER();
 
-               LOGD("Num of video buffers(%d/%d)", player->video_num_buffers, player->video_extra_num_buffers);
+       /* check video sinkbin is created */
+       if (__mmplayer_video_param_check_video_sink_bin(player) != MM_ERROR_NONE) {
+               LOGW("There is no video sink");
+               return;
        }
 
-       while (TRUE) {
-               /* get bo from list*/
-               for (l = g_list_first(player->video_bo_list); l; l = g_list_next(l)) {
-                       mm_player_video_bo_info_t* tmp = (mm_player_video_bo_info_t *)l->data;
-                       if (tmp && (tmp->using == FALSE)) {
-                               LOGD("found bo %p to use", tmp->bo);
-                               tmp->using = TRUE;
-                               MMPLAYER_VIDEO_BO_UNLOCK(player);
-                               return tbm_bo_ref(tmp->bo);
-                       }
-               }
-               if (!ret) {
-                       LOGE("failed to get bo in %d timeout", player->ini.video_bo_timeout);
-                       MMPLAYER_VIDEO_BO_UNLOCK(player);
-                       return NULL;
-               }
-
-               if (player->ini.video_bo_timeout <= 0) {
-                       MMPLAYER_VIDEO_BO_WAIT(player);
-               } else {
-                       gint64 timeout = g_get_monotonic_time() + player->ini.video_bo_timeout*G_TIME_SPAN_SECOND;
-                       ret = MMPLAYER_VIDEO_BO_WAIT_UNTIL(player, timeout);
-               }
-               continue;
+       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);
        }
 }
 
-static void
-__mmplayer_video_stream_decoded_preroll_cb(GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data)
+void
+__mmplayer_video_param_set_roi_area(mmplayer_t *player)
 {
-       mm_player_t* player = (mm_player_t*)data;
+       MMHandleType attrs = 0;
+       void *handle = NULL;
+       /*set wl_display*/
+       int win_roi_x = 0;
+       int win_roi_y = 0;
+       int win_roi_width = 0;
+       int win_roi_height = 0;
        MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player && player->video_stream_cb);
 
-       /* send prerolled pkt */
-       player->video_stream_prerolled = FALSE;
+       /* check video sinkbin is created */
+       if (__mmplayer_video_param_check_video_sink_bin(player) != MM_ERROR_NONE) {
+               LOGW("There is no video sink");
+               return;
+       }
 
-       __mmplayer_video_stream_decoded_render_cb(object, buffer, pad, data);
+       attrs = MMPLAYER_GET_ATTRS(player);
+       MMPLAYER_RETURN_IF_FAIL(attrs);
 
-       /* not to send prerolled pkt again */
-       player->video_stream_prerolled = TRUE;
+       mm_attrs_get_data_by_name(attrs, "display_overlay", &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);
+
+               /* 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);
+       }
 }
 
-static void
-__mmplayer_video_stream_decoded_render_cb(GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data)
+void
+__mmplayer_video_param_set_display_overlay(mmplayer_t *player)
 {
-       mm_player_t* player = (mm_player_t*)data;
-       GstCaps *caps = NULL;
-       MMPlayerVideoStreamDataType *stream = NULL;
-       MMVideoBuffer *video_buffer = NULL;
-       GstMemory *dataBlock = NULL;
-       GstMemory *metaBlock = NULL;
-       GstMapInfo mapinfo = GST_MAP_INFO_INIT;
-       GstStructure *structure = NULL;
-       const gchar *string_format = NULL;
-       unsigned int fourcc = 0;
-
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player && player->video_stream_cb);
+       MMHandleType attrs = 0;
+       void *handle = NULL;
 
-       if (player->video_stream_prerolled) {
-               player->video_stream_prerolled = FALSE;
-               LOGD("skip the prerolled pkt not to send it again");
+       /* check video sinkbin is created */
+       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
                return;
-       }
 
-       caps = gst_pad_get_current_caps(pad);
-       if (caps == NULL) {
-               LOGE("Caps is NULL.");
-               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.");
        }
+}
 
-       /* MMPLAYER_LOG_GST_CAPS_TYPE(caps); */
+int
+__mmplayer_update_wayland_videosink_video_param(mmplayer_t *player, char *param_name)
+{
+       gboolean update_all_param = FALSE;
+       MMPLAYER_FENTER();
 
-       /* clear stream data structure */
-       stream = (MMPlayerVideoStreamDataType *)g_malloc0(sizeof(MMPlayerVideoStreamDataType));
-       if (!stream) {
-               LOGE("failed to alloc mem for video data");
-               return;
+       /* check video sinkbin is created */
+       if (MM_ERROR_NONE != __mmplayer_video_param_check_video_sink_bin(player))
+               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+
+       if (strcmp(player->ini.videosink_element_overlay, "tizenwlsink")) {
+               LOGE("can not find tizenwlsink");
+               return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       structure = gst_caps_get_structure(caps, 0);
-       gst_structure_get_int(structure, "width", &(stream->width));
-       gst_structure_get_int(structure, "height", &(stream->height));
-       string_format = gst_structure_get_string(structure, "format");
-       if (string_format)
-               fourcc = _mmplayer_convert_fourcc_string_to_value(string_format);
-       stream->format = util_get_pixtype(fourcc);
-       gst_caps_unref(caps);
-       caps = NULL;
+       LOGD("param_name : %s", param_name);
+       if (!g_strcmp0(param_name, "update_all_param"))
+               update_all_param = TRUE;
 
-       __mmplayer_get_video_angle(player, NULL, &stream->orientation);
+       if (update_all_param || !g_strcmp0(param_name, "display_overlay"))
+               __mmplayer_video_param_set_display_overlay(player);
+       if (update_all_param || !g_strcmp0(param_name, "display_method"))
+               __mmplayer_video_param_set_display_method(player);
+       if (update_all_param || !g_strcmp0(param_name, "display_visible"))
+               __mmplayer_video_param_set_display_visible(player);
+       if (update_all_param || !g_strcmp0(param_name, "display_rotation"))
+               __mmplayer_video_param_set_display_rotation(player);
+       if (update_all_param || !g_strcmp0(param_name, "display_win_roi_x"))
+               __mmplayer_video_param_set_roi_area(player);
+       if (update_all_param)
+               __mmplayer_video_param_set_video_roi_area(player);
 
-    /*
-       LOGD("Call video steramCb, data[%p], Width[%d],Height[%d], Format[%d]",
-               GST_BUFFER_DATA(buffer), stream.width, stream.height, stream.format);
-    */
+       return MM_ERROR_NONE;
+}
 
-       if (stream->width == 0 || stream->height == 0 || stream->format == MM_PIXEL_FORMAT_INVALID) {
-               LOGE("Wrong condition!!");
-               goto ERROR;
+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);
 
-       /* set size and timestamp */
-       dataBlock = gst_buffer_peek_memory(buffer, 0);
-       stream->length_total = gst_memory_get_sizes(dataBlock, NULL, NULL);
-       stream->timestamp = (unsigned int)(GST_BUFFER_PTS(buffer)/1000000); /* nano sec -> mili sec */
+       /* update display surface */
+       mm_attrs_get_int_by_name(attrs, "display_surface_type", &surface_type);
+       LOGD("check display surface type attribute: %d", surface_type);
 
-       /* check zero-copy */
-       if (player->set_mode.video_zc &&
-               player->set_mode.media_packet_video_stream &&
-               gst_buffer_n_memory(buffer) > 1) {
-               metaBlock = gst_buffer_peek_memory(buffer, 1);
-               gst_memory_map(metaBlock, &mapinfo, GST_MAP_READ);
-               video_buffer = (MMVideoBuffer *)mapinfo.data;
-       }
-
-       if (video_buffer) { /* hw codec */
-               /* set tbm bo */
-               if (video_buffer->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) {
-                       int i = 0;
-
-                       /* copy pointer of tbm bo, stride, elevation */
-                       while (i < MM_VIDEO_BUFFER_PLANE_MAX && video_buffer->handle.bo[i]) {
-                               stream->bo[i] = tbm_bo_ref(video_buffer->handle.bo[i]);
-                               i++;
-                       }
-               } else {
-                       LOGE("Not support video buffer format");
-                       goto ERROR;
+       /* 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;
                }
-               memcpy(stream->stride, video_buffer->stride_width,
-                               sizeof(int) * MM_VIDEO_BUFFER_PLANE_MAX);
-               memcpy(stream->elevation, video_buffer->stride_height,
-                               sizeof(int) * MM_VIDEO_BUFFER_PLANE_MAX);
+               break;
+       }
 
-               /* will be released, by calling _mm_player_video_stream_internal_buffer_unref() */
-               stream->internal_buffer = gst_buffer_ref(buffer);
-       } else { /* sw codec */
-               int i = 0;
-               int j = 0;
-               int k = 0;
-               int ret = TBM_SURFACE_ERROR_NONE;
-               int src_stride[MM_PLAYER_IMGB_MPLANE_MAX] = { 0, };
-               int src_offset[MM_PLAYER_IMGB_MPLANE_MAX] = { 0, };
-               int size = 0;
-               unsigned char *src = NULL;
-               unsigned char *dest = NULL;
-               tbm_bo_handle thandle;
-               tbm_surface_h surface;
-               tbm_surface_info_s info;
-               gboolean gst_ret;
+       MMPLAYER_FLEAVE();
 
-               gst_ret = gst_memory_map(dataBlock, &mapinfo, GST_MAP_READWRITE);
-               if (!gst_ret) {
-                       LOGE("fail to gst_memory_map");
-                       goto ERROR;
-               }
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_set_audio_only(MMHandleType hplayer, bool audio_only)
+{
+       gboolean disable_overlay = FALSE;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       int ret = MM_ERROR_NONE;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin &&
+                                                               player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                                               MM_ERROR_PLAYER_NO_OP); /* invalid op */
+
+       if (!g_object_class_find_property(G_OBJECT_GET_CLASS(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "disable-overlay")) {
+               LOGW("Display control is not supported");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
+       g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", &disable_overlay, NULL);
 
-               if (stream->format == MM_PIXEL_FORMAT_I420) {
-                       surface = tbm_surface_create(stream->width, stream->height, TBM_FORMAT_YUV420);
+       if (audio_only == (bool)disable_overlay) {
+               LOGE("It's the same with current setting: (%d)", audio_only);
+               return MM_ERROR_NONE;
+       }
 
-                       ret = tbm_surface_get_info(surface, &info);
+       if (audio_only) {
+               LOGE("disable overlay");
+               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", TRUE, NULL);
 
-                       if (ret != TBM_SURFACE_ERROR_NONE) {
-                               tbm_surface_destroy(surface);
+               /* release overlay resource */
+               if (player->video_overlay_resource != NULL) {
+                       ret = mm_resource_manager_mark_for_release(player->resource_manager,
+                                       player->video_overlay_resource);
+                       if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+                               LOGE("failed to mark overlay resource for release, ret(0x%x)", ret);
                                goto ERROR;
                        }
-                       tbm_surface_destroy(surface);
-
-                       src_stride[0] = GST_ROUND_UP_4(stream->width);
-                       src_stride[1] = src_stride[2] = GST_ROUND_UP_4(stream->width>>1);
-                       src_offset[1] = src_stride[0] * GST_ROUND_UP_2(stream->height);
-                       src_offset[2] = src_offset[1] + (src_stride[1] * (GST_ROUND_UP_2(stream->height)>>1));
-                       stream->stride[0] = info.planes[0].stride;
-                       stream->elevation[0] = info.planes[0].size / info.planes[0].stride;
-                       stream->stride[1] = info.planes[1].stride;
-                       stream->elevation[1] = info.planes[1].size / info.planes[1].stride;
-                       stream->stride[2] = info.planes[2].stride;
-                       stream->elevation[2] = info.planes[2].size / info.planes[2].stride;
-                       size = info.planes[0].size + info.planes[1].size + info.planes[2].size;
-               } else if (stream->format == MM_PIXEL_FORMAT_RGBA) {
-                       stream->stride[0] = stream->width * 4;
-                       stream->elevation[0] = stream->height;
-                       size = stream->stride[0] * stream->height;
-               } else {
-                       LOGE("Not support format %d", stream->format);
-                       goto ERROR;
+                       player->video_overlay_resource = NULL;
                }
 
-               stream->bo[0] = __mmplayer_video_stream_get_bo(player, size);
-               if (!stream->bo[0]) {
-                       LOGE("Fail to tbm_bo_alloc!!");
+               ret = mm_resource_manager_commit(player->resource_manager);
+               if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+                       LOGE("failed to commit acquiring of overlay resource, ret(0x%x)", ret);
                        goto ERROR;
                }
-
-               thandle = tbm_bo_map(stream->bo[0], TBM_DEVICE_CPU, TBM_OPTION_WRITE);
-               if (thandle.ptr && mapinfo.data) {
-                       if (stream->format == MM_PIXEL_FORMAT_I420) {
-                               for (i = 0; i < 3; i++) {
-                                       src = mapinfo.data + src_offset[i];
-                                       dest = thandle.ptr + info.planes[i].offset;
-
-                                       if (i > 0) k = 1;
-                                       for (j = 0; j < stream->height>>k; j++) {
-                                               memcpy(dest, src, stream->width>>k);
-                                               src += src_stride[i];
-                                               dest += stream->stride[i];
-                                       }
-                               }
-                       } else if (stream->format == MM_PIXEL_FORMAT_RGBA) {
-                               memcpy(thandle.ptr, mapinfo.data, size);
-                       } else {
-                               LOGE("Not support format %d", stream->format);
+       } else {
+               /* mark video overlay for acquire */
+               if (player->video_overlay_resource == NULL) {
+                       ret = mm_resource_manager_mark_for_acquire(player->resource_manager,
+                                       MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY,
+                                       MM_RESOURCE_MANAGER_RES_VOLUME_FULL,
+                                       &player->video_overlay_resource);
+                       if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+                               LOGE("could not prepare for video_overlay resource");
                                goto ERROR;
                        }
-               } else {
-                       LOGE("data pointer is wrong. dest : %p, src : %p",
-                                       thandle.ptr, mapinfo.data);
-                       goto ERROR;
                }
-               tbm_bo_unmap(stream->bo[0]);
-       }
 
-       if (player->video_stream_cb) { /* This has been already checked at the entry */
-               if (!player->video_stream_cb(stream, player->video_stream_cb_user_param)) {
-                       LOGE("failed to send video stream data.");
+               player->interrupted_by_resource = FALSE;
+               /* acquire resources for video overlay */
+               ret = mm_resource_manager_commit(player->resource_manager);
+               if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+                       LOGE("could not acquire resources for video playing");
                        goto ERROR;
                }
-       }
-
-       if (metaBlock)
-               gst_memory_unmap(metaBlock, &mapinfo);
-       else
-               gst_memory_unmap(dataBlock, &mapinfo);
-
-       return;
-
-ERROR:
-       LOGE("release video stream resource.");
-       if (metaBlock) {
-               int i = 0;
-               for (i = 0 ; i < MM_VIDEO_BUFFER_PLANE_MAX ; i++) {
-                       if (stream->bo[i])
-                               tbm_bo_unref(stream->bo[i]);
-               }
-               gst_memory_unmap(metaBlock, &mapinfo);
 
-               /* unref gst buffer */
-               if (stream->internal_buffer)
-                       gst_buffer_unref(stream->internal_buffer);
-       } else if (dataBlock) {
-               if (stream->bo[0])
-                       _mmplayer_video_stream_release_bo(player, stream->bo[0]);
-               gst_memory_unmap(dataBlock, &mapinfo);
+               LOGD("enable overlay");
+               __mmplayer_video_param_set_display_overlay(player);
+               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", FALSE, NULL);
        }
 
-       g_free(stream);
-       return;
+ERROR:
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
 }
 
-static int
-__mmplayer_gst_create_video_filters(mm_player_t* player, GList** bucket)
+int
+_mmplayer_get_audio_only(MMHandleType hplayer, bool *paudio_only)
 {
-       gchar* video_csc = "videoconvert"; /* default colorspace converter */
-       GList* element_bucket = NULL;
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->videobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       gboolean disable_overlay = FALSE;
 
        MMPLAYER_FENTER();
 
-       if (player->set_mode.video_zc || (player->is_360_feature_enabled && player->is_content_spherical)) {
-               LOGD("do not need to add video filters.");
-               return MM_ERROR_NONE;
-       }
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(paudio_only, MM_ERROR_INVALID_ARGUMENT);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin &&
+                                                               player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                                               MM_ERROR_PLAYER_NO_OP); /* invalid op */
 
-       /* in case of sw codec except 360 playback,
-        * if libav video decoder is selected, videoconvert is required to render the shm wl-buffer which support RGB only via tizenwlsink. */
-       MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_CONV, video_csc, "video converter", TRUE, player);
-       LOGD("using video converter: %s", video_csc);
+       if (!g_object_class_find_property(G_OBJECT_GET_CLASS(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "disable-overlay")) {
+               LOGW("Display control is not supported");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-       /* set video rotator */
-       MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_FLIP, "videoflip", "video rotator", TRUE, player);
+       g_object_get(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "disable-overlay", &disable_overlay, NULL);
 
-       *bucket = element_bucket;
-       MMPLAYER_FLEAVE();
-       return MM_ERROR_NONE;
+       *paudio_only = (bool)disable_overlay;
 
-ERROR: /* refer MMPLAYER_CREATE_ELEMENT */
-       g_list_free(element_bucket);
+       LOGD("audio_only : %d", *paudio_only);
 
-       *bucket = NULL;
        MMPLAYER_FLEAVE();
-       return MM_ERROR_PLAYER_INTERNAL;
+
+       return MM_ERROR_NONE;
 }
 
-/**
- * This function is to create video pipeline.
- *
- * @param      player          [in]    handle of player
- *             caps            [in]    src caps of decoder
- *             surface_type    [in]    surface type for video rendering
- *
- * @return     This function returns zero on success.
- * @remark
- * @see                __mmplayer_gst_create_audio_pipeline, __mmplayer_gst_create_midi_pipeline
- */
-/**
-  * VIDEO PIPELINE
-  * - video overlay surface(arm/x86) : tizenwlsink
-  */
-static int
-__mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDisplaySurfaceType surface_type)
+int
+__mmplayer_gst_element_link_bucket(GList *element_bucket)
 {
-       GstPad *pad = NULL;
-       MMHandleType attrs;
-       GList*element_bucket = NULL;
-       MMPlayerGstElement* first_element = NULL;
-       MMPlayerGstElement* videobin = NULL;
-       gchar *videosink_element = NULL;
+       GList *bucket = element_bucket;
+       mmplayer_gst_element_t *element = NULL;
+       mmplayer_gst_element_t *prv_element = NULL;
+       GstElement *tee_element = NULL;
+       gint successful_link_count = 0;
 
        MMPLAYER_FENTER();
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(element_bucket, -1);
 
-       /* alloc handles */
-       videobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_V_NUM);
-       if (!videobin)
-               return MM_ERROR_PLAYER_NO_FREE_SPACE;
+       prv_element = (mmplayer_gst_element_t *)bucket->data;
+       bucket = bucket->next;
 
-       player->pipeline->videobin = videobin;
+       for (; bucket; bucket = bucket->next) {
+               element = (mmplayer_gst_element_t *)bucket->data;
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if (!attrs) {
-               LOGE("cannot get content attribute");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
+               if (element && element->gst) {
+                       if (prv_element && prv_element->gst) {
+                               if (strstr(GST_ELEMENT_NAME(element->gst), "audio-tee-queue") && strcmp(GST_ELEMENT_NAME(prv_element->gst), "audio-tee")) {
+                                       if (tee_element) {
+                                               prv_element->gst = tee_element;
+                                       } else {
+                                               LOGD("failed to make new audio branch - linking [%s] to [%s] is not supported",
+                                                       GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
+                                                       GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
+                                               return -1;
+                                       }
+                               }
+                               if (gst_element_link(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst))) {
+                                       LOGD("linking [%s] to [%s] success",
+                                               GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
+                                               GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
+                                       successful_link_count++;
+                                       if (!strcmp(GST_ELEMENT_NAME(prv_element->gst), "audio-tee")) {
+                                               LOGD("keep audio-tee element for next audio pipeline branch");
+                                               tee_element = prv_element->gst;
+                                       }
+                               } else {
+                                       LOGD("linking [%s] to [%s] failed",
+                                               GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
+                                               GST_ELEMENT_NAME(GST_ELEMENT(element->gst)));
+                                       return -1;
+                               }
+                       }
+               }
 
-       /* create bin */
-       videobin[MMPLAYER_V_BIN].id = MMPLAYER_V_BIN;
-       videobin[MMPLAYER_V_BIN].gst = gst_bin_new("videobin");
-       if (!videobin[MMPLAYER_V_BIN].gst) {
-               LOGE("failed to create videobin");
-               goto ERROR;
+               prv_element = element;
        }
 
-       int enable_video_decoded_cb = 0;
-       mm_attrs_get_int_by_name(player->attrs, "enable_video_decoded_cb", &enable_video_decoded_cb);
+       MMPLAYER_FLEAVE();
 
-       if (player->is_360_feature_enabled && player->is_content_spherical) {
-               LOGD("video360 elem will be added.");
+       return successful_link_count;
+}
 
-               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_360, "video360",
-                               "video-360", TRUE, player);
+int
+__mmplayer_gst_element_add_bucket_to_bin(GstBin *bin, GList *element_bucket)
+{
+       GList *bucket = element_bucket;
+       mmplayer_gst_element_t *element = NULL;
+       int successful_add_count = 0;
 
-               /* Set spatial media metadata and/or user settings to the element.
-                * */
-               g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
-                               "projection-type", player->video360_metadata.projection_type, NULL);
+       MMPLAYER_FENTER();
 
-               g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
-                               "stereo-mode", player->video360_metadata.stereo_mode, NULL);
-
-               if (player->video360_metadata.full_pano_width_pixels &&
-                               player->video360_metadata.full_pano_height_pixels &&
-                               player->video360_metadata.cropped_area_image_width &&
-                               player->video360_metadata.cropped_area_image_height) {
-                       g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
-                                       "projection-bounds-top", player->video360_metadata.cropped_area_top,
-                                       "projection-bounds-bottom", player->video360_metadata.full_pano_height_pixels -
-                                                       player->video360_metadata.cropped_area_top - player->video360_metadata.cropped_area_image_height,
-                                       "projection-bounds-left", player->video360_metadata.cropped_area_left,
-                                       "projection-bounds-right", player->video360_metadata.full_pano_width_pixels -
-                                                       player->video360_metadata.cropped_area_left - player->video360_metadata.cropped_area_image_width,
-                                       NULL);
-               }
+       MMPLAYER_RETURN_VAL_IF_FAIL(element_bucket, 0);
+       MMPLAYER_RETURN_VAL_IF_FAIL(bin, 0);
 
-               if (player->video360_horizontal_fov && player->video360_vertical_fov) {
-                       g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
-                                       "horizontal-fov", player->video360_horizontal_fov,
-                                       "vertical-fov", player->video360_vertical_fov, NULL);
-               }
+       for (; bucket; bucket = bucket->next) {
+               element = (mmplayer_gst_element_t *)bucket->data;
 
-               if (player->video360_zoom <= VIDEO360_MAX_ZOOM && player->video360_zoom > 1.0f) {
-                       g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
-                                       "zoom", 1.0f / player->video360_zoom, NULL);
+               if (element && element->gst) {
+                       if (!gst_bin_add(bin, GST_ELEMENT(element->gst))) {
+                               LOGD("__mmplayer_gst_element_link_bucket : Adding element [%s]  to bin [%s] failed",
+                                       GST_ELEMENT_NAME(GST_ELEMENT(element->gst)),
+                                       GST_ELEMENT_NAME(GST_ELEMENT(bin)));
+                               return 0;
+                       }
+                       successful_add_count++;
                }
+       }
 
-               if (player->video360_yaw_radians <= M_PI &&
-                               player->video360_yaw_radians >= -M_PI &&
-                               player->video360_pitch_radians <= M_PI_2 &&
-                               player->video360_pitch_radians >= -M_PI_2) {
-                       g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
-                                       "pose-yaw", (int) (player->video360_yaw_radians * 180.0 / M_PI),
-                                       "pose-pitch", (int) (player->video360_pitch_radians * 180.0 / M_PI), NULL);
-               } else if (player->video360_metadata.init_view_heading || player->video360_metadata.init_view_pitch) {
-                       g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
-                                       "pose-yaw", player->video360_metadata.init_view_heading,
-                                       "pose-pitch", player->video360_metadata.init_view_pitch, NULL);
-               }
+       MMPLAYER_FLEAVE();
 
-               g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
-                               "passthrough", !player->is_video360_enabled, NULL);
-       }
+       return successful_add_count;
+}
 
-       /* set video sink */
-       switch (surface_type) {
-       case MM_DISPLAY_SURFACE_OVERLAY:
-               if (__mmplayer_gst_create_video_filters(player, &element_bucket) != MM_ERROR_NONE)
-                       goto ERROR;
-               if (strlen(player->ini.videosink_element_overlay) > 0)
-                       videosink_element = player->ini.videosink_element_overlay;
-               else
-                       goto ERROR;
-               break;
-       case MM_DISPLAY_SURFACE_NULL:
-               if (strlen(player->ini.videosink_element_fake) > 0)
-                       videosink_element = player->ini.videosink_element_fake;
-               else
-                       goto ERROR;
-               break;
-       case MM_DISPLAY_SURFACE_REMOTE:
-               if (strlen(player->ini.videosink_element_fake) > 0)
-                       videosink_element = player->ini.videosink_element_fake;
-               else
-                       goto ERROR;
-               break;
-       default:
-               LOGE("unidentified surface type");
-               goto ERROR;
-       }
-       LOGD("surface_type %d, selected videosink name: %s", surface_type, videosink_element);
+static void
+__mmplayer_gst_caps_notify_cb(GstPad *pad, GParamSpec *unused, gpointer data)
+{
+       mmplayer_t *player = (mmplayer_t *)data;
+       GstCaps *caps = NULL;
+       GstStructure *str = NULL;
+       const char *name;
+       gboolean caps_ret = TRUE;
 
-       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_element, "videosink", TRUE, player);
+       MMPLAYER_FENTER();
 
-       /* additional setting for sink plug-in */
-       switch (surface_type) {
-       case MM_DISPLAY_SURFACE_OVERLAY:
-       {
-               bool use_tbm = (player->set_mode.video_zc || (player->is_360_feature_enabled && player->is_content_spherical));
-               if (!use_tbm) {
-                       LOGD("selected videosink name: %s", videosink_element);
+       MMPLAYER_RETURN_IF_FAIL(pad);
+       MMPLAYER_RETURN_IF_FAIL(unused);
+       MMPLAYER_RETURN_IF_FAIL(data);
 
-                       /* support shard memory with S/W codec on HawkP */
-                       if (strncmp(videosink_element, "tizenwlsink", strlen(videosink_element)) == 0) {
-                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-                                       "use-tbm", use_tbm, NULL);
-                       }
-               } else {
-                       if (attrs) {
-                               int gapless = 0;
+       caps = gst_pad_get_current_caps(pad);
+       if (!caps)
+               return;
+
+       MMPLAYER_GST_GET_CAPS_INFO(pad, caps, str, name, caps_ret);
+       if (!caps_ret)
+               goto ERROR;
 
-                               mm_attrs_get_int_by_name(attrs, "gapless_mode", &gapless);
+       LOGD("name = %s", name);
 
-                               if (gapless > 0) {
-                                       LOGD("disable last-sample");
-                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "enable-last-sample", FALSE, NULL);
-                               }
-                       }
-               }
-               if (player->set_mode.media_packet_video_stream) {
-                       int enable = 0;
-                       mm_attrs_get_int_by_name(player->attrs, "enable_video_decoded_cb", &enable);
-                       if (enable)
-                               g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "signal-handoffs", TRUE, NULL);
-
-                       MMPLAYER_SIGNAL_CONNECT(player,
-                                                                       G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
-                                                                       MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
-                                                                       "handoff",
-                                                                       G_CALLBACK(__mmplayer_video_stream_decoded_render_cb),
-                                                                       (gpointer)player);
-
-                       MMPLAYER_SIGNAL_CONNECT(player,
-                                                                       G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
-                                                                       MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
-                                                                       "preroll-handoff",
-                                                                       G_CALLBACK(__mmplayer_video_stream_decoded_preroll_cb),
-                                                                       (gpointer)player);
+       if (strstr(name, "audio")) {
+               __mmplayer_update_content_attrs(player, ATTR_AUDIO);
+
+               if (player->audio_stream_changed_cb) {
+                       LOGE("call the audio stream changed cb");
+                       player->audio_stream_changed_cb(player->audio_stream_changed_cb_user_param);
                }
-               break;
-       }
-       case MM_DISPLAY_SURFACE_REMOTE:
-       {
-               if (player->set_mode.media_packet_video_stream) {
-                       LOGE("add data probe at videosink");
-                       g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
-                                                                                       "sync", TRUE, "signal-handoffs", TRUE, NULL);
-
-                       MMPLAYER_SIGNAL_CONNECT(player,
-                                                                       G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
-                                                                       MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
-                                                                       "handoff",
-                                                                       G_CALLBACK(__mmplayer_video_stream_decoded_render_cb),
-                                                                       (gpointer)player);
-
-                       MMPLAYER_SIGNAL_CONNECT(player,
-                                                                       G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
-                                                                       MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
-                                                                       "preroll-handoff",
-                                                                       G_CALLBACK(__mmplayer_video_stream_decoded_preroll_cb),
-                                                                       (gpointer)player);
-                       if (attrs) {
-                               int gapless = 0;
+       } else if (strstr(name, "video")) {
+               if ((name = gst_structure_get_string(str, "format")))
+                       player->set_mode.video_zc = name[0] == 'S';
 
-                               mm_attrs_get_int_by_name(attrs, "gapless_mode", &gapless);
+               __mmplayer_update_content_attrs(player, ATTR_VIDEO);
 
-                               if (gapless > 0) {
-                                       LOGD("disable last-sample");
-                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "enable-last-sample", FALSE, NULL);
-                               }
-                       }
+               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);
                }
-               break;
-       }
-       default:
-               break;
+       } else {
+               LOGW("invalid caps info");
        }
 
-       if (_mmplayer_update_video_param(player, "update_all_param") != MM_ERROR_NONE)
-               goto ERROR;
+ERROR:
+       if (caps)
+               gst_caps_unref(caps);
 
-       if (videobin[MMPLAYER_V_SINK].gst) {
-               GstPad *sink_pad = NULL;
-               sink_pad = gst_element_get_static_pad(videobin[MMPLAYER_V_SINK].gst, "sink");
-               if (sink_pad) {
-                       MMPLAYER_SIGNAL_CONNECT(player, sink_pad, MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
-                                       "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), player);
-                       gst_object_unref(GST_OBJECT(sink_pad));
-               } else
-                       LOGW("failed to get sink pad from videosink\n");
-       }
+       MMPLAYER_FLEAVE();
 
-       /* store it as it's sink element */
-       __mmplayer_add_sink(player, videobin[MMPLAYER_V_SINK].gst);
+       return;
+}
 
-       /* adding created elements to bin */
-       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(videobin[MMPLAYER_V_BIN].gst), element_bucket)) {
-               LOGE("failed to add elements\n");
-               goto ERROR;
-       }
+void
+__mmplayer_audio_stream_clear_buffer(mmplayer_t *player, gboolean send_all)
+{
+       GList *l = NULL;
 
-       /* Linking elements in the bucket by added order */
-       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1) {
-               LOGE("failed to link elements\n");
-               goto ERROR;
-       }
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player);
 
-       /* get first element's sinkpad for creating ghostpad */
-       if (element_bucket)
-               first_element = (MMPlayerGstElement *)element_bucket->data;
-       if (!first_element) {
-               LOGE("failed to get first element from bucket\n");
-               goto ERROR;
+       if (player->audio_stream_buff_list) {
+               for (l = g_list_first(player->audio_stream_buff_list); l; l = g_list_next(l)) {
+                       mmplayer_audio_stream_buff_t *tmp = (mmplayer_audio_stream_buff_t *)l->data;
+                       if (tmp) {
+                               if (send_all) {
+                                       LOGD("[%"G_GUINT64_FORMAT"] send remained data.", tmp->channel_mask);
+                                       __mmplayer_audio_stream_send_data(player, tmp);
+                               }
+                               MMPLAYER_FREEIF(tmp->pcm_data);
+                               MMPLAYER_FREEIF(tmp);
+                       }
+               }
+               g_list_free(player->audio_stream_buff_list);
+               player->audio_stream_buff_list = NULL;
        }
 
-       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
-       if (!pad) {
-               LOGE("failed to get pad from first element\n");
-               goto ERROR;
-       }
+       MMPLAYER_FLEAVE();
+}
 
-       /* create ghostpad */
-       player->ghost_pad_for_videobin = gst_ghost_pad_new("sink", pad);
-       if (FALSE == gst_element_add_pad(videobin[MMPLAYER_V_BIN].gst, player->ghost_pad_for_videobin)) {
-               LOGE("failed to add ghostpad to videobin\n");
-               goto ERROR;
-       }
-       gst_object_unref(pad);
+static void
+__mmplayer_audio_stream_send_data(mmplayer_t *player, mmplayer_audio_stream_buff_t *a_buffer)
+{
+       mmplayer_audio_decoded_data_info_t audio_stream = { 0, };
 
-       /* done. free allocated variables */
-       if (element_bucket)
-               g_list_free(element_bucket);
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->audio_decoded_cb);
+
+       audio_stream.bitrate = a_buffer->bitrate;
+       audio_stream.channel = a_buffer->channel;
+       audio_stream.depth = a_buffer->depth;
+       audio_stream.is_little_endian = a_buffer->is_little_endian;
+       audio_stream.channel_mask = a_buffer->channel_mask;
+       audio_stream.data_size = a_buffer->data_size;
+       audio_stream.data = a_buffer->pcm_data;
+       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); */
+       player->audio_decoded_cb(&audio_stream, player->audio_decoded_cb_user_param);
 
        MMPLAYER_FLEAVE();
+}
+
+static void
+__mmplayer_audio_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data)
+{
+       mmplayer_t *player = (mmplayer_t *)data;
+       const gchar *pcm_format = NULL;
+       gint channel = 0;
+       gint rate = 0;
+       gint depth = 0;
+       gint endianness = 0;
+       guint64 channel_mask = 0;
+       void *a_data = NULL;
+       gint a_size = 0;
+       mmplayer_audio_stream_buff_t *a_buffer = NULL;
+       GstMapInfo mapinfo = GST_MAP_INFO_INIT;
+       GList *l = NULL;
 
-       return MM_ERROR_NONE;
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->audio_decoded_cb);
 
-ERROR:
-       LOGE("ERROR : releasing videobin\n");
+       gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
+       a_data = mapinfo.data;
+       a_size = mapinfo.size;
 
-       g_list_free(element_bucket);
+       GstCaps *caps = gst_pad_get_current_caps(pad);
+       GstStructure *structure = gst_caps_get_structure(caps, 0);
 
-       if (pad)
-               gst_object_unref(GST_OBJECT(pad));
+       /* MMPLAYER_LOG_GST_CAPS_TYPE(caps); */
+       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));
 
-       /* release videobin with it's childs */
-       if (videobin[MMPLAYER_V_BIN].gst)
-               gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst));
+       /* In case of the sync is false, use buffer list.              *
+        * The num of buffer list depends on the num of audio channels */
+       if (player->audio_stream_buff_list) {
+               for (l = g_list_first(player->audio_stream_buff_list); l; l = g_list_next(l)) {
+                       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); */
+                                       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;
+                                       } else {
+                                               /* send data to client */
+                                               __mmplayer_audio_stream_send_data(player, tmp);
 
+                                               if (a_size > tmp->buff_size) {
+                                                       LOGD("[%"G_GUINT64_FORMAT"] adj buffer size %d -> %d", channel_mask, tmp->buff_size, a_size);
+                                                       tmp->pcm_data = g_realloc(tmp->pcm_data, a_size);
+                                                       if (tmp->pcm_data == NULL) {
+                                                               LOGE("failed to realloc data.");
+                                                               goto DONE;
+                                                       }
+                                                       tmp->buff_size = a_size;
+                                               }
+                                               memset(tmp->pcm_data, 0x00, tmp->buff_size);
+                                               memcpy(tmp->pcm_data, a_data, a_size);
+                                               tmp->data_size = a_size;
+                                       }
+                                       goto DONE;
+                               }
+                       } else {
+                               LOGE("data is empty in list.");
+                               goto DONE;
+                       }
+               }
+       }
 
-       MMPLAYER_FREEIF(videobin);
+       /* create new audio stream data for newly found audio channel */
+       a_buffer = (mmplayer_audio_stream_buff_t *)g_try_malloc0(sizeof(mmplayer_audio_stream_buff_t));
+       if (a_buffer == NULL) {
+               LOGE("failed to alloc data.");
+               goto DONE;
+       }
+       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 = util_convert_audio_pcm_str_to_media_format_mime(pcm_format);
 
-       player->pipeline->videobin = NULL;
+       if (player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK) {
+               /* If sync is FALSE, use buffer list to reduce the IPC. */
+               a_buffer->buff_size = (a_size > player->ini.pcm_buffer_size) ? (a_size) : (player->ini.pcm_buffer_size);
+               a_buffer->pcm_data = g_try_malloc(a_buffer->buff_size);
+               if (a_buffer->pcm_data == NULL) {
+                       LOGE("failed to alloc data.");
+                       MMPLAYER_FREEIF(a_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); */
+               player->audio_stream_buff_list = g_list_append(player->audio_stream_buff_list, a_buffer);
+       } else {
+               /* If sync is TRUE, send data directly. */
+               a_buffer->pcm_data = a_data;
+               __mmplayer_audio_stream_send_data(player, a_buffer);
+               MMPLAYER_FREEIF(a_buffer);
+       }
 
-       return MM_ERROR_PLAYER_INTERNAL;
+DONE:
+       gst_buffer_unmap(buffer, &mapinfo);
+       MMPLAYER_FLEAVE();
 }
 
-static int __mmplayer_gst_create_plain_text_elements(mm_player_t* player)
+static void
+__mmplayer_gst_audio_deinterleave_pad_added(GstElement *elem, GstPad *pad, gpointer data)
 {
-       GList *element_bucket = NULL;
-       MMPlayerGstElement *textbin = player->pipeline->textbin;
-
-       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_QUEUE, "queue", "text_queue", TRUE, player);
-       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_IDENTITY, "identity", "text_identity", TRUE, player);
-       g_object_set(G_OBJECT(textbin[MMPLAYER_T_IDENTITY].gst),
-                                                       "signal-handoffs", FALSE,
-                                                       NULL);
+       mmplayer_t *player = (mmplayer_t *)data;
+       mmplayer_gst_element_t *audiobin = player->pipeline->audiobin;
+       GstPad *sinkpad = NULL;
+       GstElement *queue = NULL, *sink = NULL;
 
-       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_FAKE_SINK, "fakesink", "text_fakesink", TRUE, player);
-       MMPLAYER_SIGNAL_CONNECT(player,
-                                                       G_OBJECT(textbin[MMPLAYER_T_FAKE_SINK].gst),
-                                                       MM_PLAYER_SIGNAL_TYPE_TEXTBIN,
-                                                       "handoff",
-                                                       G_CALLBACK(__mmplayer_update_subtitle),
-                                                       (gpointer)player);
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->mainbin);
 
-       g_object_set(G_OBJECT(textbin[MMPLAYER_T_FAKE_SINK].gst), "async", TRUE, NULL);
-       g_object_set(G_OBJECT(textbin[MMPLAYER_T_FAKE_SINK].gst), "sync", TRUE, NULL);
-       g_object_set(G_OBJECT(textbin[MMPLAYER_T_FAKE_SINK].gst), "signal-handoffs", TRUE, NULL);
+       queue = gst_element_factory_make("queue", NULL);
+       if (queue == NULL) {
+               LOGD("fail make queue");
+               goto ERROR;
+       }
 
-       if (!player->play_subtitle) {
-               LOGD("add textbin sink as sink element of whole pipeline.\n");
-               __mmplayer_add_sink(player, GST_ELEMENT(textbin[MMPLAYER_T_FAKE_SINK].gst));
+       sink = gst_element_factory_make("fakesink", NULL);
+       if (sink == NULL) {
+               LOGD("fail make fakesink");
+               goto ERROR;
        }
 
-       /* adding created elements to bin */
-       LOGD("adding created elements to bin\n");
-       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(textbin[MMPLAYER_T_BIN].gst), element_bucket)) {
-               LOGE("failed to add elements\n");
+       gst_bin_add_many(GST_BIN(audiobin[MMPLAYER_A_BIN].gst), queue, sink, NULL);
+
+       if (!gst_element_link_pads_full(queue, "src", sink, "sink", GST_PAD_LINK_CHECK_NOTHING)) {
+               LOGW("failed to link queue & sink");
                goto ERROR;
        }
 
-       /* unset sink flag from textbin. not to hold eos when video data is shorter than subtitle */
-       GST_OBJECT_FLAG_UNSET(textbin[MMPLAYER_T_BIN].gst, GST_ELEMENT_FLAG_SINK);
-       GST_OBJECT_FLAG_UNSET(textbin[MMPLAYER_T_FAKE_SINK].gst, GST_ELEMENT_FLAG_SINK);
+       sinkpad = gst_element_get_static_pad(queue, "sink");
 
-       /* linking elements in the bucket by added order. */
-       LOGD("Linking elements in the bucket by added order.\n");
-       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1) {
-               LOGE("failed to link elements\n");
+       if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
+               LOGW("failed to link [%s:%s] to queue", GST_DEBUG_PAD_NAME(pad));
                goto ERROR;
        }
 
-       /* done. free allocated variables */
-       g_list_free(element_bucket);
+       LOGE("audio_extract_opt : 0x%X", player->audio_extract_opt);
 
-       if (textbin[MMPLAYER_T_QUEUE].gst) {
-               GstPad *pad = NULL;
-               GstPad *ghostpad = NULL;
+       gst_object_unref(sinkpad);
+       if (!(player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK))
+               g_object_set(sink, "sync", TRUE, NULL);
+       g_object_set(sink, "signal-handoffs", TRUE, NULL);
 
-               pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_QUEUE].gst), "sink");
-               if (!pad) {
-                       LOGE("failed to get sink pad of text queue");
-                       goto ERROR;
-               }
+       /* keep the first sink reference only */
+       if (!audiobin[MMPLAYER_A_SINK].gst) {
+               audiobin[MMPLAYER_A_SINK].id = MMPLAYER_A_SINK;
+               audiobin[MMPLAYER_A_SINK].gst = sink;
+       }
 
-               ghostpad = gst_ghost_pad_new("text_sink", pad);
-               gst_object_unref(pad);
+       gst_element_set_state(sink, GST_STATE_PAUSED);
+       gst_element_set_state(queue, GST_STATE_PAUSED);
 
-               if (!ghostpad) {
-                       LOGE("failed to create ghostpad of textbin\n");
-                       goto ERROR;
-               }
+       __mmplayer_add_signal_connection(player,
+               G_OBJECT(sink),
+               MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
+               "handoff",
+               G_CALLBACK(__mmplayer_audio_stream_decoded_render_cb),
+               (gpointer)player);
 
-               if (!gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad)) {
-                       LOGE("failed to add ghostpad to textbin\n");
-                       gst_object_unref(ghostpad);
-                       goto ERROR;
-               }
-       }
+       __mmplayer_add_sink(player, sink);
 
-       return MM_ERROR_NONE;
+       MMPLAYER_FLEAVE();
+       return;
 
 ERROR:
-       g_list_free(element_bucket);
-
-       if (!player->play_subtitle && textbin[MMPLAYER_T_FAKE_SINK].gst) {
-               LOGE("remove textbin sink from sink list");
-               __mmplayer_del_sink(player, textbin[MMPLAYER_T_FAKE_SINK].gst);
+       LOGE("__mmplayer_gst_audio_deinterleave_pad_added ERROR");
+       if (queue) {
+               gst_object_unref(GST_OBJECT(queue));
+               queue = NULL;
+       }
+       if (sink) {
+               gst_object_unref(GST_OBJECT(sink));
+               sink = NULL;
+       }
+       if (sinkpad) {
+               gst_object_unref(GST_OBJECT(sinkpad));
+               sinkpad = NULL;
        }
 
-       /* release element at __mmplayer_gst_create_text_sink_bin */
-       return MM_ERROR_PLAYER_INTERNAL;
+       return;
 }
 
-static int __mmplayer_gst_create_text_sink_bin(mm_player_t* player)
+void
+__mmplayer_gst_set_pulsesink_property(mmplayer_t *player)
 {
-       MMPlayerGstElement *textbin = NULL;
-       GList *element_bucket = NULL;
-       int surface_type = 0;
-       gint i = 0;
+       #define MAX_PROPS_LEN 128
+       gint latency_mode = 0;
+       gchar *stream_type = NULL;
+       gchar *latency = NULL;
+       gint stream_id = 0;
+       gchar stream_props[MAX_PROPS_LEN] = {0,};
+       GstStructure *props = NULL;
 
+       /* set volume table
+        * It should be set after player creation through attribute.
+        * But, it can not be changed during playing.
+        */
        MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->audiobin);
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       /* alloc handles */
-       textbin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_T_NUM);
-       if (!textbin) {
-               LOGE("failed to allocate memory for textbin\n");
-               return MM_ERROR_PLAYER_NO_FREE_SPACE;
-       }
+       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);
 
-       /* create bin */
-       textbin[MMPLAYER_T_BIN].id = MMPLAYER_T_BIN;
-       textbin[MMPLAYER_T_BIN].gst = gst_bin_new("textbin");
-       if (!textbin[MMPLAYER_T_BIN].gst) {
-               LOGE("failed to create textbin\n");
-               goto ERROR;
+       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);
        }
 
-       /* take it */
-       player->pipeline->textbin = textbin;
+       mm_attrs_get_int_by_name(player->attrs, "sound_latency_mode", &latency_mode);
 
-       /* fakesink */
-       mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
-       LOGD("surface type for subtitle : %d", surface_type);
-       switch (surface_type) {
-       case MM_DISPLAY_SURFACE_OVERLAY:
-       case MM_DISPLAY_SURFACE_NULL:
-       case MM_DISPLAY_SURFACE_REMOTE:
-               if (__mmplayer_gst_create_plain_text_elements(player) != MM_ERROR_NONE) {
-                       LOGE("failed to make plain text elements\n");
-                       goto ERROR;
-               }
+       switch (latency_mode) {
+       case AUDIO_LATENCY_MODE_LOW:
+               latency = g_strndup("low", 3);
                break;
-       default:
-               goto ERROR;
+       case AUDIO_LATENCY_MODE_MID:
+               latency = g_strndup("mid", 3);
                break;
-       }
-
-       MMPLAYER_FLEAVE();
+       case AUDIO_LATENCY_MODE_HIGH:
+               latency = g_strndup("high", 4);
+               break;
+       };
 
-       return MM_ERROR_NONE;
+       g_object_set(player->pipeline->audiobin[MMPLAYER_A_SINK].gst,
+                       "latency", latency,
+                       NULL);
 
-ERROR:
+       LOGD("audiosink property - latency=%s", latency);
 
-       LOGD("ERROR : releasing textbin\n");
+       MMPLAYER_FREEIF(latency);
 
-       g_list_free(element_bucket);
+       MMPLAYER_FLEAVE();
+}
 
-       /* release signal */
-       __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
+void
+__mmplayer_gst_set_openalsink_property(mmplayer_t *player)
+{
+       mmplayer_gst_element_t *audiobin = NULL;
 
-       /* release element which are not added to bin */
-       for (i = 1; i < MMPLAYER_T_NUM; i++) {
-               /* NOTE : skip bin */
-               if (textbin[i].gst) {
-                       GstObject* parent = NULL;
-                       parent = gst_element_get_parent(textbin[i].gst);
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->audiobin);
 
-                       if (!parent) {
-                               gst_object_unref(GST_OBJECT(textbin[i].gst));
-                               textbin[i].gst = NULL;
-                       } else {
-                               gst_object_unref(GST_OBJECT(parent));
-                       }
-               }
-       }
+       audiobin = player->pipeline->audiobin;
 
-       /* release textbin with it's childs */
-       if (textbin[MMPLAYER_T_BIN].gst)
-               gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
+       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);
+       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "stream-info", stream_info, NULL);
 
-       MMPLAYER_FREEIF(player->pipeline->textbin);
-       player->pipeline->textbin = NULL;
+       if (player->video360_yaw_radians <= M_PI &&
+                       player->video360_yaw_radians >= -M_PI &&
+                       player->video360_pitch_radians <= M_PI_2 &&
+                       player->video360_pitch_radians >= -M_PI_2) {
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst),
+                               "source-orientation-y", (int)(player->video360_yaw_radians * 180.0 / M_PI),
+                               "source-orientation-x", (int)(player->video360_pitch_radians * 180.0 / M_PI), NULL);
+       } else if (player->video360_metadata.init_view_heading || player->video360_metadata.init_view_pitch) {
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst),
+                               "source-orientation-y", player->video360_metadata.init_view_heading,
+                               "source-orientation-x", player->video360_metadata.init_view_pitch, NULL);
+       }
 
        MMPLAYER_FLEAVE();
-       return MM_ERROR_PLAYER_INTERNAL;
 }
 
-
 static int
-__mmplayer_gst_create_text_pipeline(mm_player_t* player)
+__mmplayer_gst_make_audio_playback_sink(mmplayer_t *player, GList **bucket)
 {
-       MMPlayerGstElement* mainbin = NULL;
-       MMPlayerGstElement* textbin = NULL;
-       MMHandleType attrs = 0;
-       GstElement *subsrc = NULL;
-       GstElement *subparse = NULL;
-       gchar *subtitle_uri = NULL;
-       const gchar *charset = NULL;
-       GstPad *pad = NULL;
+       mmplayer_gst_element_t *audiobin = NULL;
+       GstPad *sink_pad = NULL;
+       GstCaps *acaps = NULL;
+       gint channels = 0;
+       int pitch_control = 0;
+       double pitch_value = 1.0;
 
        MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       /* get mainbin */
-       MMPLAYER_RETURN_VAL_IF_FAIL(player &&
-                                                               player->pipeline &&
-                                                               player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       mainbin = player->pipeline->mainbin;
+       audiobin = player->pipeline->audiobin;
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if (!attrs) {
-               LOGE("cannot get content attribute\n");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
+       LOGD("make element for normal audio playback");
 
-       mm_attrs_get_string_by_name(attrs, "subtitle_uri", &subtitle_uri);
-       if (!subtitle_uri || strlen(subtitle_uri) < 1) {
-               LOGE("subtitle uri is not proper filepath.\n");
-               return MM_ERROR_PLAYER_INVALID_URI;
-       }
+       /* audio bin structure for playback. {} means optional.
+          optional : pitch, audioeq, custom audioeq, openalsink for 360 audio content
 
-       if (!util_get_storage_info(subtitle_uri, &player->storage_info[MMPLAYER_PATH_TEXT])) {
-               LOGE("failed to get storage info of subtitle path");
-               return MM_ERROR_PLAYER_INVALID_URI;
-       }
+        * src - ... - {aconv - pitch} - aconv - rgvolume - resample - volume -
+                       {audioeq} - {custom audioeq} - pulsesink or {aconv - capsfilter - openalsink}
+        */
 
-       SECURE_LOGD("subtitle file path is [%s].\n", subtitle_uri);
+       /* for pitch control */
+       mm_attrs_multiple_get(player->attrs, NULL,
+                               MM_PLAYER_PITCH_CONTROL, &pitch_control,
+                               MM_PLAYER_PITCH_VALUE, &pitch_value,
+                               NULL);
 
-       MMPLAYER_SUBTITLE_INFO_LOCK(player);
-       player->subtitle_language_list = NULL;
-       MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
+       LOGD("pitch %d / %1.3f", pitch_control, pitch_value);
+       if (pitch_control && (player->videodec_linked == 0)) {
+               GstElementFactory *factory;
 
-       /* create the subtitle source */
-       subsrc = gst_element_factory_make("filesrc", "subtitle_source");
-       if (!subsrc) {
-               LOGE("failed to create filesrc element\n");
-               goto ERROR;
-       }
-       g_object_set(G_OBJECT(subsrc), "location", subtitle_uri, NULL);
+               factory = gst_element_factory_find("pitch");
+               if (factory) {
+                       gst_object_unref(factory);
 
-       mainbin[MMPLAYER_M_SUBSRC].id = MMPLAYER_M_SUBSRC;
-       mainbin[MMPLAYER_M_SUBSRC].gst = subsrc;
+                       /* converter */
+                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV_PITCH, "audioconvert", "audio convert pitch", *bucket, player);
 
-       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subsrc)) {
-               LOGW("failed to add queue\n");
-               gst_object_unref(mainbin[MMPLAYER_M_SUBSRC].gst);
-               mainbin[MMPLAYER_M_SUBSRC].gst = NULL;
-               mainbin[MMPLAYER_M_SUBSRC].id = MMPLAYER_M_NUM;
-               goto ERROR;
+                       /* pitch */
+                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_PITCH, "pitch", "audio pitch", *bucket, player);
+                       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_PITCH].gst), "pitch", (gdouble)pitch_value, NULL);
+               } else {
+                       LOGW("there is no pitch element");
+               }
        }
 
-       /* subparse */
-       subparse = gst_element_factory_make("subparse", "subtitle_parser");
-       if (!subparse) {
-               LOGE("failed to create subparse element\n");
-               goto ERROR;
-       }
+       /* converter */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audio converter", *bucket, player);
 
-       charset = util_get_charset(subtitle_uri);
-       if (charset) {
-               LOGD("detected charset is %s\n", charset);
-               g_object_set(G_OBJECT(subparse), "subtitle-encoding", charset, NULL);
-       }
+       /* replaygain volume */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RGVOL, "rgvolume", "audio rgvolume", *bucket, player);
+       if (player->sound.rg_enable)
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_RGVOL].gst), "enable-rgvolume", TRUE, NULL);
+       else
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_RGVOL].gst), "enable-rgvolume", FALSE, NULL);
 
-       mainbin[MMPLAYER_M_SUBPARSE].id = MMPLAYER_M_SUBPARSE;
-       mainbin[MMPLAYER_M_SUBPARSE].gst = subparse;
+       /* resampler */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RESAMPLER,  player->ini.audioresampler_element, "audio resampler", *bucket, player);
 
-       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subparse)) {
-               LOGW("failed to add subparse\n");
-               gst_object_unref(mainbin[MMPLAYER_M_SUBPARSE].gst);
-               mainbin[MMPLAYER_M_SUBPARSE].gst = NULL;
-               mainbin[MMPLAYER_M_SUBPARSE].id = MMPLAYER_M_NUM;
-               goto ERROR;
-       }
+       /* 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 (!gst_element_link_pads(subsrc, "src", subparse, "sink")) {
-               LOGW("failed to link subsrc and subparse\n");
-               goto ERROR;
+       if (player->sound.mute) {
+               LOGD("mute enabled");
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
        }
 
-       player->play_subtitle = TRUE;
-       player->adjust_subtitle_pos = 0;
+       mm_attrs_get_int_by_name(player->attrs, "content_audio_channels", &channels);
 
-       LOGD("play subtitle using subtitle file\n");
+       /* audio effect element. if audio effect is enabled */
+       if ((strcmp(player->ini.audioeffect_element, ""))
+               && (channels <= 2)
+               && (player->ini.use_audio_effect_preset || player->ini.use_audio_effect_custom)) {
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER, player->ini.audioeffect_element, "audio effect filter", *bucket, player);
 
-       if (player->pipeline->textbin == NULL) {
-               if (MM_ERROR_NONE != __mmplayer_gst_create_text_sink_bin(player)) {
-                       LOGE("failed to create text sink bin. continuing without text\n");
-                       goto ERROR;
+               LOGD("audio effect config. bypass = %d, effect type = %d", player->bypass_audio_effect, player->audio_effect_info.effect_type);
+
+               if ((!player->bypass_audio_effect)
+                       && (player->ini.use_audio_effect_preset || player->ini.use_audio_effect_custom)) {
+                       if (player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM) {
+                               if (!_mmplayer_audio_effect_custom_apply(player))
+                                       LOGI("apply audio effect(custom) setting success");
+                       }
                }
 
-               textbin = player->pipeline->textbin;
+               if ((strcmp(player->ini.audioeffect_element_custom, ""))
+                       && (player->set_mode.rich_audio)) {
+                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER_SEC, player->ini.audioeffect_element_custom, "audio effect filter custom", *bucket, player);
+               }
+       }
 
-               if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), GST_ELEMENT(textbin[MMPLAYER_T_BIN].gst))) {
-                       LOGW("failed to add textbin\n");
+       /* create audio sink */
+       LOGD("spherical %d, channels %d, ambisonic type %d, format %d, order %d",
+                       player->is_content_spherical, channels, player->video360_metadata.ambisonic_type,
+                       player->video360_metadata.ambisonic_format, player->video360_metadata.ambisonic_order);
 
-                       /* release signal */
-                       __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
+       /* Note: qtdemux converts audio metadata defaults to openalsink defaults. */
+       if (player->is_360_feature_enabled &&
+               player->is_content_spherical &&
+               channels == 4 &&
+               player->video360_metadata.ambisonic_type == MMFILE_AMBISONIC_TYPE_PERIPHONIC &&
+               player->video360_metadata.ambisonic_format == MMFILE_AMBISONIC_FORMAT_AMB &&
+               player->video360_metadata.ambisonic_order == MMFILE_AMBISONIC_ORDER_FOA) {
 
-                       /* release textbin with it's childs */
-                       gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
-                       MMPLAYER_FREEIF(player->pipeline->textbin);
-                       player->pipeline->textbin = textbin = NULL;
-                       goto ERROR;
-               }
+               strncpy(player->ini.audiosink_element, "openalsink", PLAYER_INI_MAX_STRLEN - 1);
 
-               LOGD("link text input selector and textbin ghost pad");
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV_BFORMAT, "audioconvert", "audio-converter-bformat", *bucket, player);
 
-               player->textsink_linked = 1;
-               player->external_text_idx = 0;
-               LOGI("player->textsink_linked set to 1\n");
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_360, "capsfilter", "audio-caps-filter", *bucket, player);
+               acaps = gst_caps_from_string(SPATIAL_AUDIO_CAPS);
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_CAPS_360].gst), "caps", acaps, NULL);
+               gst_caps_unref(acaps);
+
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "openalsink", "audiosink", *bucket, player);
+
+               player->is_openal_plugin_used = TRUE;
        } else {
-               textbin = player->pipeline->textbin;
-               LOGD("text bin has been created. reuse it.");
-               player->external_text_idx = 1;
+               if (player->is_360_feature_enabled && player->is_content_spherical)
+                       LOGW("Audio track isn't of the ambisonic type and can't be played back as a spatial sound.");
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.audiosink_element, "audiosink", *bucket, player);
        }
 
-       if (!gst_element_link_pads(subparse, "src", textbin[MMPLAYER_T_BIN].gst, "text_sink")) {
-               LOGW("failed to link subparse and textbin\n");
-               goto ERROR;
+       if ((MMPLAYER_IS_RTSP_STREAMING(player)) ||
+               (player->videodec_linked && player->ini.use_system_clock)) {
+               LOGD("system clock will be used.");
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "provide-clock", FALSE,  NULL);
        }
 
-       pad = gst_element_get_static_pad(textbin[MMPLAYER_T_FAKE_SINK].gst, "sink");
-       if (!pad) {
-               LOGE("failed to get sink pad from textsink to probe data");
-               goto ERROR;
-       }
+       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);
 
-       gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER,
-                               __mmplayer_subtitle_adjust_position_probe, player, NULL);
+       /* qos on */
+       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL);       /* qos on */
+       g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "slave-method", GST_AUDIO_BASE_SINK_SLAVE_NONE, NULL);
 
-       gst_object_unref(pad);
-       pad = NULL;
+       sink_pad = gst_element_get_static_pad(audiobin[MMPLAYER_A_SINK].gst, "sink");
+       __mmplayer_add_signal_connection(player, G_OBJECT(sink_pad), MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
+                               "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), (gpointer)player);
+       gst_object_unref(GST_OBJECT(sink_pad));
 
-       /* create dot. for debugging */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-with-subtitle");
-       MMPLAYER_FLEAVE();
+       __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst);
 
+       MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
 
-ERROR:
-       /* release text pipeline resource */
-       player->textsink_linked = 0;
-
-       /* release signal */
-       __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
-
-       if (player->pipeline->textbin) {
-               LOGE("remove textbin");
-
-               /* release textbin with it's childs */
-               MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->textbin, MMPLAYER_T_BIN);
-               MMPLAYER_FREEIF(player->pipeline->textbin);
-               player->pipeline->textbin = NULL;
-
-       }
-
-       /* release subtitle elem */
-       MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->mainbin, MMPLAYER_M_SUBSRC);
-       MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->mainbin, MMPLAYER_M_SUBPARSE);
-
+ERROR: /* MMPLAYER_CREATE_ELEMENT */
+       MMPLAYER_FLEAVE();
        return MM_ERROR_PLAYER_INTERNAL;
 }
 
-gboolean
-__mmplayer_update_subtitle(GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data)
+static int
+__mmplayer_gst_make_audio_extract_sink(mmplayer_t *player, GList **bucket)
 {
-       mm_player_t* player = (mm_player_t*) data;
-       MMMessageParamType msg = {0, };
-       GstClockTime duration = 0;
-       gpointer text = NULL;
-       guint text_size = 0;
-       gboolean ret = TRUE;
-       GstMapInfo mapinfo = GST_MAP_INFO_INIT;
+       mmplayer_gst_element_t *audiobin = NULL;
+       enum audio_element_id extract_sink_id = MMPLAYER_A_SINK;
 
-       MMPLAYER_FENTER();
+       gchar *dst_format = NULL;
+       int dst_len = 0;
+       int dst_samplerate = 0;
+       int dst_channels = 0;
+       GstCaps *caps = NULL;
+       char *caps_str = NULL;
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL(buffer, FALSE);
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       if (player->is_subtitle_force_drop) {
-               LOGW("subtitle is dropped forcedly.");
-               return ret;
-       }
+       audiobin = player->pipeline->audiobin;
 
-       gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
-       text = mapinfo.data;
-       text_size = mapinfo.size;
-       duration = GST_BUFFER_DURATION(buffer);
+       LOGD("make element for audio extract, option = 0x%X", player->audio_extract_opt);
 
-       if (player->set_mode.subtitle_off) {
-               LOGD("subtitle is OFF.\n");
-               return TRUE;
-       }
+       /* audio bin structure according to the mmplayer_audio_extract_opt_e.
 
-       if (!text || (text_size == 0)) {
-               LOGD("There is no subtitle to be displayed.\n");
-               return TRUE;
-       }
+          [case 1] extract interleave audio pcm without playback
+                               : MM_PLAYER_AUDIO_EXTRACT_DEFAULT (sync)
+                                 MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK (non sync)
 
-       msg.data = (void *) text;
-       msg.subtitle.duration = GST_TIME_AS_MSECONDS(duration);
+                               * src - ... - aconv - resample - capsfilter - fakesink (sync or not)
 
-       LOGD("update subtitle : [%ld msec] %s\n'", msg.subtitle.duration, (char*)msg.data);
+          [case 2] deinterleave for each channel without playback
+                               : MM_PLAYER_AUDIO_EXTRACT_DEINTERLEAVE (sync)
+                                 MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_AND_DEINTERLEAVE (non sync)
 
-       MMPLAYER_POST_MSG(player, MM_MESSAGE_UPDATE_SUBTITLE, &msg);
-       gst_buffer_unmap(buffer, &mapinfo);
+                               * src - ... - aconv - resample - capsfilter - deinterleave - fakesink (sync or not)
+                                                                                                                                                  - fakesink (sync or not)
+                                                                                                                                                  - ...      (sync or not)
 
-       MMPLAYER_FLEAVE();
+          [case 3] [case 1(sync only)] + playback
+                               : MM_PLAYER_AUDIO_EXTRACT_WITH_PLAYBACK
 
-       return ret;
-}
+                               * src - ... - tee - queue1 - playback path
+                                                                 - queue2 - [case1 pipeline with sync]
 
-static GstPadProbeReturn
-__mmplayer_subtitle_adjust_position_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
-{
-       mm_player_t *player = (mm_player_t *) u_data;
-       GstClockTime cur_timestamp = 0;
-       gint64 adjusted_timestamp = 0;
-       GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
+          [case 4] [case 2(sync only)] + playback
+                               : MM_PLAYER_AUDIO_EXTRACT_DEINTERLEAVE_WITH_PLAYBACK
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+                               * src - ... - tee - queue1 - playback path
+                                                                 - queue2 - [case2 pipeline with sync]
 
-       if (player->set_mode.subtitle_off) {
-               LOGD("subtitle is OFF.\n");
-               return TRUE;
-       }
+        */
 
-       if (player->adjust_subtitle_pos == 0) {
-               LOGD("nothing to do");
-               return TRUE;
-       }
+       /* 1. create tee and playback path
+             'tee' should be added at first to copy the decoded stream
+        */
+       if (player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_WITH_PLAYBACK) {
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TEE, "tee", "audio-tee", *bucket, player);
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_TEE].gst), "num-src-pads", 2, NULL);
 
-       cur_timestamp = GST_BUFFER_TIMESTAMP(buffer);
-       adjusted_timestamp = (gint64) cur_timestamp +((gint64) player->adjust_subtitle_pos * G_GINT64_CONSTANT(1000000));
+               /* tee - path 1 : for playback path */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TEE_Q1, "queue", "audio-tee-queue1", *bucket, player);
+               __mmplayer_gst_make_audio_playback_sink(player, bucket);
 
-       if (adjusted_timestamp < 0) {
-               LOGD("adjusted_timestamp under zero");
-               MMPLAYER_FLEAVE();
-               return FALSE;
+               /* tee - path 2 : for extract path */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TEE_Q2, "queue", "audio-tee-queue2", *bucket, player);
+               extract_sink_id = MMPLAYER_A_EXTRACT_SINK; /* there is another playback sink */
        }
 
-       GST_BUFFER_TIMESTAMP(buffer) = (GstClockTime) adjusted_timestamp;
-       LOGD("buffer timestamp changed %" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "",
-                               GST_TIME_ARGS(cur_timestamp),
-                               GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
+       /* if there is tee, 'tee - path 2' is linked here */
+       /* converter */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_EXTRACT_CONV, "audioconvert", "audio-ext-conv", *bucket, player);
 
-       return GST_PAD_PROBE_OK;
-}
-static int __gst_adjust_subtitle_position(mm_player_t* player, int format, int position)
-{
-       MMPLAYER_FENTER();
+       /* resampler */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_EXTRACT_RESAMPLER,  player->ini.audioresampler_element, "audio-ext-resampler", *bucket, player);
 
-       /* check player and subtitlebin are created */
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(player->play_subtitle, MM_ERROR_NOT_SUPPORT_API);
+       /* 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,
+                               NULL);
 
-       if (position == 0) {
-               LOGD("nothing to do\n");
-               MMPLAYER_FLEAVE();
-               return MM_ERROR_NONE;
-       }
+       LOGD("required extract pcm format - format: %s(%d), samplerate : %d, channel: %d",
+                       dst_format, dst_len, dst_samplerate, dst_channels);
 
-       switch (format) {
-       case MM_PLAYER_POS_FORMAT_TIME:
-               {
-                       /* check current postion */
-                       player->adjust_subtitle_pos = position;
+       if (dst_format == NULL || dst_len == 0 || dst_samplerate == 0 || dst_channels == 0) {
+               mm_attrs_multiple_get(player->attrs, NULL,
+                                       "content_audio_format", &dst_format, &dst_len, /* get string and len */
+                                       "content_audio_samplerate", &dst_samplerate,
+                                       "content_audio_channels", &dst_channels,
+                                       NULL);
 
-                       LOGD("save adjust_subtitle_pos in player") ;
-               }
-               break;
+               LOGD("apply the decoded pcm format - format: %s(%d), samplerate : %d, channel: %d",
+                               dst_format, dst_len, dst_samplerate, dst_channels);
 
-       default:
-               {
-                       LOGW("invalid format.\n");
-                       MMPLAYER_FLEAVE();
-                       return MM_ERROR_INVALID_ARGUMENT;
+               /* If there is no enough information, set it to platform default value. */
+               if (dst_format == NULL || util_convert_audio_pcm_str_to_media_format_mime(dst_format) == MEDIA_FORMAT_MAX) {
+                       LOGD("set platform default format");
+                       dst_format = DEFAULT_PCM_OUT_FORMAT;
                }
+               if (dst_samplerate <= 0) dst_samplerate = DEFAULT_PCM_OUT_SAMPLERATE;
+               if (dst_channels <= 0)   dst_channels = DEFAULT_PCM_OUT_CHANNEL;
        }
 
-       MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
-}
-static int __gst_adjust_video_position(mm_player_t* player, int offset)
-{
-       MMPLAYER_FENTER();
-       LOGD("adjusting video_pos in player") ;
-       int current_pos = 0;
-       /* check player and videobin are created */
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       if (!player->pipeline->videobin ||
-                       !player->pipeline->videobin[MMPLAYER_V_SINK].gst) {
-               LOGD("no video pipeline or sink is there");
-               return MM_ERROR_PLAYER_INVALID_STATE ;
-       }
-       if (offset == 0) {
-               LOGD("nothing to do\n");
-               MMPLAYER_FLEAVE();
-               return MM_ERROR_NONE;
-       }
-       if (__gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, (unsigned long*)&current_pos) != MM_ERROR_NONE) {
-               LOGD("failed to get current position");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-       if ((current_pos - offset) < GST_TIME_AS_MSECONDS(player->duration)) {
-               LOGD("enter video delay is valid");
-       } else {
-               LOGD("enter video delay is crossing content boundary");
-               return MM_ERROR_INVALID_ARGUMENT ;
-       }
-       g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "ts-offset", ((gint64) offset * G_GINT64_CONSTANT(1000000)), NULL);
-       LOGD("video delay has been done");
-       MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
-}
-
-static void
-__gst_appsrc_feed_data_mem(GstElement *element, guint size, gpointer user_data)
-{
-       GstElement *appsrc = element;
-       MMPlayerInputBuffer *buf = (MMPlayerInputBuffer *)user_data;
-       GstBuffer *buffer = NULL;
-       GstFlowReturn ret = GST_FLOW_OK;
-       gint len = size;
-
-       MMPLAYER_RETURN_IF_FAIL(element);
-       MMPLAYER_RETURN_IF_FAIL(buf);
-
-       buffer = gst_buffer_new();
+       /* 3. create capsfilter */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_EXTRACT_CAPS, "capsfilter", "audio-ext-caps", *bucket, player);
+       caps = gst_caps_new_simple("audio/x-raw",
+                       "format", G_TYPE_STRING, dst_format,
+                       "rate", G_TYPE_INT, dst_samplerate,
+                       "channels", G_TYPE_INT, dst_channels,
+                       NULL);
 
-       if (buf->offset >= buf->len) {
-               LOGD("call eos appsrc\n");
-               g_signal_emit_by_name(appsrc, "end-of-stream", &ret);
-               return;
-       }
+       caps_str = gst_caps_to_string(caps);
+       LOGD("new caps : %s", caps_str);
 
-       if (buf->len - buf->offset < size)
-               len = buf->len - buf->offset;
+       g_object_set(GST_ELEMENT(audiobin[MMPLAYER_A_EXTRACT_CAPS].gst), "caps", caps, NULL);
 
-       gst_buffer_insert_memory(buffer, -1, gst_memory_new_wrapped(0, (guint8 *)(buf->buf + buf->offset), len, 0, len, NULL, NULL));
-       GST_BUFFER_OFFSET(buffer) = (guint64)buf->offset;
-       GST_BUFFER_OFFSET_END(buffer) = (guint64)(buf->offset + len);
+       /* clean */
+       gst_caps_unref(caps);
+       MMPLAYER_FREEIF(caps_str);
 
-       //LOGD("feed buffer %p, offset %u-%u length %u", buffer, buf->offset, (buf->offset+len), len);
-       g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret);
+       /* 4-1. create deinterleave to extract pcm for each channel */
+       if (player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_DEINTERLEAVE) {
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_EXTRACT_DEINTERLEAVE, "deinterleave", "deinterleave", *bucket, player);
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_EXTRACT_DEINTERLEAVE].gst), "keep-positions", TRUE, NULL);
 
-       buf->offset += len;
-}
+               /* 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);
+       } else {
+       /* 4-2. create fakesink to extract interlevaed pcm */
+               LOGD("add audio fakesink for interleaved audio");
+               MMPLAYER_CREATE_ELEMENT(audiobin, extract_sink_id, "fakesink", "fakeaudiosink", *bucket, player);
+               if (!(player->audio_extract_opt & MM_PLAYER_AUDIO_EXTRACT_NO_SYNC_WITH_CLOCK))
+                       g_object_set(G_OBJECT(audiobin[extract_sink_id].gst), "sync", TRUE, NULL);
+               g_object_set(G_OBJECT(audiobin[extract_sink_id].gst), "signal-handoffs", TRUE, NULL);
 
-static gboolean
-__gst_appsrc_seek_data_mem(GstElement *element, guint64 size, gpointer user_data)
-{
-       MMPlayerInputBuffer *buf = (MMPlayerInputBuffer *)user_data;
+               __mmplayer_add_signal_connection(player,
+                       G_OBJECT(audiobin[extract_sink_id].gst),
+                       MM_PLAYER_SIGNAL_TYPE_AUDIOBIN,
+                       "handoff",
+                       G_CALLBACK(__mmplayer_audio_stream_decoded_render_cb),
+                       (gpointer)player);
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(buf, FALSE);
+               __mmplayer_add_sink(player, audiobin[extract_sink_id].gst);
+       }
 
-       buf->offset  = (int)size;
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
 
-       return TRUE;
+ERROR: /* MMPLAYER_CREATE_ELEMENT */
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_PLAYER_INTERNAL;
 }
 
-static GstBusSyncReply
-__mmplayer_bus_sync_callback(GstBus * bus, GstMessage * message, gpointer data)
+static int
+__mmplayer_gst_make_audio_bin_element(mmplayer_t *player, GList **bucket)
 {
-       mm_player_t *player = (mm_player_t *)data;
-       GstBusSyncReply reply = GST_BUS_DROP;
+       int ret = MM_ERROR_NONE;
+       mmplayer_gst_element_t *audiobin = NULL;
+       GList *element_bucket = NULL;
 
-       if (!(player->pipeline && player->pipeline->mainbin)) {
-               LOGE("player pipeline handle is null");
-               return GST_BUS_PASS;
-       }
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline &&
+                               player->pipeline->audiobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       if (!__mmplayer_check_useful_message(player, message)) {
-               gst_message_unref(message);
-               return GST_BUS_DROP;
-       }
+       audiobin = player->pipeline->audiobin;
 
-       switch (GST_MESSAGE_TYPE(message)) {
-       case GST_MESSAGE_STATE_CHANGED:
-               /* post directly for fast launch */
-               if (player->sync_handler) {
-                       __mmplayer_gst_callback(message, player);
-                       reply = GST_BUS_DROP;
-               } else
-                       reply = GST_BUS_PASS;
-               break;
-       case GST_MESSAGE_TAG:
-               __mmplayer_gst_extract_tag_from_msg(player, message);
+       if (player->build_audio_offload) { /* skip all the audio filters */
+               LOGD("create audio offload sink : %s", player->ini.audio_offload_sink_element);
 
-               #if 0 // debug
-               {
-                       GstTagList *tags = NULL;
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, player->ini.audio_offload_sink_element, "audiosink", element_bucket, player);
+               g_object_set(G_OBJECT(audiobin[MMPLAYER_A_SINK].gst), "sync", TRUE,
+                               "volume", player->sound.volume, "mute", player->sound.mute, NULL);
 
-                       gst_message_parse_tag(message, &tags);
-                       if (tags) {
-                               LOGE("TAGS received from element \"%s\".\n",
-                               GST_STR_NULL(GST_ELEMENT_NAME(GST_MESSAGE_SRC(message))));
+               __mmplayer_add_sink(player, audiobin[MMPLAYER_A_SINK].gst);
+               goto DONE;
+       }
 
-                               gst_tag_list_foreach(tags, print_tag, NULL);
-                               gst_tag_list_free(tags);
-                               tags = NULL;
-                       }
-                       break;
-               }
-               #endif
-               break;
+       /* FIXME: need to mention the supportable condition at API reference */
+       if (player->audio_decoded_cb && (!MMPLAYER_IS_RTSP_STREAMING(player)))
+               ret = __mmplayer_gst_make_audio_extract_sink(player, &element_bucket);
+       else
+               ret = __mmplayer_gst_make_audio_playback_sink(player, &element_bucket);
 
-       case GST_MESSAGE_DURATION_CHANGED:
-               __mmplayer_gst_handle_duration(player, message);
-               break;
-       case GST_MESSAGE_ASYNC_DONE:
-               /* NOTE:Don't call gst_callback directly
-                * because previous frame can be showed even though this message is received for seek.
-                */
-       default:
-               reply = GST_BUS_PASS;
-               break;
-       }
+       if (ret != MM_ERROR_NONE)
+               goto ERROR;
+DONE:
+       LOGD("success to make audio bin element");
+       *bucket = element_bucket;
 
-       if (reply == GST_BUS_DROP)
-               gst_message_unref(message);
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+
+ERROR:
+       LOGE("failed to make audio bin element");
+       g_list_free(element_bucket);
 
-       return reply;
+       *bucket = NULL;
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_PLAYER_INTERNAL;
 }
 
-static gboolean
-__mmplayer_gst_create_decoder(mm_player_t *player,
-                                                               MMPlayerTrackType track,
-                                                               GstPad* srcpad,
-                                                               enum MainElementID elemId,
-                                                               const gchar* name)
+static int
+__mmplayer_gst_create_audio_sink_bin(mmplayer_t *player)
 {
-       gboolean ret = TRUE;
-       GstPad *sinkpad = NULL;
+       mmplayer_gst_element_t *first_element = NULL;
+       mmplayer_gst_element_t *audiobin = NULL;
+       GstPad *pad = NULL;
+       GstPad *ghostpad = NULL;
+       GList *element_bucket = NULL;
+       int i = 0;
 
        MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player &&
-                                               player->pipeline &&
-                                               player->pipeline->mainbin, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL((track == MM_PLAYER_TRACK_TYPE_AUDIO || track == MM_PLAYER_TRACK_TYPE_VIDEO), FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL(srcpad, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL((player->pipeline->mainbin[elemId].gst == NULL), FALSE);
-
-       GstElement *decodebin = NULL;
-       GstCaps *dec_caps = NULL;
-
-       /* create decodebin */
-       decodebin = gst_element_factory_make("decodebin", name);
+       /* alloc handles */
+       audiobin = (mmplayer_gst_element_t *)g_try_malloc0(sizeof(mmplayer_gst_element_t) * MMPLAYER_A_NUM);
+       if (!audiobin) {
+               LOGE("failed to allocate memory for audiobin");
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;
+       }
 
-       if (!decodebin) {
-               LOGE("error : fail to create decodebin for %d decoder\n", track);
-               ret = FALSE;
+       /* create bin */
+       audiobin[MMPLAYER_A_BIN].id = MMPLAYER_A_BIN;
+       audiobin[MMPLAYER_A_BIN].gst = gst_bin_new("audiobin");
+       if (!audiobin[MMPLAYER_A_BIN].gst) {
+               LOGE("failed to create audiobin");
                goto ERROR;
        }
 
-       /* raw pad handling signal */
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
-                                                                               G_CALLBACK(__mmplayer_gst_decode_pad_added), player);
+       /* take it */
+       player->pipeline->audiobin = audiobin;
 
-       /* This signal is emitted whenever decodebin finds a new stream. It is emitted
-       before looking for any elements that can handle that stream.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select",
-                                                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_select), player);
+       /* create audio filters and audiosink */
+       if (__mmplayer_gst_make_audio_bin_element(player, &element_bucket) != MM_ERROR_NONE)
+               goto ERROR;
 
-       /* This signal is emitted when a element is added to the bin.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added",
-                                                                               G_CALLBACK(__mmplayer_gst_element_added), player);
+       /* adding created elements to bin */
+       LOGD("adding created elements to bin");
+       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(audiobin[MMPLAYER_A_BIN].gst), element_bucket))
+               goto ERROR;
 
-       if (!gst_bin_add(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), decodebin)) {
-               LOGE("failed to add new decodebin\n");
-               ret = FALSE;
+       /* linking elements in the bucket by added order. */
+       LOGD("Linking elements in the bucket by added order.");
+       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1)
                goto ERROR;
-       }
 
-       dec_caps = gst_pad_query_caps(srcpad, NULL);
-       if (dec_caps) {
-               //LOGD("got pad %s:%s , dec_caps %" GST_PTR_FORMAT, GST_DEBUG_PAD_NAME(srcpad), dec_caps);
-               g_object_set(G_OBJECT(decodebin), "sink-caps", dec_caps, NULL);
-               gst_caps_unref(dec_caps);
+       /* get first element's sinkpad for creating ghostpad */
+       first_element = (mmplayer_gst_element_t *)element_bucket->data;
+       if (!first_element) {
+               LOGE("failed to get first elem");
+               goto ERROR;
        }
 
-       player->pipeline->mainbin[elemId].id = elemId;
-       player->pipeline->mainbin[elemId].gst = decodebin;
+       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
+       if (!pad) {
+               LOGE("failed to get pad from first element of audiobin");
+               goto ERROR;
+       }
 
-       sinkpad = gst_element_get_static_pad(decodebin, "sink");
+       ghostpad = gst_ghost_pad_new("sink", pad);
+       if (!ghostpad) {
+               LOGE("failed to create ghostpad");
+               goto ERROR;
+       }
 
-       if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) {
-               LOGW("failed to link [%s:%s] to decoder\n", GST_DEBUG_PAD_NAME(srcpad));
-               gst_object_unref(GST_OBJECT(decodebin));
+       if (!gst_element_add_pad(audiobin[MMPLAYER_A_BIN].gst, ghostpad)) {
+               LOGE("failed to add ghostpad to audiobin");
+               goto ERROR;
        }
 
-       if (GST_STATE_CHANGE_FAILURE == gst_element_sync_state_with_parent(decodebin))
-               LOGE("failed to sync second level decodebin state with parent\n");
+       gst_object_unref(pad);
+
+       g_list_free(element_bucket);
+       MMPLAYER_FLEAVE();
 
-       LOGD("Total num of %d tracks = %d \n", track, player->selector[track].total_track_num);
+       return MM_ERROR_NONE;
 
 ERROR:
-       if (sinkpad) {
-               gst_object_unref(GST_OBJECT(sinkpad));
-               sinkpad = NULL;
+       LOGD("ERROR : releasing audiobin");
+
+       if (pad)
+               gst_object_unref(GST_OBJECT(pad));
+
+       if (ghostpad)
+               gst_object_unref(GST_OBJECT(ghostpad));
+
+       if (element_bucket)
+               g_list_free(element_bucket);
+
+       /* release element which are not added to bin */
+       for (i = 1; i < MMPLAYER_A_NUM; i++) {
+               /* NOTE : skip bin */
+               if (audiobin[i].gst) {
+                       GstObject *parent = NULL;
+                       parent = gst_element_get_parent(audiobin[i].gst);
+
+                       if (!parent) {
+                               gst_object_unref(GST_OBJECT(audiobin[i].gst));
+                               audiobin[i].gst = NULL;
+                       } else
+                               gst_object_unref(GST_OBJECT(parent));
+               }
        }
-       MMPLAYER_FLEAVE();
 
-       return ret;
+       /* release audiobin with it's childs */
+       if (audiobin[MMPLAYER_A_BIN].gst)
+               gst_object_unref(GST_OBJECT(audiobin[MMPLAYER_A_BIN].gst));
+
+       MMPLAYER_FREEIF(audiobin);
+
+       player->pipeline->audiobin = NULL;
+
+       return MM_ERROR_PLAYER_INTERNAL;
 }
 
-/**
- * This function is to create  audio or video pipeline for playing.
- *
- * @param      player          [in]    handle of player
- *
- * @return     This function returns zero on success.
- * @remark
- * @see
- */
-static int
-__mmplayer_gst_create_pipeline(mm_player_t* player)
+static guint32
+_mmplayer_convert_fourcc_string_to_value(const gchar *format_name)
 {
-       GstBus  *bus = NULL;
-       MMPlayerGstElement *mainbin = NULL;
-       MMHandleType attrs = 0;
-       GstElement* element = NULL;
-       GstElement* elem_src_audio = NULL;
-       GstElement* elem_src_subtitle = NULL;
-       GstElement* es_video_queue = NULL;
-       GstElement* es_audio_queue = NULL;
-       GstElement* es_subtitle_queue = NULL;
-       GList* element_bucket = NULL;
-       gboolean need_state_holder = TRUE;
-       gint i = 0;
-#ifdef SW_CODEC_ONLY
-       int surface_type = 0;
-#endif
-       MMPLAYER_FENTER();
+       return format_name[0] | (format_name[1] << 8) | (format_name[2] << 16) | (format_name[3] << 24);
+}
 
+int
+_mmplayer_video_stream_release_bo(mmplayer_t *player, void *bo)
+{
+       int ret = MM_ERROR_NONE;
+       GList *l = NULL;
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(bo, MM_ERROR_INVALID_ARGUMENT);
 
-       /* get profile attribute */
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if (!attrs) {
-               LOGE("cannot get content attribute\n");
-               goto INIT_ERROR;
-       }
+       MMPLAYER_VIDEO_BO_LOCK(player);
 
-       /* create pipeline handles */
-       if (player->pipeline) {
-               LOGW("pipeline should be released before create new one\n");
-               goto INIT_ERROR;
+       if (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 && tmp->bo == bo) {
+                               tmp->used = FALSE;
+                               LOGD("release bo %p", bo);
+                               tbm_bo_unref(tmp->bo);
+                               MMPLAYER_VIDEO_BO_UNLOCK(player);
+                               MMPLAYER_VIDEO_BO_SIGNAL(player);
+                               return ret;
+                       }
+               }
+       } else {
+               /* hw codec is running or the list was reset for DRC. */
+               LOGW("there is no bo list.");
        }
+       MMPLAYER_VIDEO_BO_UNLOCK(player);
 
-       player->video360_metadata.is_spherical = -1;
-       player->is_openal_plugin_used = FALSE;
+       LOGW("failed to find bo %p", bo);
+       return ret;
+}
 
-       player->pipeline = (MMPlayerGstPipelineInfo*) g_malloc0(sizeof(MMPlayerGstPipelineInfo));
-       if (player->pipeline == NULL)
-               goto INIT_ERROR;
+static void
+__mmplayer_video_stream_destroy_bo_list(mmplayer_t *player)
+{
+       GList *l = NULL;
 
-       memset(player->pipeline, 0, sizeof(MMPlayerGstPipelineInfo)); /* g_malloc0 did this job already */
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player);
 
-       /* create mainbin */
-       mainbin = (MMPlayerGstElement*) g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM);
-       if (mainbin == NULL)
-               goto INIT_ERROR;
+       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);
+               player->video_bo_list = NULL;
+       }
+       player->video_bo_size = 0;
+       MMPLAYER_VIDEO_BO_UNLOCK(player);
+
+       MMPLAYER_FLEAVE();
+       return;
+}
 
-       memset(mainbin, 0, sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM); /* g_malloc0 did this job already */
+static void *
+__mmplayer_video_stream_get_bo(mmplayer_t *player, int size)
+{
+       GList *l = NULL;
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, NULL);
+       gboolean ret = TRUE;
 
-       /* create pipeline */
-       mainbin[MMPLAYER_M_PIPE].id = MMPLAYER_M_PIPE;
-       mainbin[MMPLAYER_M_PIPE].gst = gst_pipeline_new("player");
-       if (!mainbin[MMPLAYER_M_PIPE].gst) {
-               LOGE("failed to create pipeline\n");
-               goto INIT_ERROR;
+       /* check DRC, if it is, destroy the prev bo list to create again */
+       if (player->video_bo_size != size) {
+               LOGD("video size is changed: %d -> %d", player->video_bo_size, size);
+               __mmplayer_video_stream_destroy_bo_list(player);
+               player->video_bo_size = size;
        }
-       player->demux_pad_index = 0;
-       player->subtitle_language_list = NULL;
 
-       player->is_subtitle_force_drop = FALSE;
-       player->last_multiwin_status = FALSE;
+       MMPLAYER_VIDEO_BO_LOCK(player);
 
-       _mmplayer_track_initialize(player);
-       __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
+       if ((!player->video_bo_list) ||
+               (g_list_length(player->video_bo_list) < player->ini.num_of_video_bo)) {
 
-       /* create source element */
-       switch (player->profile.uri_type) {
-       /* rtsp streamming */
-       case MM_PLAYER_URI_TYPE_URL_RTSP:
-               {
-                       gchar *user_agent;
+               /* create bo list */
+               int idx = 0;
+               LOGD("Create bo list for decoded video stream(num:%d)", player->ini.num_of_video_bo);
 
-                       element = gst_element_factory_make("rtspsrc", "rtsp source");
+               if (player->video_bo_list) {
+                       /* if bo list did not created all, try it again. */
+                       idx = g_list_length(player->video_bo_list);
+                       LOGD("bo list exist(len: %d)", idx);
+               }
 
-                       if (!element) {
-                               LOGE("failed to create streaming source element\n");
+               for (; idx < player->ini.num_of_video_bo; idx++) {
+                       mmplayer_video_bo_info_t *bo_info = g_new(mmplayer_video_bo_info_t, 1);
+                       if (!bo_info) {
+                               LOGE("Fail to alloc bo_info.");
                                break;
                        }
+                       bo_info->bo = tbm_bo_alloc(player->bufmgr, size, TBM_BO_DEFAULT);
+                       if (!bo_info->bo) {
+                               LOGE("Fail to tbm_bo_alloc.");
+                               MMPLAYER_FREEIF(bo_info);
+                               break;
+                       }
+                       bo_info->used = FALSE;
+                       player->video_bo_list = g_list_append(player->video_bo_list, bo_info);
+               }
 
-                       /* make it zero */
-                       user_agent = NULL;
-
-                       /* get attribute */
-                       mm_attrs_get_string_by_name(attrs, "streaming_user_agent", &user_agent);
+               /* 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;
 
-                       SECURE_LOGD("user_agent : %s\n", user_agent);
+               if (idx == 0) {
+                       MMPLAYER_VIDEO_BO_UNLOCK(player);
+                       return NULL;
+               }
 
-                       /* setting property to streaming source */
-                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-                       if (user_agent)
-                               g_object_set(G_OBJECT(element), "user-agent", user_agent, NULL);
+               LOGD("Num of video buffers(%d/%d)", player->video_num_buffers, player->video_extra_num_buffers);
+       }
 
-                       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(element), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
-                               G_CALLBACK(__mmplayer_gst_rtp_dynamic_pad), player);
-                       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(element), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
-                               G_CALLBACK(__mmplayer_gst_rtp_no_more_pads), player);
+       while (TRUE) {
+               /* get bo from 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 && (tmp->used == FALSE)) {
+                               LOGD("found bo %p to use", tmp->bo);
+                               tmp->used = TRUE;
+                               MMPLAYER_VIDEO_BO_UNLOCK(player);
+                               return tbm_bo_ref(tmp->bo);
+                       }
+               }
+               if (!ret) {
+                       LOGE("failed to get bo in %d timeout", player->ini.video_bo_timeout);
+                       MMPLAYER_VIDEO_BO_UNLOCK(player);
+                       return NULL;
                }
-               break;
 
-       /* http streaming*/
-       case MM_PLAYER_URI_TYPE_URL_HTTP:
-               {
-                       gchar *user_agent, *cookies, **cookie_list;
-                       gint http_timeout = DEFAULT_HTTP_TIMEOUT;
-                       user_agent = cookies = NULL;
-                       cookie_list = NULL;
-                       gint mode = MM_PLAYER_PD_MODE_NONE;
+               if (player->ini.video_bo_timeout <= 0) {
+                       MMPLAYER_VIDEO_BO_WAIT(player);
+               } else {
+                       gint64 timeout = g_get_monotonic_time() + player->ini.video_bo_timeout * G_TIME_SPAN_SECOND;
+                       ret = MMPLAYER_VIDEO_BO_WAIT_UNTIL(player, timeout);
+               }
+               continue;
+       }
+}
 
-                       mm_attrs_get_int_by_name(attrs, "pd_mode", &mode);
+static void
+__mmplayer_video_stream_decoded_preroll_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data)
+{
+       mmplayer_t *player = (mmplayer_t *)data;
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->video_decoded_cb);
 
-                       player->pd_mode = mode;
+       /* send prerolled pkt */
+       player->video_stream_prerolled = false;
 
-                       LOGD("http playback, PD mode : %d\n", player->pd_mode);
+       __mmplayer_video_stream_decoded_render_cb(object, buffer, pad, data);
 
-                       if (!MMPLAYER_IS_HTTP_PD(player)) {
-                               element = gst_element_factory_make(player->ini.httpsrc_element, "http_streaming_source");
-                               if (!element) {
-                                       LOGE("failed to create http streaming source element[%s].\n", player->ini.httpsrc_element);
-                                       break;
-                               }
-                               LOGD("using http streamming source [%s].\n", player->ini.httpsrc_element);
+       /* not to send prerolled pkt again */
+       player->video_stream_prerolled = true;
+}
 
-                               /* get attribute */
-                               mm_attrs_get_string_by_name(attrs, "streaming_cookie", &cookies);
-                               mm_attrs_get_string_by_name(attrs, "streaming_user_agent", &user_agent);
+static void
+__mmplayer_video_stream_decoded_render_cb(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data)
+{
+       mmplayer_t *player = (mmplayer_t *)data;
+       mmplayer_video_decoded_data_info_t *stream = NULL;
+       GstMemory *mem = NULL;
 
-                               if (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT) {
-                                       LOGD("get timeout from ini\n");
-                                       http_timeout = player->ini.http_timeout;
-                               }
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player);
+       MMPLAYER_RETURN_IF_FAIL(player->video_decoded_cb);
 
-                               /* get attribute */
-                               SECURE_LOGD("location : %s\n", player->profile.uri);
-                               SECURE_LOGD("cookies : %s\n", cookies);
-                               SECURE_LOGD("user_agent :  %s\n",  user_agent);
-                               LOGD("timeout : %d\n",  http_timeout);
-
-                               /* setting property to streaming source */
-                               g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-                               g_object_set(G_OBJECT(element), "timeout", http_timeout, NULL);
-                               g_object_set(G_OBJECT(element), "blocksize", (unsigned long)(64*1024), NULL);
-
-                               /* parsing cookies */
-                               if ((cookie_list = util_get_cookie_list((const char*)cookies))) {
-                                       g_object_set(G_OBJECT(element), "cookies", cookie_list, NULL);
-                                       g_strfreev(cookie_list);
-                               }
-                               if (user_agent)
-                                       g_object_set(G_OBJECT(element), "user-agent", user_agent, NULL);
+       if (player->video_stream_prerolled) {
+               player->video_stream_prerolled = false;
+               LOGD("skip the prerolled pkt not to send it again");
+               return;
+       }
 
-                               if (MMPLAYER_URL_HAS_DASH_SUFFIX(player))
-                                       LOGW("it's dash. and it's still experimental feature.");
-                       } else {
-                               // progressive download
-                               gchar* location = NULL;
+       /* clear stream data structure */
+       stream = __mmplayer_create_stream_from_pad(pad);
+       if (!stream) {
+               LOGE("failed to alloc stream");
+               return;
+       }
 
-                               if (player->pd_mode == MM_PLAYER_PD_MODE_URI) {
-                                       gchar *path = NULL;
+       __mmplayer_get_video_angle(player, NULL, &stream->orientation);
 
-                                       mm_attrs_get_string_by_name(attrs, "pd_location", &path);
+       /* set size and timestamp */
+       mem = gst_buffer_peek_memory(buffer, 0);
+       stream->length_total = gst_memory_get_sizes(mem, NULL, NULL);
+       stream->timestamp = (unsigned int)(GST_TIME_AS_MSECONDS(GST_BUFFER_PTS(buffer))); /* nano sec -> mili sec */
 
-                                       MMPLAYER_FREEIF(player->pd_file_save_path);
+       /* check zero-copy */
+       if (player->set_mode.video_zc &&
+               player->set_mode.video_export &&
+               gst_is_tizen_memory(mem)) {
+               __mmplayer_zerocopy_set_stride_elevation_bo(stream, mem);
+               stream->internal_buffer = gst_buffer_ref(buffer);
+       } else { /* sw codec */
+               if (!__mmplayer_swcodec_set_stride_elevation(stream))
+                       goto ERROR;
 
-                                       LOGD("PD Location : %s\n", path);
+               if (!__mmplayer_swcodec_set_bo(player, stream, mem))
+                       goto ERROR;
+       }
 
-                                       if (path) {
-                                               if (!util_get_storage_info(path, &player->storage_info[MMPLAYER_PATH_VOD])) {
-                                                       LOGE("failed to get storage info");
-                                                       break;
-                                               }
-                                               player->pd_file_save_path = g_strdup(path);
-                                       } else {
-                                               LOGE("can't find pd location so, it should be set \n");
-                                               break;
-                                       }
-                               }
+       if (!player->video_decoded_cb(stream, player->video_decoded_cb_user_param)) {
+               LOGE("failed to send video decoded data.");
+               goto ERROR;
+       }
 
-                               element = gst_element_factory_make("pdpushsrc", "PD pushsrc");
-                               if (!element) {
-                                       LOGE("failed to create PD push source element[%s].\n", "pdpushsrc");
-                                       break;
-                               }
+       return;
 
-                               if (player->pd_mode == MM_PLAYER_PD_MODE_URI)
-                                       g_object_set(G_OBJECT(element), "location", player->pd_file_save_path, NULL);
-                               else
-                                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-                               g_object_get(element, "location", &location, NULL);
-                               LOGD("PD_LOCATION [%s].\n", location);
-                               if (location)
-                                       g_free(location);
-                       }
+ERROR:
+       LOGE("release video stream resource.");
+       if (gst_is_tizen_memory(mem)) {
+               int i = 0;
+               for (i = 0 ; i < MM_VIDEO_BUFFER_PLANE_MAX ; i++) {
+                       if (stream->bo[i])
+                               tbm_bo_unref(stream->bo[i]);
                }
-               break;
 
-       /* file source */
-       case MM_PLAYER_URI_TYPE_FILE:
-               {
-                       LOGD("using filesrc for 'file://' handler.\n");
-                       if (!util_get_storage_info(player->profile.uri, &player->storage_info[MMPLAYER_PATH_VOD])) {
-                               LOGE("failed to get storage info");
-                               break;
-                       }
+               /* unref gst buffer */
+               if (stream->internal_buffer)
+                       gst_buffer_unref(stream->internal_buffer);
+       } else {
+               if (stream->bo[0])
+                       _mmplayer_video_stream_release_bo(player, stream->bo[0]);
+       }
+       MMPLAYER_FREEIF(stream);
+       return;
+}
 
-                       element = gst_element_factory_make("filesrc", "source");
-                       if (!element) {
-                               LOGE("failed to create filesrc\n");
-                               break;
-                       }
+static void
+__mmplayer_gst_set_video360_property(mmplayer_t *player)
+{
+       mmplayer_gst_element_t *videobin = NULL;
 
-                       g_object_set(G_OBJECT(element), "location", (player->profile.uri)+7, NULL);     /* uri+7 -> remove "file:// */
-               }
-               break;
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player && player->pipeline && player->pipeline->videobin);
 
-       case MM_PLAYER_URI_TYPE_SS:
-               {
-                       gint http_timeout = DEFAULT_HTTP_TIMEOUT;
-                       element = gst_element_factory_make("souphttpsrc", "http streaming source");
-                       if (!element) {
-                               LOGE("failed to create http streaming source element[%s]", player->ini.httpsrc_element);
-                               break;
-                       }
+       videobin = player->pipeline->videobin;
 
-                       if (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT) {
-                               LOGD("get timeout from ini\n");
-                               http_timeout = player->ini.http_timeout;
-                       }
+       /* Set spatial media metadata and/or user settings to the element.
+        * */
+       g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
+                       "projection-type", player->video360_metadata.projection_type, NULL);
 
-                       /* setting property to streaming source */
-                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-                       g_object_set(G_OBJECT(element), "timeout", http_timeout, NULL);
-               }
-               break;
-       case MM_PLAYER_URI_TYPE_MS_BUFF:
-               {
-                       LOGD("MS buff src is selected\n");
+       g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
+                       "stereo-mode", player->video360_metadata.stereo_mode, NULL);
 
-                       if (player->v_stream_caps) {
-                               element = gst_element_factory_make("appsrc", "video_appsrc");
-                               if (!element) {
-                                       LOGF("failed to create video app source element[appsrc].\n");
-                                       break;
-                               }
+       if (player->video360_metadata.full_pano_width_pixels &&
+                       player->video360_metadata.full_pano_height_pixels &&
+                       player->video360_metadata.cropped_area_image_width &&
+                       player->video360_metadata.cropped_area_image_height) {
+               g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
+                               "projection-bounds-top", player->video360_metadata.cropped_area_top,
+                               "projection-bounds-bottom", player->video360_metadata.full_pano_height_pixels -
+                                               player->video360_metadata.cropped_area_top - player->video360_metadata.cropped_area_image_height,
+                               "projection-bounds-left", player->video360_metadata.cropped_area_left,
+                               "projection-bounds-right", player->video360_metadata.full_pano_width_pixels -
+                                               player->video360_metadata.cropped_area_left - player->video360_metadata.cropped_area_image_width,
+                               NULL);
+       }
 
-                               if (player->a_stream_caps) {
-                                       elem_src_audio = gst_element_factory_make("appsrc", "audio_appsrc");
-                                       if (!elem_src_audio) {
-                                               LOGF("failed to create audio app source element[appsrc].\n");
-                                               break;
-                                       }
-                               }
-                       } else if (player->a_stream_caps) {
-                               /* no video, only audio pipeline*/
-                               element = gst_element_factory_make("appsrc", "audio_appsrc");
-                               if (!element) {
-                                       LOGF("failed to create audio app source element[appsrc].\n");
-                                       break;
-                               }
-                       }
+       if (player->video360_horizontal_fov && player->video360_vertical_fov) {
+               g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
+                               "horizontal-fov", player->video360_horizontal_fov,
+                               "vertical-fov", player->video360_vertical_fov, NULL);
+       }
 
-                       if (player->s_stream_caps) {
-                               elem_src_subtitle = gst_element_factory_make("appsrc", "subtitle_appsrc");
-                               if (!elem_src_subtitle) {
-                                       LOGF("failed to create subtitle app source element[appsrc].\n");
-                                       break;
-                               }
-                       }
+       if (player->video360_zoom <= VIDEO360_MAX_ZOOM && player->video360_zoom > 1.0f) {
+               g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
+                               "zoom", 1.0f / player->video360_zoom, NULL);
+       }
 
-                       LOGD("setting app sources properties.\n");
-                       LOGD("location : %s\n", player->profile.uri);
-
-                       if (player->v_stream_caps && element) {
-                               g_object_set(G_OBJECT(element), "format", GST_FORMAT_TIME,
-                                                                                           "blocksize", (guint)1048576,        /* size of many video frames are larger than default blocksize as 4096 */
-                                                                                               "caps", player->v_stream_caps, NULL);
-
-                               if (player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_VIDEO] > 0)
-                                       g_object_set(G_OBJECT(element), "max-bytes", player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_VIDEO], NULL);
-                               if (player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_VIDEO] > 0)
-                                       g_object_set(G_OBJECT(element), "min-percent", player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_VIDEO], NULL);
-
-                               /*Fix Seek External Demuxer:  set audio and video appsrc as seekable */
-                               gst_app_src_set_stream_type((GstAppSrc*)G_OBJECT(element), GST_APP_STREAM_TYPE_SEEKABLE);
-                               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
-                                                                                                               G_CALLBACK(__gst_seek_video_data), player);
-
-                               if (player->a_stream_caps && elem_src_audio) {
-                                       g_object_set(G_OBJECT(elem_src_audio), "format", GST_FORMAT_TIME,
-                                                                                                                       "caps", player->a_stream_caps, NULL);
-
-                                       if (player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_AUDIO] > 0)
-                                               g_object_set(G_OBJECT(elem_src_audio), "max-bytes", player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_AUDIO], NULL);
-                                       if (player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_AUDIO] > 0)
-                                               g_object_set(G_OBJECT(elem_src_audio), "min-percent", player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_AUDIO], NULL);
-
-                                       /*Fix Seek External Demuxer:  set audio and video appsrc as seekable */
-                                       gst_app_src_set_stream_type((GstAppSrc*)G_OBJECT(elem_src_audio), GST_APP_STREAM_TYPE_SEEKABLE);
-                                       MMPLAYER_SIGNAL_CONNECT(player, elem_src_audio, MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
-                                                                                                               G_CALLBACK(__gst_seek_audio_data), player);
-                               }
-                       } else if (player->a_stream_caps && element) {
-                               g_object_set(G_OBJECT(element), "format", GST_FORMAT_TIME,
-                                                                                               "caps", player->a_stream_caps, NULL);
-
-                               if (player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_AUDIO] > 0)
-                                       g_object_set(G_OBJECT(element), "max-bytes", player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_AUDIO], NULL);
-                               if (player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_AUDIO] > 0)
-                                       g_object_set(G_OBJECT(element), "min-percent", player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_AUDIO], NULL);
-
-                               /*Fix Seek External Demuxer:  set audio and video appsrc as seekable */
-                               gst_app_src_set_stream_type((GstAppSrc*)G_OBJECT(element), GST_APP_STREAM_TYPE_SEEKABLE);
-                               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
-                                                                                                                       G_CALLBACK(__gst_seek_audio_data), player);
-                       }
+       if (player->video360_yaw_radians <= M_PI &&
+                       player->video360_yaw_radians >= -M_PI &&
+                       player->video360_pitch_radians <= M_PI_2 &&
+                       player->video360_pitch_radians >= -M_PI_2) {
+               g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
+                               "pose-yaw", (int)(player->video360_yaw_radians * 180.0 / M_PI),
+                               "pose-pitch", (int)(player->video360_pitch_radians * 180.0 / M_PI), NULL);
+       } else if (player->video360_metadata.init_view_heading || player->video360_metadata.init_view_pitch) {
+               g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
+                               "pose-yaw", player->video360_metadata.init_view_heading,
+                               "pose-pitch", player->video360_metadata.init_view_pitch, NULL);
+       }
 
-                       if (player->s_stream_caps && elem_src_subtitle) {
-                               g_object_set(G_OBJECT(elem_src_subtitle), "format", GST_FORMAT_TIME,
-                                                                                                                "caps", player->s_stream_caps, NULL);
+       g_object_set(G_OBJECT(videobin[MMPLAYER_V_360].gst),
+                       "passthrough", !player->is_video360_enabled, NULL);
 
-                               if (player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_TEXT] > 0)
-                                       g_object_set(G_OBJECT(elem_src_subtitle), "max-bytes", player->media_stream_buffer_max_size[MM_PLAYER_STREAM_TYPE_TEXT], NULL);
-                               if (player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_TEXT] > 0)
-                                       g_object_set(G_OBJECT(elem_src_subtitle), "min-percent", player->media_stream_buffer_min_percent[MM_PLAYER_STREAM_TYPE_TEXT], NULL);
 
-                               gst_app_src_set_stream_type((GstAppSrc*)G_OBJECT(elem_src_subtitle), GST_APP_STREAM_TYPE_SEEKABLE);
+       MMPLAYER_FLEAVE();
+}
 
-                               MMPLAYER_SIGNAL_CONNECT(player, elem_src_subtitle, MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
-                                                                                                                               G_CALLBACK(__gst_seek_subtitle_data), player);
-                       }
+static int
+__mmplayer_gst_create_video_filters(mmplayer_t *player, MMDisplaySurfaceType surface_type, GList **bucket)
+{
+       gchar *video_csc = "videoconvert"; /* default colorspace converter */
+       GList *element_bucket = NULL;
 
-                       if (player->v_stream_caps && element) {
-                               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_feed_video_data), player);
-                               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "enough-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_enough_video_data), player);
-
-                               if (player->a_stream_caps && elem_src_audio) {
-                                       MMPLAYER_SIGNAL_CONNECT(player, elem_src_audio, MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_feed_audio_data), player);
-                                       MMPLAYER_SIGNAL_CONNECT(player, elem_src_audio, MM_PLAYER_SIGNAL_TYPE_OTHERS, "enough-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_enough_audio_data), player);
-                               }
-                       } else if (player->a_stream_caps && element) {
-                               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_feed_audio_data), player);
-                               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "enough-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_enough_audio_data), player);
-                       }
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->videobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-                       if (player->s_stream_caps && elem_src_subtitle)
-                               MMPLAYER_SIGNAL_CONNECT(player, elem_src_subtitle, MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
-                                                                                                               G_CALLBACK(__gst_appsrc_feed_subtitle_data), player);
+       /* create video360 filter */
+       if (player->is_360_feature_enabled && player->is_content_spherical) {
+               LOGD("create video360 element");
+               MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_360, "video360", "video-360", element_bucket, player);
+               __mmplayer_gst_set_video360_property(player);
+               goto EXIT;
+       }
 
-                       need_state_holder = FALSE;
+       if (surface_type != MM_DISPLAY_SURFACE_OVERLAY || player->set_mode.video_zc) {
+               LOGD("skip creating the videoconv and rotator");
+               return MM_ERROR_NONE;
+       }
 
-                       mm_attrs_set_int_by_name(attrs, "profile_prepare_async", TRUE);
-                       if (mmf_attrs_commit(attrs)) /* return -1 if error */
-                               LOGE("failed to commit\n");
-               }
-               break;
-       /* appsrc */
-       case MM_PLAYER_URI_TYPE_MEM:
-               {
-                       guint64 stream_type = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
+       /* in case of sw codec & overlay surface type, except 360 playback.
+        * if libav video decoder is selected, videoconvert is required to render the shm wl-buffer which support RGB only via tizenwlsink. */
+       LOGD("create video converter: %s", video_csc);
+       MMPLAYER_CREATE_ELEMENT(player->pipeline->videobin, MMPLAYER_V_CONV, video_csc, "video converter", element_bucket, player);
 
-                       LOGD("mem src is selected\n");
+EXIT:
+       *bucket = element_bucket;
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
 
-                       element = gst_element_factory_make("appsrc", "mem-source");
-                       if (!element) {
-                               LOGE("failed to create appsrc element\n");
-                               break;
-                       }
+ERROR: /* refer MMPLAYER_CREATE_ELEMENT */
+       g_list_free(element_bucket);
 
-                       g_object_set(element, "stream-type", stream_type, NULL);
-                       g_object_set(element, "size", player->profile.input_mem.len, NULL);
-                       g_object_set(element, "blocksize", (guint64)20480, NULL);
+       *bucket = NULL;
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_PLAYER_INTERNAL;
+}
 
-                       MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "seek-data",
-                               G_CALLBACK(__gst_appsrc_seek_data_mem), &player->profile.input_mem);
-                       MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_OTHERS, "need-data",
-                               G_CALLBACK(__gst_appsrc_feed_data_mem), &player->profile.input_mem);
-               }
-               break;
-       case MM_PLAYER_URI_TYPE_URL:
-               break;
+static gchar *
+__mmplayer_get_videosink_factory_name(mmplayer_t *player, MMDisplaySurfaceType surface_type)
+{
+       gchar *factory_name = NULL;
 
-       case MM_PLAYER_URI_TYPE_TEMP:
+       switch (surface_type) {
+       case MM_DISPLAY_SURFACE_OVERLAY:
+               if (strlen(player->ini.videosink_element_overlay) > 0)
+                       factory_name = player->ini.videosink_element_overlay;
+               break;
+       case MM_DISPLAY_SURFACE_REMOTE:
+       case MM_DISPLAY_SURFACE_NULL:
+               if (strlen(player->ini.videosink_element_fake) > 0)
+                       factory_name = player->ini.videosink_element_fake;
                break;
-
-       case MM_PLAYER_URI_TYPE_NONE:
        default:
+               LOGE("unidentified surface type");
                break;
        }
 
-       /* check source element is OK */
-       if (!element) {
-               LOGE("no source element was created.\n");
-               goto INIT_ERROR;
-       }
-
-       /* take source element */
-       mainbin[MMPLAYER_M_SRC].id = MMPLAYER_M_SRC;
-       mainbin[MMPLAYER_M_SRC].gst = element;
-       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_SRC]);
-
-       if ((MMPLAYER_IS_STREAMING(player)) && (player->streamer == NULL)) {
-               player->streamer = __mm_player_streaming_create();
-               __mm_player_streaming_initialize(player->streamer);
-       }
-
-       if (MMPLAYER_IS_HTTP_PD(player)) {
-               gint pre_buffering_time = player->streamer->buffering_req.prebuffer_time;
-
-               LOGD("Picked queue2 element(pre buffer : %d ms)....\n", pre_buffering_time);
-               element = gst_element_factory_make("queue2", "queue2");
-               if (!element) {
-                       LOGE("failed to create http streaming buffer element\n");
-                       goto INIT_ERROR;
-               }
+       LOGD("surface_type %d, videosink is %s", surface_type, factory_name);
+       return factory_name;
+}
 
-               /* take it */
-               mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER;
-               mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = element;
-               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_MUXED_S_BUFFER]);
+static int
+__mmplayer_gst_set_videosink_property(mmplayer_t *player, MMDisplaySurfaceType surface_type)
+{
+       gchar *factory_name = NULL;
+       mmplayer_gst_element_t *videobin = NULL;
+       MMHandleType attrs;
+       int gapless = 0;
 
-               pre_buffering_time = (pre_buffering_time > 0) ? (pre_buffering_time) : (player->ini.http_buffering_time);
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->videobin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-               player->streamer->is_pd_mode = TRUE;
+       videobin = player->pipeline->videobin;
+       factory_name = GST_OBJECT_NAME(gst_element_get_factory(videobin[MMPLAYER_V_SINK].gst));
 
-               __mm_player_streaming_set_queue2(player->streamer,
-                               element,
-                               TRUE,
-                               player->ini.http_max_size_bytes + PLAYER_PD_EXT_MAX_SIZE_BYTE,
-                               pre_buffering_time,
-                               1.0,
-                               player->ini.http_buffering_limit,
-                               MUXED_BUFFER_TYPE_MEM_QUEUE,
-                               NULL,
-                               0);
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if (!attrs) {
+               LOGE("cannot get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
        }
-       if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
-               if (player->v_stream_caps) {
-                       es_video_queue = gst_element_factory_make("queue2", "video_queue");
-                       if (!es_video_queue) {
-                               LOGE("create es_video_queue for es player failed\n");
-                               goto INIT_ERROR;
-                       }
-                       g_object_set(G_OBJECT(es_video_queue), "max-size-buffers", 2, NULL);
-                       mainbin[MMPLAYER_M_V_BUFFER].id = MMPLAYER_M_V_BUFFER;
-                       mainbin[MMPLAYER_M_V_BUFFER].gst = es_video_queue;
-                       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_V_BUFFER]);
-
-                       /* Adding audio appsrc to bucket */
-                       if (player->a_stream_caps && elem_src_audio) {
-                               mainbin[MMPLAYER_M_2ND_SRC].id = MMPLAYER_M_2ND_SRC;
-                               mainbin[MMPLAYER_M_2ND_SRC].gst = elem_src_audio;
-                               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_2ND_SRC]);
-
-                               es_audio_queue = gst_element_factory_make("queue2", "audio_queue");
-                               if (!es_audio_queue) {
-                                       LOGE("create es_audio_queue for es player failed\n");
-                                       goto INIT_ERROR;
-                               }
-                               g_object_set(G_OBJECT(es_audio_queue), "max-size-buffers", 2, NULL);
-
-                               mainbin[MMPLAYER_M_A_BUFFER].id = MMPLAYER_M_A_BUFFER;
-                               mainbin[MMPLAYER_M_A_BUFFER].gst = es_audio_queue;
-                               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_A_BUFFER]);
-                       }
-               } else if (player->a_stream_caps) {
-                       /* Only audio stream, no video */
-                       es_audio_queue = gst_element_factory_make("queue2", "audio_queue");
-                       if (!es_audio_queue) {
-                               LOGE("create es_audio_queue for es player failed\n");
-                               goto INIT_ERROR;
-                       }
-                       mainbin[MMPLAYER_M_A_BUFFER].id = MMPLAYER_M_A_BUFFER;
-                       mainbin[MMPLAYER_M_A_BUFFER].gst = es_audio_queue;
-                       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_A_BUFFER]);
-               }
 
-               if (player->s_stream_caps && elem_src_subtitle) {
-                       mainbin[MMPLAYER_M_SUBSRC].id = MMPLAYER_M_SUBSRC;
-                       mainbin[MMPLAYER_M_SUBSRC].gst = elem_src_subtitle;
-                       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_SUBSRC]);
-
-                       es_subtitle_queue = gst_element_factory_make("queue2", "subtitle_queue");
-                       if (!es_subtitle_queue) {
-                               LOGE("create es_subtitle_queue for es player failed\n");
-                               goto INIT_ERROR;
+       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);
                        }
-                       mainbin[MMPLAYER_M_S_BUFFER].id = MMPLAYER_M_V_BUFFER;
-                       mainbin[MMPLAYER_M_S_BUFFER].gst = es_subtitle_queue;
-                       element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_S_BUFFER]);
                }
+       } else {
+               g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
+                                                                               "sync", TRUE, "max-lateness", FAKE_SINK_MAX_LATENESS, NULL);
        }
 
-       /* create autoplugging element if src element is not a rtsp src */
-       if ((player->profile.uri_type != MM_PLAYER_URI_TYPE_URL_RTSP) &&
-               (player->profile.uri_type != MM_PLAYER_URI_TYPE_MS_BUFF)) {
-               element = NULL;
-               enum MainElementID elemId = MMPLAYER_M_NUM;
-
-               if (((MMPLAYER_IS_HTTP_PD(player)) ||
-                       (!MMPLAYER_IS_HTTP_STREAMING(player)))) {
-                       elemId = MMPLAYER_M_AUTOPLUG;
-                       element = __mmplayer_create_decodebin(player);
-                       if (element) {
-                               /* default size of mq in decodebin is 2M
-                                * but it can cause blocking issue during seeking depends on content. */
-                               g_object_set(G_OBJECT(element), "max-size-bytes", (5*1024*1024), NULL);
-                       }
-                       need_state_holder = FALSE;
-               } else {
-                       elemId = MMPLAYER_M_TYPEFIND;
-                       element = gst_element_factory_make("typefind", "typefinder");
-                       MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type",
-                               G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player);
-               }
-
-
-               /* check autoplug element is OK */
-               if (!element) {
-                       LOGE("can not create element(%d)\n", elemId);
-                       goto INIT_ERROR;
-               }
+       mm_attrs_get_int_by_name(attrs, "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);
+       }
 
-               mainbin[elemId].id = elemId;
-               mainbin[elemId].gst = element;
+       if (player->set_mode.video_export) {
+               int enable = 0;
+               mm_attrs_get_int_by_name(player->attrs, "enable_video_decoded_cb", &enable);
+               if (enable || (surface_type == MM_DISPLAY_SURFACE_REMOTE) || (surface_type == MM_DISPLAY_SURFACE_NULL))
+                       g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "signal-handoffs", TRUE, NULL);
 
-               element_bucket = g_list_append(element_bucket, &mainbin[elemId]);
-       }
+               __mmplayer_add_signal_connection(player,
+                                                               G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
+                                                               MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                                                               "handoff",
+                                                               G_CALLBACK(__mmplayer_video_stream_decoded_render_cb),
+                                                               (gpointer)player);
 
-       /* add elements to pipeline */
-       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element_bucket)) {
-               LOGE("Failed to add elements to pipeline\n");
-               goto INIT_ERROR;
+               __mmplayer_add_signal_connection(player,
+                                                               G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
+                                                               MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                                                               "preroll-handoff",
+                                                               G_CALLBACK(__mmplayer_video_stream_decoded_preroll_cb),
+                                                               (gpointer)player);
        }
 
+       if (_mmplayer_update_video_param(player, "update_all_param") != MM_ERROR_NONE)
+               return MM_ERROR_PLAYER_INTERNAL;
 
-       /* linking elements in the bucket by added order. */
-       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1) {
-               LOGE("Failed to link some elements\n");
-               goto INIT_ERROR;
+       if (videobin[MMPLAYER_V_SINK].gst) {
+               GstPad *sink_pad = NULL;
+               sink_pad = gst_element_get_static_pad(videobin[MMPLAYER_V_SINK].gst, "sink");
+               if (sink_pad) {
+                       __mmplayer_add_signal_connection(player, G_OBJECT(sink_pad), MM_PLAYER_SIGNAL_TYPE_VIDEOBIN,
+                                       "notify::caps", G_CALLBACK(__mmplayer_gst_caps_notify_cb), (gpointer)player);
+                       gst_object_unref(GST_OBJECT(sink_pad));
+               } else {
+                       LOGE("failed to get sink pad from videosink");
+               }
        }
 
+       return MM_ERROR_NONE;
+}
 
-       /* create fakesink element for keeping the pipeline state PAUSED. if needed */
-       if (need_state_holder) {
-               /* create */
-               mainbin[MMPLAYER_M_SRC_FAKESINK].id = MMPLAYER_M_SRC_FAKESINK;
-               mainbin[MMPLAYER_M_SRC_FAKESINK].gst = gst_element_factory_make("fakesink", "state-holder");
-
-               if (!mainbin[MMPLAYER_M_SRC_FAKESINK].gst) {
-                       LOGE("fakesink element could not be created\n");
-                       goto INIT_ERROR;
-               }
-               GST_OBJECT_FLAG_UNSET(mainbin[MMPLAYER_M_SRC_FAKESINK].gst, GST_ELEMENT_FLAG_SINK);
+/**
+ * VIDEO BIN
+ * - video overlay surface(arm/x86) : tizenwlsink
+ */
+static int
+__mmplayer_gst_create_video_sink_bin(mmplayer_t *player, GstCaps *caps, MMDisplaySurfaceType surface_type)
+{
+       GstPad *pad = NULL;
+       GList *element_bucket = NULL;
+       mmplayer_gst_element_t *first_element = NULL;
+       mmplayer_gst_element_t *videobin = NULL;
+       gchar *videosink_factory_name = NULL;
 
-               /* take ownership of fakesink. we are reusing it */
-               gst_object_ref(mainbin[MMPLAYER_M_SRC_FAKESINK].gst);
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-               /* add */
-               if (FALSE == gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst),
-                       mainbin[MMPLAYER_M_SRC_FAKESINK].gst)) {
-                       LOGE("failed to add fakesink to bin\n");
-                       goto INIT_ERROR;
-               }
-       }
+       /* alloc handles */
+       videobin = (mmplayer_gst_element_t *)g_try_malloc0(sizeof(mmplayer_gst_element_t) * MMPLAYER_V_NUM);
+       if (!videobin)
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;
 
-       /* now we have completed mainbin. take it */
-       player->pipeline->mainbin = mainbin;
+       player->pipeline->videobin = videobin;
 
-       if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
-               GstPad *srcpad = NULL;
-
-               if (mainbin[MMPLAYER_M_V_BUFFER].gst) {
-                       srcpad = gst_element_get_static_pad(mainbin[MMPLAYER_M_V_BUFFER].gst, "src");
-                       if (srcpad) {
-                               __mmplayer_gst_create_decoder(player,
-                                                                                               MM_PLAYER_TRACK_TYPE_VIDEO,
-                                                                                               srcpad,
-                                                                                               MMPLAYER_M_AUTOPLUG_V_DEC,
-                                                                                               "video_decodebin");
-
-                               gst_object_unref(GST_OBJECT(srcpad));
-                               srcpad = NULL;
-                       }
-               }
+       /* create bin */
+       videobin[MMPLAYER_V_BIN].id = MMPLAYER_V_BIN;
+       videobin[MMPLAYER_V_BIN].gst = gst_bin_new("videobin");
+       if (!videobin[MMPLAYER_V_BIN].gst) {
+               LOGE("failed to create videobin");
+               goto ERROR;
+       }
 
-               if ((player->a_stream_caps) && (mainbin[MMPLAYER_M_A_BUFFER].gst)) {
-                       srcpad = gst_element_get_static_pad(mainbin[MMPLAYER_M_A_BUFFER].gst, "src");
-                       if (srcpad) {
-                               __mmplayer_gst_create_decoder(player,
-                                                                                               MM_PLAYER_TRACK_TYPE_AUDIO,
-                                                                                               srcpad,
-                                                                                               MMPLAYER_M_AUTOPLUG_A_DEC,
-                                                                                               "audio_decodebin");
+       if (__mmplayer_gst_create_video_filters(player, surface_type, &element_bucket) != MM_ERROR_NONE)
+               goto ERROR;
 
-                               gst_object_unref(GST_OBJECT(srcpad));
-                               srcpad = NULL;
-                       } // else error
-               } //  else error
+       videosink_factory_name = __mmplayer_get_videosink_factory_name(player, surface_type);
+       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_factory_name, "videosink", element_bucket, player);
 
-               if (mainbin[MMPLAYER_M_S_BUFFER].gst)
-                       __mmplayer_try_to_plug_decodebin(player, gst_element_get_static_pad(mainbin[MMPLAYER_M_S_BUFFER].gst, "src"), player->s_stream_caps);
+       /* additional setting for sink plug-in */
+       if (__mmplayer_gst_set_videosink_property(player, surface_type) != MM_ERROR_NONE) {
+               LOGE("failed to set video property");
+               goto ERROR;
        }
 
-       /* Note : check whether subtitle atrribute uri is set. If uri is set, then try to play subtitle file */
-       if (__mmplayer_check_subtitle(player)) {
-               if (MM_ERROR_NONE != __mmplayer_gst_create_text_pipeline(player))
-                       LOGE("fail to create text pipeline");
-       }
+       /* store it as it's sink element */
+       __mmplayer_add_sink(player, videobin[MMPLAYER_V_SINK].gst);
 
-       /* connect bus callback */
-       bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[MMPLAYER_M_PIPE].gst));
-       if (!bus) {
-               LOGE("cannot get bus from pipeline.\n");
-               goto INIT_ERROR;
+       /* adding created elements to bin */
+       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(videobin[MMPLAYER_V_BIN].gst), element_bucket)) {
+               LOGE("failed to add elements");
+               goto ERROR;
        }
 
-       player->bus_watcher = gst_bus_add_watch(bus, (GstBusFunc)__mmplayer_gst_msg_push, player);
+       /* Linking elements in the bucket by added order */
+       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1) {
+               LOGE("failed to link elements");
+               goto ERROR;
+       }
 
-       player->context.thread_default = g_main_context_get_thread_default();
+       /* get first element's sinkpad for creating ghostpad */
+       first_element = (mmplayer_gst_element_t *)element_bucket->data;
+       if (!first_element) {
+               LOGE("failed to get first element from bucket");
+               goto ERROR;
+       }
 
-       if (player->context.thread_default == NULL) {
-               player->context.thread_default = g_main_context_default();
-               LOGD("thread-default context is the global default context");
+       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
+       if (!pad) {
+               LOGE("failed to get pad from first element");
+               goto ERROR;
        }
-       LOGW("bus watcher thread context = %p, watcher : %d", player->context.thread_default, player->bus_watcher);
 
-       /* set sync handler to get tag synchronously */
-       gst_bus_set_sync_handler(bus, __mmplayer_bus_sync_callback, player, NULL);
+       /* create ghostpad */
+       player->ghost_pad_for_videobin = gst_ghost_pad_new("sink", pad);
+       if (!gst_element_add_pad(videobin[MMPLAYER_V_BIN].gst, player->ghost_pad_for_videobin)) {
+               LOGE("failed to add ghostpad to videobin");
+               goto ERROR;
+       }
+       gst_object_unref(pad);
 
-       /* finished */
-       gst_object_unref(GST_OBJECT(bus));
+       /* done. free allocated variables */
        g_list_free(element_bucket);
 
-       /* create gst bus_msb_cb thread */
-       g_mutex_init(&player->bus_msg_thread_mutex);
-       g_cond_init(&player->bus_msg_thread_cond);
-       player->bus_msg_thread_exit = FALSE;
-       player->bus_msg_timeout = PLAYER_BUS_MSG_DEFAULT_TIMEOUT;
-       player->bus_msg_thread =
-               g_thread_try_new("gst_bus_msg_thread", __mmplayer_gst_bus_msg_thread, (gpointer)player, NULL);
-       if (!player->bus_msg_thread) {
-               LOGE("failed to create gst BUS msg thread");
-               g_mutex_clear(&player->bus_msg_thread_mutex);
-               g_cond_clear(&player->bus_msg_thread_cond);
-               goto INIT_ERROR;
-       }
-
        MMPLAYER_FLEAVE();
 
        return MM_ERROR_NONE;
 
-INIT_ERROR:
-       __mmplayer_gst_destroy_pipeline(player);
+ERROR:
+       LOGE("ERROR : releasing videobin");
        g_list_free(element_bucket);
 
-       if (mainbin) {
-               /* release element which are not added to bin */
-               for (i = 1; i < MMPLAYER_M_NUM; i++) {
-                       /* NOTE : skip pipeline */
-                       if (mainbin[i].gst) {
-                               GstObject* parent = NULL;
-                               parent = gst_element_get_parent(mainbin[i].gst);
-
-                               if (!parent) {
-                                       gst_object_unref(GST_OBJECT(mainbin[i].gst));
-                                       mainbin[i].gst = NULL;
-                               } else
-                                       gst_object_unref(GST_OBJECT(parent));
-                       }
-               }
+       if (pad)
+               gst_object_unref(GST_OBJECT(pad));
 
-               /* release pipeline with it's childs */
-               if (mainbin[MMPLAYER_M_PIPE].gst)
-                       gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
+       /* release videobin with it's childs */
+       if (videobin[MMPLAYER_V_BIN].gst)
+               gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst));
 
-               MMPLAYER_FREEIF(mainbin);
-       }
+       MMPLAYER_FREEIF(videobin);
+       player->pipeline->videobin = NULL;
 
-       MMPLAYER_FREEIF(player->pipeline);
        return MM_ERROR_PLAYER_INTERNAL;
 }
 
-static void
-__mmplayer_reset_gapless_state(mm_player_t* player)
-{
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player
-               && player->pipeline
-               && player->pipeline->audiobin
-               && player->pipeline->audiobin[MMPLAYER_A_BIN].gst);
-
-       memset(&player->gapless, 0, sizeof(mm_player_gapless_t));
-
-       MMPLAYER_FLEAVE();
-       return;
-}
-
 static int
-__mmplayer_gst_destroy_pipeline(mm_player_t* player)
+__mmplayer_gst_create_plain_text_elements(mmplayer_t *player)
 {
-       gint timeout = 0;
-       int ret = MM_ERROR_NONE;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_INVALID_HANDLE);
+       GList *element_bucket = NULL;
+       mmplayer_gst_element_t *textbin = player->pipeline->textbin;
 
-       /* cleanup stuffs */
-       MMPLAYER_FREEIF(player->type);
-       player->have_dynamic_pad = FALSE;
-       player->no_more_pad = FALSE;
-       player->num_dynamic_pad = 0;
-       player->demux_pad_index = 0;
-       player->use_deinterleave = FALSE;
-       player->max_audio_channels = 0;
-       player->video_share_api_delta = 0;
-       player->video_share_clock_delta = 0;
-       player->video_hub_download_mode = 0;
+       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_QUEUE, "queue", "text_queue", element_bucket, player);
+       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_IDENTITY, "identity", "text_identity", element_bucket, player);
+       g_object_set(G_OBJECT(textbin[MMPLAYER_T_IDENTITY].gst),
+                                                       "signal-handoffs", FALSE,
+                                                       NULL);
 
-       MMPLAYER_SUBTITLE_INFO_LOCK(player);
-       player->subtitle_language_list = NULL;
-       MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
+       MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_FAKE_SINK, "fakesink", "text_fakesink", element_bucket, player);
+       __mmplayer_add_signal_connection(player,
+                                                       G_OBJECT(textbin[MMPLAYER_T_FAKE_SINK].gst),
+                                                       MM_PLAYER_SIGNAL_TYPE_TEXTBIN,
+                                                       "handoff",
+                                                       G_CALLBACK(__mmplayer_update_subtitle),
+                                                       (gpointer)player);
 
-       __mmplayer_reset_gapless_state(player);
+       g_object_set(G_OBJECT(textbin[MMPLAYER_T_FAKE_SINK].gst), "sync", TRUE,
+                                               "signal-handoffs", TRUE, "max-lateness", FAKE_SINK_MAX_LATENESS, NULL);
 
-       if (player->streamer) {
-               __mm_player_streaming_deinitialize(player->streamer);
-               __mm_player_streaming_destroy(player->streamer);
-               player->streamer = NULL;
+       if (!player->play_subtitle) {
+               LOGD("add textbin sink as sink element of whole pipeline.");
+               __mmplayer_add_sink(player, GST_ELEMENT(textbin[MMPLAYER_T_FAKE_SINK].gst));
        }
 
-       /* cleanup unlinked mime type */
-       MMPLAYER_FREEIF(player->unlinked_audio_mime);
-       MMPLAYER_FREEIF(player->unlinked_video_mime);
-       MMPLAYER_FREEIF(player->unlinked_demuxer_mime);
-
-       /* cleanup running stuffs */
-       __mmplayer_cancel_eos_timer(player);
-
-       /* cleanup gst stuffs */
-       if (player->pipeline) {
-               MMPlayerGstElement* mainbin = player->pipeline->mainbin;
-               GstTagList* tag_list = player->pipeline->tag_list;
-
-               /* first we need to disconnect all signal hander */
-               __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_ALL);
-
-               if (player->bus_watcher)
-                       __mmplayer_remove_g_source_from_context(player->context.thread_default, player->bus_watcher);
-               player->bus_watcher = 0;
-
-               if (mainbin) {
-                       MMPlayerGstElement* audiobin = player->pipeline->audiobin;
-                       MMPlayerGstElement* videobin = player->pipeline->videobin;
-                       MMPlayerGstElement* textbin = player->pipeline->textbin;
-                       GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[MMPLAYER_M_PIPE].gst));
-                       gst_bus_set_sync_handler(bus, NULL, NULL, NULL);
-                       gst_object_unref(bus);
+       /* adding created elements to bin */
+       LOGD("adding created elements to bin");
+       if (!__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(textbin[MMPLAYER_T_BIN].gst), element_bucket)) {
+               LOGE("failed to add elements");
+               goto ERROR;
+       }
 
-                       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
-                       ret = __mmplayer_gst_set_state(player, mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_NULL, FALSE, timeout);
-                       if (ret != MM_ERROR_NONE) {
-                               LOGE("fail to change state to NULL\n");
-                               return MM_ERROR_PLAYER_INTERNAL;
-                       }
+       /* unset sink flag from textbin. not to hold eos when video data is shorter than subtitle */
+       GST_OBJECT_FLAG_UNSET(textbin[MMPLAYER_T_BIN].gst, GST_ELEMENT_FLAG_SINK);
+       GST_OBJECT_FLAG_UNSET(textbin[MMPLAYER_T_FAKE_SINK].gst, GST_ELEMENT_FLAG_SINK);
 
-                       LOGW("succeeded in chaning state to NULL\n");
+       /* linking elements in the bucket by added order. */
+       LOGD("Linking elements in the bucket by added order.");
+       if (__mmplayer_gst_element_link_bucket(element_bucket) == -1) {
+               LOGE("failed to link elements");
+               goto ERROR;
+       }
 
-                       gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
+       /* done. free allocated variables */
+       g_list_free(element_bucket);
 
-                       /* free fakesink */
-                       if (mainbin[MMPLAYER_M_SRC_FAKESINK].gst)
-                               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC_FAKESINK].gst));
+       if (textbin[MMPLAYER_T_QUEUE].gst) {
+               GstPad *pad = NULL;
+               GstPad *ghostpad = NULL;
 
-                       /* free avsysaudiosink
-                          avsysaudiosink should be unref when destory pipeline just after start play with BT.
-                          Because audiosink is created but never added to bin, and therefore it will not be unref when pipeline is destroyed.
-                       */
-                       MMPLAYER_FREEIF(audiobin);
-                       MMPLAYER_FREEIF(videobin);
-                       MMPLAYER_FREEIF(textbin);
-                       MMPLAYER_FREEIF(mainbin);
+               pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_QUEUE].gst), "sink");
+               if (!pad) {
+                       LOGE("failed to get sink pad of text queue");
+                       goto ERROR;
                }
 
-               if (tag_list)
-                       gst_tag_list_free(tag_list);
+               ghostpad = gst_ghost_pad_new("text_sink", pad);
+               gst_object_unref(pad);
 
-               MMPLAYER_FREEIF(player->pipeline);
-       }
-       MMPLAYER_FREEIF(player->album_art);
+               if (!ghostpad) {
+                       LOGE("failed to create ghostpad of textbin");
+                       goto ERROR;
+               }
 
-       if (player->v_stream_caps) {
-               gst_caps_unref(player->v_stream_caps);
-               player->v_stream_caps = NULL;
-       }
-       if (player->a_stream_caps) {
-               gst_caps_unref(player->a_stream_caps);
-               player->a_stream_caps = NULL;
+               if (!gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad)) {
+                       LOGE("failed to add ghostpad to textbin");
+                       gst_object_unref(ghostpad);
+                       goto ERROR;
+               }
        }
 
-       if (player->s_stream_caps) {
-               gst_caps_unref(player->s_stream_caps);
-               player->s_stream_caps = NULL;
-       }
-       _mmplayer_track_destroy(player);
+       return MM_ERROR_NONE;
 
-       if (player->sink_elements)
-               g_list_free(player->sink_elements);
-       player->sink_elements = NULL;
+ERROR:
+       g_list_free(element_bucket);
 
-       if (player->bufmgr) {
-               tbm_bufmgr_deinit(player->bufmgr);
-               player->bufmgr = NULL;
+       if (!player->play_subtitle && textbin[MMPLAYER_T_FAKE_SINK].gst) {
+               LOGE("remove textbin sink from sink list");
+               __mmplayer_del_sink(player, textbin[MMPLAYER_T_FAKE_SINK].gst);
        }
 
-       LOGW("finished destroy pipeline\n");
-
-       MMPLAYER_FLEAVE();
-
-       return ret;
+       /* release element at __mmplayer_gst_create_text_sink_bin */
+       return MM_ERROR_PLAYER_INTERNAL;
 }
 
-static int __gst_realize(mm_player_t* player)
+static int
+__mmplayer_gst_create_text_sink_bin(mmplayer_t *player)
 {
-       gint timeout = 0;
-       int ret = MM_ERROR_NONE;
+       mmplayer_gst_element_t *textbin = NULL;
+       GList *element_bucket = NULL;
+       int surface_type = 0;
+       gint i = 0;
 
        MMPLAYER_FENTER();
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       ret = __mmplayer_gst_create_pipeline(player);
-       if (ret) {
-               LOGE("failed to create pipeline\n");
-               return ret;
+       /* alloc handles */
+       textbin = (mmplayer_gst_element_t *)g_try_malloc0(sizeof(mmplayer_gst_element_t) * MMPLAYER_T_NUM);
+       if (!textbin) {
+               LOGE("failed to allocate memory for textbin");
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;
        }
 
-       /* set pipeline state to READY */
-       /* NOTE : state change to READY must be performed sync. */
-       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
-       ret = __mmplayer_gst_set_state(player,
-                               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_READY, FALSE, timeout);
-
-       if (ret != MM_ERROR_NONE) {
-               /* return error if failed to set state */
-               LOGE("failed to set READY state");
-               return ret;
+       /* create bin */
+       textbin[MMPLAYER_T_BIN].id = MMPLAYER_T_BIN;
+       textbin[MMPLAYER_T_BIN].gst = gst_bin_new("textbin");
+       if (!textbin[MMPLAYER_T_BIN].gst) {
+               LOGE("failed to create textbin");
+               goto ERROR;
        }
 
-       MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_READY);
-
-       /* create dot before error-return. for debugging */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-realize");
-
-       MMPLAYER_FLEAVE();
-
-       return ret;
-}
-
-static int __gst_unrealize(mm_player_t* player)
-{
-       int ret = MM_ERROR_NONE;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NULL;
-       MMPLAYER_PRINT_STATE(player);
-
-       /* release miscellaneous information */
-       __mmplayer_release_misc(player);
+       /* take it */
+       player->pipeline->textbin = textbin;
 
-       /* destroy pipeline */
-       ret = __mmplayer_gst_destroy_pipeline(player);
-       if (ret != MM_ERROR_NONE) {
-               LOGE("failed to destory pipeline\n");
-               return ret;
+       /* fakesink */
+       mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
+       LOGD("surface type for subtitle : %d", surface_type);
+       switch (surface_type) {
+       case MM_DISPLAY_SURFACE_OVERLAY:
+       case MM_DISPLAY_SURFACE_NULL:
+       case MM_DISPLAY_SURFACE_REMOTE:
+               if (__mmplayer_gst_create_plain_text_elements(player) != MM_ERROR_NONE) {
+                       LOGE("failed to make plain text elements");
+                       goto ERROR;
+               }
+               break;
+       default:
+               goto ERROR;
+               break;
        }
 
-       /* release miscellaneous information.
-          these info needs to be released after pipeline is destroyed. */
-       __mmplayer_release_misc_post(player);
-
-       MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_NULL);
-
        MMPLAYER_FLEAVE();
 
-       return ret;
-}
+       return MM_ERROR_NONE;
 
-static int __gst_pending_seek(mm_player_t* player)
-{
-       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
-       int ret = MM_ERROR_NONE;
+ERROR:
 
-       MMPLAYER_FENTER();
+       LOGD("ERROR : releasing textbin");
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       g_list_free(element_bucket);
 
-       if (!player->pending_seek.is_pending) {
-               LOGD("pending seek is not reserved. nothing to do.\n");
-               return ret;
-       }
+       /* release signal */
+       __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
 
-       /* check player state if player could pending seek or not. */
-       current_state = MMPLAYER_CURRENT_STATE(player);
+       /* release element which are not added to bin */
+       for (i = 1; i < MMPLAYER_T_NUM; i++) {
+               /* NOTE : skip bin */
+               if (textbin[i].gst) {
+                       GstObject *parent = NULL;
+                       parent = gst_element_get_parent(textbin[i].gst);
 
-       if (current_state != MM_PLAYER_STATE_PAUSED && current_state != MM_PLAYER_STATE_PLAYING) {
-               LOGW("try to pending seek in %s state, try next time. \n",
-                       MMPLAYER_STATE_GET_NAME(current_state));
-               return ret;
+                       if (!parent) {
+                               gst_object_unref(GST_OBJECT(textbin[i].gst));
+                               textbin[i].gst = NULL;
+                       } else {
+                               gst_object_unref(GST_OBJECT(parent));
+                       }
+               }
        }
 
-       LOGD("trying to play from(%lu) pending position\n", player->pending_seek.pos);
-
-       ret = __gst_set_position(player, player->pending_seek.format, player->pending_seek.pos, FALSE);
-
-       if (MM_ERROR_NONE != ret)
-               LOGE("failed to seek pending postion. just keep staying current position.\n");
+       /* release textbin with it's childs */
+       if (textbin[MMPLAYER_T_BIN].gst)
+               gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
 
-       player->pending_seek.is_pending = FALSE;
+       MMPLAYER_FREEIF(player->pipeline->textbin);
+       player->pipeline->textbin = NULL;
 
        MMPLAYER_FLEAVE();
-
-       return ret;
+       return MM_ERROR_PLAYER_INTERNAL;
 }
 
-static int __gst_start(mm_player_t* player)
+static int
+__mmplayer_gst_create_text_pipeline(mmplayer_t *player)
 {
-       gboolean sound_extraction = 0;
-       int ret = MM_ERROR_NONE;
-       gboolean async = FALSE;
+       mmplayer_gst_element_t *mainbin = NULL;
+       mmplayer_gst_element_t *textbin = NULL;
+       MMHandleType attrs = 0;
+       GstElement *subsrc = NULL;
+       GstElement *subparse = NULL;
+       gchar *subtitle_uri = NULL;
+       const gchar *charset = NULL;
+       GstPad *pad = NULL;
 
        MMPLAYER_FENTER();
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       /* get sound_extraction property */
-       mm_attrs_get_int_by_name(player->attrs, "pcm_extraction", &sound_extraction);
+       /* get mainbin */
+       MMPLAYER_RETURN_VAL_IF_FAIL(player &&
+                                                               player->pipeline &&
+                                                               player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       /* NOTE : if SetPosition was called before Start. do it now */
-       /* streaming doesn't support it. so it should be always sync */
-       /* !!create one more api to check if there is pending seek rather than checking variables */
-       if ((player->pending_seek.is_pending || sound_extraction) && !MMPLAYER_IS_STREAMING(player)) {
-               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PAUSED;
-               ret = __gst_pause(player, FALSE);
-               if (ret != MM_ERROR_NONE) {
-                       LOGE("failed to set state to PAUSED for pending seek\n");
-                       return ret;
-               }
+       mainbin = player->pipeline->mainbin;
 
-               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PLAYING;
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if (!attrs) {
+               LOGE("cannot get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-               if (sound_extraction) {
-                       LOGD("setting pcm extraction\n");
+       mm_attrs_get_string_by_name(attrs, "subtitle_uri", &subtitle_uri);
+       if (!subtitle_uri || strlen(subtitle_uri) < 1) {
+               LOGE("subtitle uri is not proper filepath.");
+               return MM_ERROR_PLAYER_INVALID_URI;
+       }
 
-                       ret = __mmplayer_set_pcm_extraction(player);
-                       if (MM_ERROR_NONE != ret) {
-                               LOGW("failed to set pcm extraction\n");
-                               return ret;
-                       }
-               } else {
-                       if (MM_ERROR_NONE != __gst_pending_seek(player))
-                               LOGW("failed to seek pending postion. starting from the begin of content.\n");
-               }
+       if (!util_get_storage_info(subtitle_uri, &player->storage_info[MMPLAYER_PATH_TEXT])) {
+               LOGE("failed to get storage info of subtitle path");
+               return MM_ERROR_PLAYER_INVALID_URI;
        }
 
-       LOGD("current state before doing transition");
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
-       MMPLAYER_PRINT_STATE(player);
+       SECURE_LOGD("subtitle file path is [%s].", subtitle_uri);
 
-       /* set pipeline state to PLAYING  */
-       if (player->es_player_push_mode)
-               async = TRUE;
-       /* set pipeline state to PLAYING  */
-       ret = __mmplayer_gst_set_state(player,
-               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, async, MMPLAYER_STATE_CHANGE_TIMEOUT(player));
+       MMPLAYER_SUBTITLE_INFO_LOCK(player);
+       player->subtitle_language_list = NULL;
+       MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
 
-       if (ret == MM_ERROR_NONE) {
-               MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PLAYING);
-       } else {
-               LOGE("failed to set state to PLAYING");
-               return ret;
+       /* create the subtitle source */
+       subsrc = gst_element_factory_make("filesrc", "subtitle_source");
+       if (!subsrc) {
+               LOGE("failed to create filesrc element");
+               goto ERROR;
        }
+       g_object_set(G_OBJECT(subsrc), "location", subtitle_uri, NULL);
 
-       /* generating debug info before returning error */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-start");
-
-       MMPLAYER_FLEAVE();
+       mainbin[MMPLAYER_M_SUBSRC].id = MMPLAYER_M_SUBSRC;
+       mainbin[MMPLAYER_M_SUBSRC].gst = subsrc;
 
-       return ret;
-}
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subsrc)) {
+               LOGW("failed to add queue");
+               gst_object_unref(mainbin[MMPLAYER_M_SUBSRC].gst);
+               mainbin[MMPLAYER_M_SUBSRC].gst = NULL;
+               mainbin[MMPLAYER_M_SUBSRC].id = MMPLAYER_M_NUM;
+               goto ERROR;
+       }
 
-static int __gst_stop(mm_player_t* player)
-{
-       GstStateChangeReturn change_ret = GST_STATE_CHANGE_SUCCESS;
-       MMHandleType attrs = 0;
-       gboolean rewind = FALSE;
-       gint timeout = 0;
-       int ret = MM_ERROR_NONE;
-       gboolean async = FALSE;
+       /* subparse */
+       subparse = gst_element_factory_make("subparse", "subtitle_parser");
+       if (!subparse) {
+               LOGE("failed to create subparse element");
+               goto ERROR;
+       }
 
-       MMPLAYER_FENTER();
+       charset = util_get_charset(subtitle_uri);
+       if (charset) {
+               LOGD("detected charset is %s", charset);
+               g_object_set(G_OBJECT(subparse), "subtitle-encoding", charset, NULL);
+       }
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       mainbin[MMPLAYER_M_SUBPARSE].id = MMPLAYER_M_SUBPARSE;
+       mainbin[MMPLAYER_M_SUBPARSE].gst = subparse;
 
-       LOGD("current state before doing transition");
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
-       MMPLAYER_PRINT_STATE(player);
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subparse)) {
+               LOGW("failed to add subparse");
+               gst_object_unref(mainbin[MMPLAYER_M_SUBPARSE].gst);
+               mainbin[MMPLAYER_M_SUBPARSE].gst = NULL;
+               mainbin[MMPLAYER_M_SUBPARSE].id = MMPLAYER_M_NUM;
+               goto ERROR;
+       }
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if (!attrs) {
-               LOGE("cannot get content attribute\n");
-               return MM_ERROR_PLAYER_INTERNAL;
+       if (!gst_element_link_pads(subsrc, "src", subparse, "sink")) {
+               LOGW("failed to link subsrc and subparse");
+               goto ERROR;
        }
 
-       /* Just set state to PAUESED and the rewind. it's usual player behavior. */
-       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
+       player->play_subtitle = TRUE;
+       player->adjust_subtitle_pos = 0;
 
-       if ((!MMPLAYER_IS_STREAMING(player) && !MMPLAYER_IS_MS_BUFF_SRC(player)) ||
-               (player->streaming_type == STREAMING_SERVICE_VOD && player->videodec_linked))
-               rewind = TRUE;
+       LOGD("play subtitle using subtitle file");
 
-       if (player->es_player_push_mode)
-               async = TRUE;
-       /* set gst state */
-       ret = __mmplayer_gst_set_state(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED, async, timeout);
+       if (player->pipeline->textbin == NULL) {
+               if (MM_ERROR_NONE != __mmplayer_gst_create_text_sink_bin(player)) {
+                       LOGE("failed to create text sink bin. continuing without text");
+                       goto ERROR;
+               }
 
-       /* return if set_state has failed */
-       if (ret != MM_ERROR_NONE) {
-               LOGE("failed to set state.\n");
-               return ret;
-       }
+               textbin = player->pipeline->textbin;
 
-       /* rewind */
-       if (rewind) {
-               if (!__gst_seek(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, player->playback_rate,
-                               GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0,
-                               GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) {
-                       LOGW("failed to rewind\n");
-                       ret = MM_ERROR_PLAYER_SEEK;
-               }
-       }
+               if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), GST_ELEMENT(textbin[MMPLAYER_T_BIN].gst))) {
+                       LOGW("failed to add textbin");
 
-       /* initialize */
-       player->sent_bos = FALSE;
+                       /* release signal */
+                       __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
+
+                       /* release textbin with it's childs */
+                       gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
+                       MMPLAYER_FREEIF(player->pipeline->textbin);
+                       player->pipeline->textbin = textbin = NULL;
+                       goto ERROR;
+               }
 
-       if (player->es_player_push_mode) //for cloudgame
-               timeout = 0;
+               LOGD("link text input selector and textbin ghost pad");
 
-       /* wait for seek to complete */
-       change_ret = gst_element_get_state(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, NULL, NULL, timeout * GST_SECOND);
-       if (change_ret == GST_STATE_CHANGE_SUCCESS || change_ret == GST_STATE_CHANGE_NO_PREROLL) {
-               MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_READY);
+               player->textsink_linked = 1;
+               player->external_text_idx = 0;
+               LOGI("textsink is linked");
        } else {
-               LOGE("fail to stop player.\n");
-               ret = MM_ERROR_PLAYER_INTERNAL;
-               __mmplayer_dump_pipeline_state(player);
+               textbin = player->pipeline->textbin;
+               LOGD("text bin has been created. reuse it.");
+               player->external_text_idx = 1;
        }
 
-       /* generate dot file if enabled */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-stop");
-
-       MMPLAYER_FLEAVE();
+       if (!gst_element_link_pads(subparse, "src", textbin[MMPLAYER_T_BIN].gst, "text_sink")) {
+               LOGW("failed to link subparse and textbin");
+               goto ERROR;
+       }
 
-       return ret;
-}
+       pad = gst_element_get_static_pad(textbin[MMPLAYER_T_FAKE_SINK].gst, "sink");
+       if (!pad) {
+               LOGE("failed to get sink pad from textsink to probe data");
+               goto ERROR;
+       }
 
-int __gst_pause(mm_player_t* player, gboolean async)
-{
-       int ret = MM_ERROR_NONE;
+       gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER,
+                               __mmplayer_subtitle_adjust_position_probe, player, NULL);
 
-       MMPLAYER_FENTER();
+       gst_object_unref(pad);
+       pad = NULL;
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       /* create dot. for debugging */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-with-subtitle");
+       MMPLAYER_FLEAVE();
 
-       LOGD("current state before doing transition");
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PAUSED;
-       MMPLAYER_PRINT_STATE(player);
+       return MM_ERROR_NONE;
 
-       /* set pipeline status to PAUSED */
-       ret = __mmplayer_gst_set_state(player,
-               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED, async, MMPLAYER_STATE_CHANGE_TIMEOUT(player));
+ERROR:
+       /* release text pipeline resource */
+       player->textsink_linked = 0;
 
-       if (FALSE == async) {
-               if (ret != MM_ERROR_NONE) {
-                       GstMessage *msg = NULL;
-                       GTimer *timer = NULL;
-                       gdouble MAX_TIMEOUT_SEC = 3;
+       /* release signal */
+       __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_TEXTBIN);
 
-                       LOGE("failed to set state to PAUSED");
+       if (player->pipeline->textbin) {
+               LOGE("remove textbin");
 
-                       if (player->msg_posted) {
-                               LOGE("error msg is already posted.");
-                               return ret;
-                       }
+               /* release textbin with it's childs */
+               MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->textbin, MMPLAYER_T_BIN);
+               MMPLAYER_FREEIF(player->pipeline->textbin);
+               player->pipeline->textbin = NULL;
 
-                       timer = g_timer_new();
-                       g_timer_start(timer);
+       }
 
-                       GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
+       /* release subtitle elem */
+       MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->mainbin, MMPLAYER_M_SUBSRC);
+       MMPLAYER_RELEASE_ELEMENT(player, player->pipeline->mainbin, MMPLAYER_M_SUBPARSE);
 
-                       do {
-                               msg = gst_bus_timed_pop(bus, 100 * GST_MSECOND);
-                               if (msg) {
-                                       if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR) {
-                                               GError *error = NULL;
+       return MM_ERROR_PLAYER_INTERNAL;
+}
 
-                                               /* parse error code */
-                                               gst_message_parse_error(msg, &error, NULL);
+gboolean
+__mmplayer_update_subtitle(GstElement *object, GstBuffer *buffer, GstPad *pad, gpointer data)
+{
+       mmplayer_t *player = (mmplayer_t *)data;
+       MMMessageParamType msg = {0, };
+       GstClockTime duration = 0;
+       gpointer text = NULL;
+       guint text_size = 0;
+       gboolean ret = TRUE;
+       GstMapInfo mapinfo = GST_MAP_INFO_INIT;
 
-                                               if (gst_structure_has_name(gst_message_get_structure(msg), "streaming_error")) {
-                                                       /* Note : the streaming error from the streaming source is handled
-                                                        *   using __mmplayer_handle_streaming_error.
-                                                        */
-                                                       __mmplayer_handle_streaming_error(player, msg);
+       MMPLAYER_FENTER();
 
-                                               } else if (error) {
-                                                       LOGE("paring error posted from bus, domain : %s, code : %d", g_quark_to_string(error->domain), error->code);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+       MMPLAYER_RETURN_VAL_IF_FAIL(buffer, FALSE);
 
-                                                       if (error->domain == GST_STREAM_ERROR)
-                                                               ret = __gst_handle_stream_error(player, error, msg);
-                                                       else if (error->domain == GST_RESOURCE_ERROR)
-                                                               ret = __gst_handle_resource_error(player, error->code, NULL);
-                                                       else if (error->domain == GST_LIBRARY_ERROR)
-                                                               ret = __gst_handle_library_error(player, error->code);
-                                                       else if (error->domain == GST_CORE_ERROR)
-                                                               ret = __gst_handle_core_error(player, error->code);
+       if (player->is_subtitle_force_drop) {
+               LOGW("subtitle is dropped forcedly.");
+               return ret;
+       }
 
-                                                       g_error_free(error);
-                                               }
-                                               player->msg_posted = TRUE;
-                                       }
-                                       gst_message_unref(msg);
-                               }
-                       } while (!player->msg_posted && (g_timer_elapsed(timer, NULL) < MAX_TIMEOUT_SEC));
-                       /* clean */
-                       gst_object_unref(bus);
-                       g_timer_stop(timer);
-                       g_timer_destroy(timer);
+       gst_buffer_map(buffer, &mapinfo, GST_MAP_READ);
+       text = mapinfo.data;
+       text_size = mapinfo.size;
 
-                       return ret;
+       if (player->set_mode.subtitle_off) {
+               LOGD("subtitle is OFF.");
+               return TRUE;
+       }
 
-               } else if ((!MMPLAYER_IS_RTSP_STREAMING(player)) && (!player->video_stream_cb) &&
-                                  (!player->pipeline->videobin) && (!player->pipeline->audiobin)) {
+       if (!text || (text_size == 0)) {
+               LOGD("There is no subtitle to be displayed.");
+               return TRUE;
+       }
 
-                       return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
+       msg.data = (void *)text;
 
-               } else if (ret == MM_ERROR_NONE) {
+       duration = GST_BUFFER_DURATION(buffer);
 
-                       MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PAUSED);
-               }
+       if (!GST_CLOCK_TIME_IS_VALID(duration)) {
+               if (player->duration > GST_BUFFER_PTS(buffer))
+                       duration = player->duration - GST_BUFFER_PTS(buffer);
+               else
+                       duration = 0;
+               LOGI("subtitle duration is invalid, subtitle duration change "
+                       "GST_CLOCK_TIME_NONE -> %" GST_TIME_FORMAT, GST_TIME_ARGS(duration));
        }
+       msg.subtitle.duration = GST_TIME_AS_MSECONDS(duration);
 
-       /* generate dot file before returning error */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-pause");
+       LOGD("update subtitle : [%ld msec] %s", msg.subtitle.duration, (char *)msg.data);
+
+       MMPLAYER_POST_MSG(player, MM_MESSAGE_UPDATE_SUBTITLE, &msg);
+       gst_buffer_unmap(buffer, &mapinfo);
 
        MMPLAYER_FLEAVE();
 
        return ret;
 }
 
-int __gst_resume(mm_player_t* player, gboolean async)
+static GstPadProbeReturn
+__mmplayer_subtitle_adjust_position_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
 {
-       int ret = MM_ERROR_NONE;
-       gint timeout = 0;
+       mmplayer_t *player = (mmplayer_t *)u_data;
+       GstClockTime cur_timestamp = 0;
+       gint64 adjusted_timestamp = 0;
+       GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
 
-       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline,
-               MM_ERROR_PLAYER_NOT_INITIALIZED);
+       if (player->set_mode.subtitle_off) {
+               LOGD("subtitle is OFF.");
+               return TRUE;
+       }
 
-       LOGD("current state before doing transition");
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
-       MMPLAYER_PRINT_STATE(player);
+       if (player->adjust_subtitle_pos == 0) {
+               LOGD("nothing to do");
+               return TRUE;
+       }
 
-       /* generate dot file before returning error */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-resume");
+       cur_timestamp = GST_BUFFER_TIMESTAMP(buffer);
+       adjusted_timestamp = (gint64)cur_timestamp + ((gint64)player->adjust_subtitle_pos * G_GINT64_CONSTANT(1000000));
 
-       if (async)
-               LOGD("do async state transition to PLAYING.\n");
+       if (adjusted_timestamp < 0) {
+               LOGD("adjusted_timestamp under zero");
+               MMPLAYER_FLEAVE();
+               return FALSE;
+       }
 
-       /* set pipeline state to PLAYING */
-       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
+       GST_BUFFER_TIMESTAMP(buffer) = (GstClockTime) adjusted_timestamp;
+       LOGD("buffer timestamp changed %" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "",
+                               GST_TIME_ARGS(cur_timestamp),
+                               GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
 
-       ret = __mmplayer_gst_set_state(player,
-               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, async, timeout);
-       if (ret != MM_ERROR_NONE) {
-               LOGE("failed to set state to PLAYING\n");
-               return ret;
-       } else {
-               if (async == FALSE) {
-                       // MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PLAYING);
-                       LOGD("update state machine to %d\n", MM_PLAYER_STATE_PLAYING);
-                       ret = __mmplayer_set_state(player, MM_PLAYER_STATE_PLAYING);
-               }
+       return GST_PAD_PROBE_OK;
+}
+
+static int
+__mmplayer_gst_adjust_subtitle_position(mmplayer_t *player, int position)
+{
+       MMPLAYER_FENTER();
+
+       /* check player and subtitlebin are created */
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player->play_subtitle, MM_ERROR_NOT_SUPPORT_API);
+
+       if (position == 0) {
+               LOGD("nothing to do");
+               MMPLAYER_FLEAVE();
+               return MM_ERROR_NONE;
        }
 
-       /* generate dot file before returning error */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-resume");
+       /* check current postion */
+       player->adjust_subtitle_pos = position;
+
+       LOGD("save adjust_subtitle_pos in player");
 
        MMPLAYER_FLEAVE();
 
-       return ret;
+       return MM_ERROR_NONE;
 }
 
+/**
+ * This function is to create  audio or video pipeline for playing.
+ *
+ * @param      player          [in]    handle of player
+ *
+ * @return     This function returns zero on success.
+ * @remark
+ * @see
+ */
 static int
-__gst_set_position(mm_player_t* player, int format, unsigned long position, gboolean internal_called)
+__mmplayer_gst_create_pipeline(mmplayer_t *player)
 {
-       unsigned long dur_msec = 0;
-       gint64 dur_nsec = 0;
-       gint64 pos_nsec = 0;
-       gboolean ret = TRUE;
-       gboolean accurated = FALSE;
-       GstSeekFlags seek_flags = GST_SEEK_FLAG_FLUSH;
+       int ret = MM_ERROR_NONE;
+       mmplayer_gst_element_t *mainbin = NULL;
+       MMHandleType attrs = 0;
 
        MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(!MMPLAYER_IS_LIVE_STREAMING(player), MM_ERROR_PLAYER_NO_OP);
-
-       if (MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING
-               && MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PAUSED)
-               goto PENDING;
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       if (!MMPLAYER_IS_MS_BUFF_SRC(player)) {
-               /* check duration */
-               /* NOTE : duration cannot be zero except live streaming.
-                *              Since some element could have some timing problemn with quering duration, try again.
-                */
-               if (!player->duration) {
-                       if (!gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &dur_nsec)) {
-                               /* For RTSP Streaming , duration is not returned in READY state. So seek to the previous position does not work properly.
-                                * Added a patch to postpone the actual seek when state changes to PLAY. Sending a fake SEEK_COMPLETED event to finish the current request. */
-                               if ((MMPLAYER_IS_RTSP_STREAMING(player)) && (__mmplayer_get_stream_service_type(player) == STREAMING_SERVICE_VOD)) {
-                                       player->pending_seek.is_pending = TRUE;
-                                       player->pending_seek.format = format;
-                                       player->pending_seek.pos = position;
-                                       player->doing_seek = FALSE;
-                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
-                                       return MM_ERROR_NONE;
-                               } else {
-                                       goto SEEK_ERROR;
-                               }
-                       }
-                       player->duration = dur_nsec;
-               }
+       /* get profile attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if (!attrs) {
+               LOGE("failed to get content attribute");
+               goto INIT_ERROR;
+       }
 
-               if (player->duration) {
-                       dur_msec = GST_TIME_AS_MSECONDS(player->duration);
-               } else {
-                       LOGE("could not get the duration. fail to seek.\n");
-                       goto SEEK_ERROR;
-               }
+       /* create pipeline handles */
+       if (player->pipeline) {
+               LOGE("pipeline should be released before create new one");
+               goto INIT_ERROR;
        }
-       LOGD("playback rate: %f\n", player->playback_rate);
 
-       mm_attrs_get_int_by_name(player->attrs, "accurate_seek", &accurated);
-       if (accurated)
-               seek_flags |= GST_SEEK_FLAG_ACCURATE;
-       else
-               seek_flags |= GST_SEEK_FLAG_KEY_UNIT;
+       player->pipeline = (mmplayer_pipeline_info_t *)g_malloc0(sizeof(mmplayer_pipeline_info_t));
+       if (player->pipeline == NULL)
+               goto INIT_ERROR;
 
-       /* do seek */
-       switch (format) {
-       case MM_PLAYER_POS_FORMAT_TIME:
-       {
-               if (!MMPLAYER_IS_MS_BUFF_SRC(player)) {
-                       GstQuery *query = NULL;
-                       gboolean seekable = FALSE;
-
-                       /* check position is valid or not */
-                       if (position > dur_msec)
-                               goto INVALID_ARGS;
-
-                       query = gst_query_new_seeking(GST_FORMAT_TIME);
-                       if (gst_element_query(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, query)) {
-                               gst_query_parse_seeking(query, NULL, &seekable, NULL, NULL);
-                               gst_query_unref(query);
-
-                               if (!seekable) {
-                                       LOGW("non-seekable content");
-                                       player->doing_seek = FALSE;
-                                       return MM_ERROR_PLAYER_NO_OP;
-                               }
-                       } else {
-                               LOGW("failed to get seeking query");
-                               gst_query_unref(query); /* keep seeking operation */
-                       }
+       /* create mainbin */
+       mainbin = (mmplayer_gst_element_t *)g_try_malloc0(sizeof(mmplayer_gst_element_t) * MMPLAYER_M_NUM);
+       if (mainbin == NULL)
+               goto INIT_ERROR;
 
-                       LOGD("seeking to(%lu) msec, duration is %d msec\n", position, dur_msec);
+       /* create pipeline */
+       mainbin[MMPLAYER_M_PIPE].id = MMPLAYER_M_PIPE;
+       mainbin[MMPLAYER_M_PIPE].gst = gst_pipeline_new("player");
+       if (!mainbin[MMPLAYER_M_PIPE].gst) {
+               LOGE("failed to create pipeline");
+               g_free(mainbin);
+               goto INIT_ERROR;
+       }
 
-                       /* For rtspsrc stack , npt-start value coming from server is used for finding the current position.
-                          But when a rtsp clip (especially from Youtube Desktop View) is paused and kept for sometime,npt-start is still increasing.
-                          This causes problem is position calculation during normal pause resume scenarios also.
-                          Currently during seek , we are sending the current position to rtspsrc module for position saving for later use. */
-                       if ((MMPLAYER_IS_RTSP_STREAMING(player)) &&
-                               (__mmplayer_get_stream_service_type(player) == STREAMING_SERVICE_VOD)) {
-                               if (!gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_nsec))
-                                       LOGW("getting current position failed in seek\n");
+       player->pipeline->mainbin = mainbin;
 
-                               player->last_position = pos_nsec;
-                               g_object_set(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "resume-position", player->last_position, NULL);
-                       }
+       /* create the source and decoder elements */
+       if (MMPLAYER_IS_MS_BUFF_SRC(player))
+               ret = __mmplayer_gst_build_es_pipeline(player);
+       else
+               ret = __mmplayer_gst_build_pipeline(player);
 
-                       if (player->doing_seek) {
-                               LOGD("not completed seek");
-                               return MM_ERROR_PLAYER_DOING_SEEK;
-                       }
-               }
+       if (ret != MM_ERROR_NONE) {
+               LOGE("failed to create some elements");
+               goto INIT_ERROR;
+       }
 
-               if (!internal_called)
-                       player->doing_seek = TRUE;
+       /* Note : check whether subtitle atrribute uri is set. If uri is set, then try to play subtitle file */
+       if (__mmplayer_check_subtitle(player)
+               && (__mmplayer_gst_create_text_pipeline(player) != MM_ERROR_NONE))
+               LOGE("failed to create text pipeline");
 
-               pos_nsec = position * G_GINT64_CONSTANT(1000000);
+       /* add bus watch */
+       ret = __mmplayer_gst_add_bus_watch(player);
+       if (ret != MM_ERROR_NONE) {
+               LOGE("failed to add bus watch");
+               goto INIT_ERROR;
+       }
 
-               if ((MMPLAYER_IS_HTTP_STREAMING(player)) && (!player->videodec_linked)) {
-                       gint64 cur_time = 0;
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
 
-                       /* get current position */
-                       gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &cur_time);
+INIT_ERROR:
+       __mmplayer_gst_destroy_pipeline(player);
+       return MM_ERROR_PLAYER_INTERNAL;
+}
 
-                       /* flush */
-                       GstEvent *event = gst_event_new_seek(1.0,
-                                                       GST_FORMAT_TIME,
-                                                       (GstSeekFlags)GST_SEEK_FLAG_FLUSH,
-                                                       GST_SEEK_TYPE_SET, cur_time,
-                                                       GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
-                       if (event)
-                               __gst_send_event_to_sink(player, event);
+static void
+__mmplayer_reset_gapless_state(mmplayer_t *player)
+{
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player
+               && player->pipeline
+               && player->pipeline->audiobin
+               && player->pipeline->audiobin[MMPLAYER_A_BIN].gst);
 
-                       if (!MMPLAYER_IS_RTSP_STREAMING(player))
-                               __gst_pause(player, FALSE);
-               }
+       memset(&player->gapless, 0, sizeof(mmplayer_gapless_t));
 
-               /* rtsp streaming case, there is no sink after READY TO PAUSE state(no preroll state change).
-                       that's why set position through property. */
-               if ((MMPLAYER_IS_RTSP_STREAMING(player)) &&
-                       (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PAUSED) &&
-                       (MMPLAYER_PREV_STATE(player) == MM_PLAYER_STATE_READY) &&
-                       (!player->videodec_linked) && (!player->audiodec_linked)) {
+       MMPLAYER_FLEAVE();
+       return;
+}
 
-                       g_object_set(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "pending-start-position", pos_nsec, NULL);
-                       LOGD("[%s] set position =%"GST_TIME_FORMAT,
-                                       GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_SRC].gst), GST_TIME_ARGS(pos_nsec));
-                       player->doing_seek = FALSE;
-                       MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
-               } else {
-                       ret = __gst_seek(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, player->playback_rate,
-                                                       GST_FORMAT_TIME, seek_flags,
-                                                       GST_SEEK_TYPE_SET, pos_nsec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
-               }
+static int
+__mmplayer_gst_destroy_pipeline(mmplayer_t *player)
+{
+       gint timeout = 0;
+       int ret = MM_ERROR_NONE;
 
-               if (!ret) {
-                       LOGE("failed to set position. dur[%lu]  pos[%lu]  pos_msec[%llu]\n", dur_msec, position, pos_nsec);
-                       goto SEEK_ERROR;
-               }
-       }
-       break;
+       MMPLAYER_FENTER();
 
-       case MM_PLAYER_POS_FORMAT_PERCENT:
-       {
-               LOGD("seeking to(%lu)%% \n", position);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_INVALID_HANDLE);
 
-               if (player->doing_seek) {
-                       LOGD("not completed seek");
-                       return MM_ERROR_PLAYER_DOING_SEEK;
-               }
+       /* cleanup stuffs */
+       MMPLAYER_FREEIF(player->type);
+       player->no_more_pad = FALSE;
+       player->num_dynamic_pad = 0;
+       player->demux_pad_index = 0;
 
-               if (!internal_called)
-                       player->doing_seek = TRUE;
+       MMPLAYER_SUBTITLE_INFO_LOCK(player);
+       player->subtitle_language_list = NULL;
+       MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
 
-               /* FIXIT : why don't we use 'GST_FORMAT_PERCENT' */
-               pos_nsec = (gint64)((position * player->duration) / 100);
-               ret = __gst_seek(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, player->playback_rate,
-                                               GST_FORMAT_TIME, seek_flags,
-                                               GST_SEEK_TYPE_SET, pos_nsec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
-               if (!ret) {
-                       LOGE("failed to set position. dur[%lud]  pos[%lud]  pos_msec[%"G_GUINT64_FORMAT"]\n", dur_msec, position, pos_nsec);
-                       goto SEEK_ERROR;
-               }
-       }
-       break;
+       __mmplayer_reset_gapless_state(player);
 
-       default:
-               goto INVALID_ARGS;
+       if (player->streamer) {
+               __mm_player_streaming_initialize(player->streamer, FALSE);
+               __mm_player_streaming_destroy(player->streamer);
+               player->streamer = NULL;
        }
 
-       /* NOTE : store last seeking point to overcome some bad operation
-         *     (returning zero when getting current position) of some elements
-         */
-       player->last_position = pos_nsec;
-
-       /* MSL should guarante playback rate when seek is selected during trick play of fast forward. */
-       if (player->playback_rate > 1.0)
-               _mmplayer_set_playspeed((MMHandleType)player, player->playback_rate, FALSE);
-
-       MMPLAYER_FLEAVE();
-       return MM_ERROR_NONE;
+       /* cleanup unlinked mime type */
+       MMPLAYER_FREEIF(player->unlinked_audio_mime);
+       MMPLAYER_FREEIF(player->unlinked_video_mime);
+       MMPLAYER_FREEIF(player->unlinked_demuxer_mime);
 
-PENDING:
-       player->pending_seek.is_pending = TRUE;
-       player->pending_seek.format = format;
-       player->pending_seek.pos = position;
+       /* cleanup running stuffs */
+       __mmplayer_cancel_eos_timer(player);
 
-       LOGW("player current-state : %s, pending-state : %s, just preserve pending position(%lu).\n",
-               MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), MMPLAYER_STATE_GET_NAME(MMPLAYER_PENDING_STATE(player)), player->pending_seek.pos);
+       /* cleanup gst stuffs */
+       if (player->pipeline) {
+               mmplayer_gst_element_t *mainbin = player->pipeline->mainbin;
+               GstTagList *tag_list = player->pipeline->tag_list;
 
-       return MM_ERROR_NONE;
+               /* first we need to disconnect all signal hander */
+               __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_ALL);
 
-INVALID_ARGS:
-       LOGE("invalid arguments, position : %ld  dur : %ld format : %d \n", position, dur_msec, format);
-       return MM_ERROR_INVALID_ARGUMENT;
+               if (mainbin) {
+                       mmplayer_gst_element_t *audiobin = player->pipeline->audiobin;
+                       mmplayer_gst_element_t *videobin = player->pipeline->videobin;
+                       mmplayer_gst_element_t *textbin = player->pipeline->textbin;
+                       GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[MMPLAYER_M_PIPE].gst));
+                       gst_bus_set_sync_handler(bus, NULL, NULL, NULL);
+                       gst_object_unref(bus);
 
-SEEK_ERROR:
-       player->doing_seek = FALSE;
-       return MM_ERROR_PLAYER_SEEK;
-}
+                       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
+                       ret = __mmplayer_gst_set_state(player, mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_NULL, FALSE, timeout);
+                       if (ret != MM_ERROR_NONE) {
+                               LOGE("fail to change state to NULL");
+                               return MM_ERROR_PLAYER_INTERNAL;
+                       }
 
-#define TRICKPLAY_OFFSET GST_MSECOND
+                       LOGW("succeeded in changing state to NULL");
 
-static int
-__gst_get_position(mm_player_t* player, int format, unsigned long* position)
-{
-       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
-       gint64 pos_msec = 0;
-       gboolean ret = TRUE;
+                       gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && position && player->pipeline && player->pipeline->mainbin,
-               MM_ERROR_PLAYER_NOT_INITIALIZED);
+                       /* free fakesink */
+                       if (mainbin[MMPLAYER_M_SRC_FAKESINK].gst)
+                               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC_FAKESINK].gst));
 
-       current_state = MMPLAYER_CURRENT_STATE(player);
+                       /* free avsysaudiosink
+                          avsysaudiosink should be unref when destory pipeline just after start play with BT.
+                          Because audiosink is created but never added to bin, and therefore it will not be unref when pipeline is destroyed.
+                       */
+                       MMPLAYER_FREEIF(audiobin);
+                       MMPLAYER_FREEIF(videobin);
+                       MMPLAYER_FREEIF(textbin);
+                       MMPLAYER_FREEIF(mainbin);
+               }
 
-       /* NOTE : query position except paused state to overcome some bad operation
-        * please refer to below comments in details
-        */
-       if (current_state != MM_PLAYER_STATE_PAUSED)
-               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_msec);
+               if (tag_list)
+                       gst_tag_list_unref(tag_list);
 
-       /* NOTE : get last point to overcome some bad operation of some elements
-        *(returning zero when getting current position in paused state
-        * and when failed to get postion during seeking
-        */
-       if ((current_state == MM_PLAYER_STATE_PAUSED) || (!ret)) {
-               LOGD("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS(pos_msec), ret, current_state);
+               MMPLAYER_FREEIF(player->pipeline);
+       }
+       MMPLAYER_FREEIF(player->album_art);
 
-               if (player->playback_rate < 0.0)
-                       pos_msec = player->last_position - TRICKPLAY_OFFSET;
-               else
-                       pos_msec = player->last_position;
+       if (player->v_stream_caps) {
+               gst_caps_unref(player->v_stream_caps);
+               player->v_stream_caps = NULL;
+       }
 
-               if (!ret)
-                       pos_msec = player->last_position;
-               else
-                       player->last_position = pos_msec;
+       if (player->a_stream_caps) {
+               gst_caps_unref(player->a_stream_caps);
+               player->a_stream_caps = NULL;
+       }
 
-               LOGD("returning last point : %"GST_TIME_FORMAT, GST_TIME_ARGS(pos_msec));
+       if (player->s_stream_caps) {
+               gst_caps_unref(player->s_stream_caps);
+               player->s_stream_caps = NULL;
+       }
+       __mmplayer_track_destroy(player);
 
-       } else {
-               if (player->duration > 0 && pos_msec > player->duration)
-                       pos_msec = player->duration;
+       if (player->sink_elements)
+               g_list_free(player->sink_elements);
+       player->sink_elements = NULL;
 
-               player->last_position = pos_msec;
+       if (player->bufmgr) {
+               tbm_bufmgr_deinit(player->bufmgr);
+               player->bufmgr = NULL;
        }
 
-       switch (format) {
-       case MM_PLAYER_POS_FORMAT_TIME:
-               *position = GST_TIME_AS_MSECONDS(pos_msec);
-               break;
+       LOGW("finished destroy pipeline");
 
-       case MM_PLAYER_POS_FORMAT_PERCENT:
-       {
-               if (player->duration <= 0) {
-                       LOGD("duration is [%lld], so returning position 0\n", player->duration);
-                       *position = 0;
-               } else {
-                       LOGD("postion is [%lld] msec , duration is [%lld] msec", pos_msec, player->duration);
-                       *position = pos_msec * 100 / player->duration;
-               }
-               break;
-       }
-       default:
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
+       MMPLAYER_FLEAVE();
 
-       return MM_ERROR_NONE;
+       return ret;
 }
 
-
-static int __gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos)
+static int
+__mmplayer_gst_realize(mmplayer_t *player)
 {
-#define STREAMING_IS_FINISHED  0
-#define BUFFERING_MAX_PER      100
-#define DEFAULT_PER_VALUE      -1
-#define CHECK_PERCENT_VALUE(a, min, max)(((a) > (min)) ? (((a) < (max)) ? (a) : (max)) : (min))
-
-       MMPlayerGstElement *mainbin = NULL;
-       gint start_per = DEFAULT_PER_VALUE, stop_per = DEFAULT_PER_VALUE;
-       gint64 buffered_total = 0;
-       unsigned long position = 0;
-       gint buffered_sec = -1;
-       GstBufferingMode mode = GST_BUFFERING_STREAM;
-       gint64 content_size_time = player->duration;
-       guint64 content_size_bytes = player->http_content_size;
+       gint timeout = 0;
+       int ret = MM_ERROR_NONE;
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player &&
-                                               player->pipeline &&
-                                               player->pipeline->mainbin,
-                                               MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_FENTER();
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(start_pos && stop_pos, MM_ERROR_INVALID_ARGUMENT);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       *start_pos = 0;
-       *stop_pos = 0;
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
 
-       if (!MMPLAYER_IS_HTTP_STREAMING(player)) {
-               /* and rtsp is not ready yet. */
-               LOGW("it's only used for http streaming case.\n");
-               return MM_ERROR_PLAYER_NO_OP;
+       ret = __mmplayer_gst_create_pipeline(player);
+       if (ret) {
+               LOGE("failed to create pipeline");
+               return ret;
        }
 
-       if (format != MM_PLAYER_POS_FORMAT_PERCENT) {
-               LOGW("Time format is not supported yet.\n");
-               return MM_ERROR_INVALID_ARGUMENT;
-       }
+       /* set pipeline state to READY */
+       /* NOTE : state change to READY must be performed sync. */
+       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
+       ret = __mmplayer_gst_set_state(player,
+                               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_READY, FALSE, timeout);
 
-       if (content_size_time <= 0 || content_size_bytes <= 0) {
-               LOGW("there is no content size.");
-               return MM_ERROR_NONE;
+       if (ret != MM_ERROR_NONE) {
+               /* return error if failed to set state */
+               LOGE("failed to set READY state");
+               return ret;
        }
 
-       if (__gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, &position) != MM_ERROR_NONE) {
-               LOGW("fail to get current position.");
-               return MM_ERROR_NONE;
-       }
+       MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_READY);
 
-       LOGD("pos %d ms, dur %d sec, len %"G_GUINT64_FORMAT" bytes",
-               position, (guint)(content_size_time/GST_SECOND), content_size_bytes);
+       /* create dot before error-return. for debugging */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-realize");
 
-       mainbin = player->pipeline->mainbin;
-       start_per = (gint)(floor(100 *(gdouble)(position*GST_MSECOND) / (gdouble)content_size_time));
-
-       if (mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst) {
-               GstQuery *query = NULL;
-               gint byte_in_rate = 0, byte_out_rate = 0;
-               gint64 estimated_total = 0;
-
-               query = gst_query_new_buffering(GST_FORMAT_BYTES);
-               if (!query || !gst_element_query(mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst, query)) {
-                       LOGW("fail to get buffering query from queue2");
-                       if (query)
-                               gst_query_unref(query);
-                       return MM_ERROR_NONE;
-               }
+       MMPLAYER_FLEAVE();
 
-               gst_query_parse_buffering_stats(query, &mode, &byte_in_rate, &byte_out_rate, NULL);
-               LOGD("mode %d, in_rate %d, out_rate %d", mode, byte_in_rate, byte_out_rate);
+       return ret;
+}
 
-               if (mode == GST_BUFFERING_STREAM) {
-                       /* using only queue in case of push mode(ts / mp3) */
-                       if (gst_element_query_position(mainbin[MMPLAYER_M_SRC].gst,
-                               GST_FORMAT_BYTES, &buffered_total)) {
-                               LOGD("buffered_total %"G_GINT64_FORMAT, buffered_total);
-                               stop_per = 100 * buffered_total / content_size_bytes;
-                       }
-               } else {
-                       /* GST_BUFFERING_TIMESHIFT or GST_BUFFERING_DOWNLOAD */
-                       guint idx = 0;
-                       guint num_of_ranges = 0;
-                       gint64 start_byte = 0, stop_byte = 0;
-
-                       gst_query_parse_buffering_range(query, NULL, NULL, NULL, &estimated_total);
-                       if (estimated_total != STREAMING_IS_FINISHED) {
-                               /* buffered size info from queue2 */
-                               num_of_ranges = gst_query_get_n_buffering_ranges(query);
-                               for (idx = 0; idx < num_of_ranges; idx++) {
-                                       gst_query_parse_nth_buffering_range(query, idx, &start_byte, &stop_byte);
-                                       LOGD("range %d, %"G_GINT64_FORMAT" ~ %"G_GUINT64_FORMAT, idx, start_byte, stop_byte);
-
-                                       buffered_total += (stop_byte - start_byte);
-                               }
-                       } else
-                               stop_per = BUFFERING_MAX_PER;
-               }
-               gst_query_unref(query);
-       }
+static int
+__mmplayer_gst_unrealize(mmplayer_t *player)
+{
+       int ret = MM_ERROR_NONE;
 
-       if (stop_per == DEFAULT_PER_VALUE) {
-               guint dur_sec = (guint)(content_size_time/GST_SECOND);
-               if (dur_sec > 0) {
-                       guint avg_byterate = (guint)(content_size_bytes/dur_sec);
+       MMPLAYER_FENTER();
 
-                       /* buffered size info from multiqueue */
-                       if (mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst) {
-                               guint curr_size_bytes = 0;
-                               g_object_get(G_OBJECT(mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst),
-                                       "curr-size-bytes", &curr_size_bytes, NULL);
-                               LOGD("curr_size_bytes of multiqueue = %d", curr_size_bytes);
-                               buffered_total += curr_size_bytes;
-                       }
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NULL;
+       MMPLAYER_PRINT_STATE(player);
 
-                       if (avg_byterate > 0)
-                               buffered_sec = (gint)(ceil((gdouble)buffered_total/(gdouble)avg_byterate));
-                       else if (player->total_maximum_bitrate > 0)
-                               buffered_sec = (gint)(ceil((gdouble)GET_BIT_FROM_BYTE(buffered_total)/(gdouble)player->total_maximum_bitrate));
-                       else if (player->total_bitrate > 0)
-                               buffered_sec = (gint)(ceil((gdouble)GET_BIT_FROM_BYTE(buffered_total)/(gdouble)player->total_bitrate));
+       /* release miscellaneous information */
+       __mmplayer_release_misc(player);
 
-                       if (buffered_sec >= 0)
-                               stop_per = start_per +(gint)(ceil)(100*(gdouble)buffered_sec/(gdouble)dur_sec);
-               }
+       /* destroy pipeline */
+       ret = __mmplayer_gst_destroy_pipeline(player);
+       if (ret != MM_ERROR_NONE) {
+               LOGE("failed to destory pipeline");
+               return ret;
        }
 
-       *start_pos = CHECK_PERCENT_VALUE(start_per, 0, 100);
-       *stop_pos = CHECK_PERCENT_VALUE(stop_per, *start_pos, 100);
+       /* release miscellaneous information.
+          these info needs to be released after pipeline is destroyed. */
+       __mmplayer_release_misc_post(player);
+
+       MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_NULL);
 
-       LOGD("buffered info: %"G_GINT64_FORMAT" bytes, %d sec, per %lu~%lu\n",
-               buffered_total, buffered_sec, *start_pos, *stop_pos);
+       MMPLAYER_FLEAVE();
 
-       return MM_ERROR_NONE;
+       return ret;
 }
 
 static int
-__gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param)
+__mmplayer_gst_set_message_callback(mmplayer_t *player, MMMessageCallback callback, gpointer user_param)
 {
        MMPLAYER_FENTER();
 
        if (!player) {
-               LOGW("set_message_callback is called with invalid player handle\n");
+               LOGW("set_message_callback is called with invalid player handle");
                return MM_ERROR_PLAYER_NOT_INITIALIZED;
        }
 
        player->msg_cb = callback;
        player->msg_cb_param = user_param;
 
-       LOGD("msg_cb : %p     msg_cb_param : %p\n", callback, user_param);
+       LOGD("msg_cb : %p     msg_cb_param : %p", callback, user_param);
 
        MMPLAYER_FLEAVE();
 
        return MM_ERROR_NONE;
 }
 
-static int __mmfplayer_parse_profile(const char *uri, void *param, MMPlayerParseProfile* data)
+int
+__mmplayer_parse_profile(const char *uri, void *param, mmplayer_parse_profile_t *data)
 {
-       int ret = MM_ERROR_PLAYER_INVALID_URI;
+       int ret = MM_ERROR_NONE;
        char *path = NULL;
 
        MMPLAYER_FENTER();
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(uri , FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL(data , FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL((strlen(uri) <= MM_MAX_URL_LEN), FALSE);
-
-       memset(data, 0, sizeof(MMPlayerParseProfile));
-
-       if ((path = strstr(uri, "es_buff://"))) {
-               if (strlen(path)) {
-                       strncpy(data->uri, uri, MM_MAX_URL_LEN-1);
-                       data->uri_type = MM_PLAYER_URI_TYPE_MS_BUFF;
-                       ret = MM_ERROR_NONE;
-               }
-       } else if ((path = strstr(uri, "rtsp://")) || (path = strstr(uri, "rtsps://"))) {
-               if (strlen(path)) {
-                       strncpy(data->uri, uri, MM_MAX_URL_LEN-1);
-                       data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
-                       ret = MM_ERROR_NONE;
-               }
-       } else if ((path = strstr(uri, "http://")) || (path = strstr(uri, "https://"))) {
-               if (strlen(path)) {
-                       gchar *tmp = NULL;
-                       strncpy(data->uri, uri, MM_MAX_URL_LEN-1);
-                       tmp = g_ascii_strdown(uri, strlen(uri));
-
-                       if (tmp && (g_str_has_suffix(tmp, ".ism/manifest") || g_str_has_suffix(tmp, ".isml/manifest")))
-                               data->uri_type = MM_PLAYER_URI_TYPE_SS;
-                       else
-                               data->uri_type = MM_PLAYER_URI_TYPE_URL_HTTP;
-
-                       ret = MM_ERROR_NONE;
-                       g_free(tmp);
-               }
-       } else if ((path = strstr(uri, "rtspu://"))) {
-               if (strlen(path)) {
-                       strncpy(data->uri, uri, MM_MAX_URL_LEN-1);
-                       data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
-                       ret = MM_ERROR_NONE;
-               }
-       } else if ((path = strstr(uri, "rtspr://"))) {
-               strncpy(data->uri, path, MM_MAX_URL_LEN-1);
-               char *separater = strstr(path, "*");
+       MMPLAYER_RETURN_VAL_IF_FAIL(uri, MM_ERROR_PLAYER_INVALID_URI);
+       MMPLAYER_RETURN_VAL_IF_FAIL(data, MM_ERROR_PLAYER_INTERNAL);
+       MMPLAYER_RETURN_VAL_IF_FAIL((strlen(uri) <= MM_MAX_URL_LEN), MM_ERROR_PLAYER_INVALID_URI);
 
-               if (separater) {
-                       int urgent_len = 0;
-                       char *urgent = separater + strlen("*");
+       memset(data, 0, sizeof(mmplayer_parse_profile_t));
 
-                       if ((urgent_len = strlen(urgent))) {
-                               data->uri[strlen(path) - urgent_len - strlen("*")] = '\0';
-                               strncpy(data->urgent, urgent, MM_MAX_FILENAME_LEN-1);
-                               data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
-                               ret = MM_ERROR_NONE;
-                       }
-               }
-       } else if ((path = strstr(uri, "mms://"))) {
-               if (strlen(path)) {
-                       strncpy(data->uri, uri, MM_MAX_URL_LEN-1);
-                       data->uri_type = MM_PLAYER_URI_TYPE_URL_MMS;
-                       ret = MM_ERROR_NONE;
-               }
+       if (strstr(uri, "es_buff://")) {
+               __mmplayer_copy_uri_and_set_type(data, uri, MM_PLAYER_URI_TYPE_MS_BUFF);
+       } else if (strstr(uri, "rtsp://") || strstr(uri, "rtsps://") || strstr(uri, "rtspu://")) {
+               __mmplayer_copy_uri_and_set_type(data, uri, MM_PLAYER_URI_TYPE_URL_RTSP);
+       } else if (strstr(uri, "http://") || strstr(uri, "https://")) {
+               gchar *tmp = NULL;
+               tmp = g_ascii_strdown(uri, strlen(uri));
+               if (tmp && (g_str_has_suffix(tmp, ".ism/manifest") || g_str_has_suffix(tmp, ".isml/manifest")))
+                       __mmplayer_copy_uri_and_set_type(data, uri, MM_PLAYER_URI_TYPE_SS);
+               else
+                       __mmplayer_copy_uri_and_set_type(data, uri, MM_PLAYER_URI_TYPE_URL_HTTP);
+               g_free(tmp);
+       } else if (strstr(uri, "mms://")) {
+               __mmplayer_copy_uri_and_set_type(data, uri, MM_PLAYER_URI_TYPE_URL_MMS);
        } else if ((path = strstr(uri, "mem://"))) {
-               if (strlen(path)) {
-                       int mem_size = 0;
-                       char *buffer = NULL;
-                       char *seperator = strchr(path, ',');
-                       char ext[100] = {0,}, size[100] = {0,};
-
-                       if (seperator) {
-                               if ((buffer = strstr(path, "ext="))) {
-                                       buffer += strlen("ext=");
-
-                                       if (strlen(buffer)) {
-                                               strncpy(ext, buffer, 99);
-
-                                               if ((seperator = strchr(ext, ','))
-                                                       || (seperator = strchr(ext, ' '))
-                                                       || (seperator = strchr(ext, '\0'))) {
-                                                       seperator[0] = '\0';
-                                               }
-                                       }
-                               }
-
-                               if ((buffer = strstr(path, "size="))) {
-                                       buffer += strlen("size=");
-
-                                       if (strlen(buffer) > 0) {
-                                               strncpy(size, buffer, 99);
-
-                                               if ((seperator = strchr(size, ','))
-                                                       || (seperator = strchr(size, ' '))
-                                                       || (seperator = strchr(size, '\0'))) {
-                                                       seperator[0] = '\0';
-                                               }
-
-                                               mem_size = atoi(size);
-                                       }
-                               }
-                       }
-
-                       LOGD("ext: %s, mem_size: %d, mmap(param): %p\n", ext, mem_size, param);
-                       if (mem_size && param) {
-                               if (data->input_mem.buf)
-                                       free(data->input_mem.buf);
-                               data->input_mem.buf = malloc(mem_size);
-
-                               if (data->input_mem.buf) {
-                                       memcpy(data->input_mem.buf, param, mem_size);
-                                       data->input_mem.len = mem_size;
-                                       ret = MM_ERROR_NONE;
-                               } else {
-                                       LOGE("failed to alloc mem %d", mem_size);
-                                       ret = MM_ERROR_PLAYER_INTERNAL;
-                               }
-
-                               data->input_mem.offset = 0;
-                               data->uri_type = MM_PLAYER_URI_TYPE_MEM;
-                       }
-               }
+               ret = __mmplayer_set_mem_uri(data, path, param);
        } else {
-               gchar *location = NULL;
-               GError *err = NULL;
-
-               if ((path = strstr(uri, "file://"))) {
-
-                       location = g_filename_from_uri(uri, NULL, &err);
-
-                       if (!location || (err != NULL)) {
-                         LOGE("Invalid URI '%s' for filesrc: %s", path,
-                                (err != NULL) ? err->message : "unknown error");
-
-                         if (err) g_error_free(err);
-                         if (location) g_free(location);
-
-                         data->uri_type = MM_PLAYER_URI_TYPE_NONE;
-                         goto exit;
-                       }
-
-                       LOGD("path from uri: %s", location);
-               }
-
-               path = (location != NULL) ? (location) : ((char*)uri);
-               int file_stat = MM_ERROR_NONE;
-
-               file_stat = util_exist_file_path(path);
-
-               /* if no protocol prefix exist. check file existence and then give file:// as it's prefix */
-               if (file_stat == MM_ERROR_NONE) {
-                       g_snprintf(data->uri,  MM_MAX_URL_LEN, "file://%s", path);
-
-                       if (util_is_sdp_file(path)) {
-                               LOGD("uri is actually a file but it's sdp file. giving it to rtspsrc\n");
-                               data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
-                       } else {
-                               data->uri_type = MM_PLAYER_URI_TYPE_FILE;
-                       }
-                       ret = MM_ERROR_NONE;
-               } else if (file_stat == MM_ERROR_PLAYER_PERMISSION_DENIED) {
-                       data->uri_type = MM_PLAYER_URI_TYPE_NO_PERMISSION;
-               } else {
-                       LOGE("invalid uri, could not play..\n");
-                       data->uri_type = MM_PLAYER_URI_TYPE_NONE;
-               }
-
-               if (location) g_free(location);
+               ret = __mmplayer_set_file_uri(data, uri);
        }
 
-exit:
        if (data->uri_type == MM_PLAYER_URI_TYPE_NONE)
                ret = MM_ERROR_PLAYER_FILE_NOT_FOUND;
        else if (data->uri_type == MM_PLAYER_URI_TYPE_NO_PERMISSION)
                ret = MM_ERROR_PLAYER_PERMISSION_DENIED;
 
        /* dump parse result */
-       SECURE_LOGW("incomming uri : %s\n", uri);
-       LOGD("uri_type : %d, mem : %p, mem_size : %d, urgent : %s\n",
+       SECURE_LOGW("incoming uri : %s", uri);
+       LOGD("uri_type : %d, mem : %p, mem_size : %d, urgent : %s",
                data->uri_type, data->input_mem.buf, data->input_mem.len, data->urgent);
 
        MMPLAYER_FLEAVE();
@@ -8102,25 +4425,25 @@ exit:
        return ret;
 }
 
-gboolean
-__mmplayer_can_do_interrupt(mm_player_t *player)
+static gboolean
+__mmplayer_can_do_interrupt(mmplayer_t *player)
 {
        if (!player || !player->pipeline || !player->attrs) {
                LOGW("not initialized");
                goto FAILED;
        }
 
-       if (player->set_mode.pcm_extraction) {
-               LOGW("leave right now, %d", player->set_mode.pcm_extraction);
+       if (player->audio_decoded_cb) {
+               LOGW("not support in pcm extraction mode");
                goto FAILED;
        }
 
        /* check if seeking */
-       if (player->doing_seek) {
+       if (player->seek_state != MMPLAYER_SEEK_NONE) {
                MMMessageParamType msg_param;
                memset(&msg_param, 0, sizeof(MMMessageParamType));
                msg_param.code = MM_ERROR_PLAYER_SEEK;
-               player->doing_seek = FALSE;
+               player->seek_state = MMPLAYER_SEEK_NONE;
                MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
                goto FAILED;
        }
@@ -8155,15 +4478,15 @@ static int
 __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
                void *user_data)
 {
-       mm_player_t *player = NULL;
+       mmplayer_t *player = NULL;
 
        MMPLAYER_FENTER();
 
        if (user_data == NULL) {
-               LOGE("- user_data is null\n");
+               LOGE("- user_data is null");
                return FALSE;
        }
-       player = (mm_player_t *)user_data;
+       player = (mmplayer_t *)user_data;
 
        /* do something to release resource here.
         * player stop and interrupt forwarding */
@@ -8171,16 +4494,16 @@ __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
                LOGW("no need to interrupt, so leave");
        } else {
                MMMessageParamType msg = {0, };
-               unsigned long pos = 0;
+               gint64 pos = 0;
 
                player->interrupted_by_resource = TRUE;
 
                /* get last play position */
-               if (_mmplayer_get_position((MMHandleType)player, MM_PLAYER_POS_FORMAT_TIME, &pos) != MM_ERROR_NONE) {
+               if (_mmplayer_get_position((MMHandleType)player, &pos) != MM_ERROR_NONE) {
                        LOGW("failed to get play position.");
                } else {
                        msg.union_type = MM_MSG_UNION_TIME;
-                       msg.time.elapsed = (unsigned int)pos;
+                       msg.time.elapsed = pos;
                        MMPLAYER_POST_MSG(player, MM_MESSAGE_PLAY_POSITION, &msg);
                }
                LOGD("video resource conflict so, resource will be freed by unrealizing");
@@ -8201,13 +4524,22 @@ __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
        return FALSE;
 }
 
+static void
+__mmplayer_initialize_video_roi(mmplayer_t *player)
+{
+       player->video_roi.scale_x = 0.0;
+       player->video_roi.scale_y = 0.0;
+       player->video_roi.scale_width = 1.0;
+       player->video_roi.scale_height = 1.0;
+}
+
 int
 _mmplayer_create_player(MMHandleType handle)
 {
        int ret = MM_ERROR_PLAYER_INTERNAL;
        bool enabled = false;
 
-       mm_player_t* player = MM_PLAYER_CAST(handle);
+       mmplayer_t *player = MM_PLAYER_CAST(handle);
 
        MMPLAYER_FENTER();
 
@@ -8226,13 +4558,13 @@ _mmplayer_create_player(MMHandleType handle)
        player->attrs = _mmplayer_construct_attribute(handle);
 
        if (!player->attrs) {
-               LOGE("Failed to construct attributes\n");
+               LOGE("Failed to construct attributes");
                return ret;
        }
 
        /* initialize gstreamer with configured parameter */
        if (!__mmplayer_init_gstreamer(player)) {
-               LOGE("Initializing gstreamer failed\n");
+               LOGE("Initializing gstreamer failed");
                _mmplayer_deconstruct_attribute(handle);
                return ret;
        }
@@ -8243,20 +4575,20 @@ _mmplayer_create_player(MMHandleType handle)
        /* create update tag lock */
        g_mutex_init(&player->update_tag_lock);
 
-       /* create next play mutex */
-       g_mutex_init(&player->next_play_thread_mutex);
+       /* create gapless play mutex */
+       g_mutex_init(&player->gapless_play_thread_mutex);
 
-       /* create next play cond */
-       g_cond_init(&player->next_play_thread_cond);
+       /* create gapless play cond */
+       g_cond_init(&player->gapless_play_thread_cond);
 
-       /* create next play thread */
-       player->next_play_thread =
-               g_thread_try_new("next_play_thread", __mmplayer_next_play_thread, (gpointer)player, NULL);
-       if (!player->next_play_thread) {
-               LOGE("failed to create next play thread");
+       /* create gapless play thread */
+       player->gapless_play_thread =
+               g_thread_try_new("gapless_play_thread", __mmplayer_gapless_play_thread, (gpointer)player, NULL);
+       if (!player->gapless_play_thread) {
+               LOGE("failed to create gapless play thread");
                ret = MM_ERROR_PLAYER_RESOURCE_LIMIT;
-               g_mutex_clear(&player->next_play_thread_mutex);
-               g_cond_clear(&player->next_play_thread_cond);
+               g_mutex_clear(&player->gapless_play_thread_mutex);
+               g_cond_clear(&player->gapless_play_thread_cond);
                goto ERROR;
        }
 
@@ -8269,23 +4601,19 @@ _mmplayer_create_player(MMHandleType handle)
 
        ret = _mmplayer_initialize_video_capture(player);
        if (ret != MM_ERROR_NONE) {
-               LOGE("failed to initialize video capture\n");
+               LOGE("failed to initialize video capture");
                goto ERROR;
        }
 
        /* initialize resource manager */
-       if (MM_RESOURCE_MANAGER_ERROR_NONE != mm_resource_manager_create(
-                       MM_RESOURCE_MANAGER_APP_CLASS_MEDIA, __resource_release_cb, player,
-                       &player->resource_manager)) {
-               LOGE("failed to initialize resource manager\n");
+       if (mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
+               __resource_release_cb, player, &player->resource_manager)
+               != MM_RESOURCE_MANAGER_ERROR_NONE) {
+               LOGE("failed to initialize resource manager");
+               ret = MM_ERROR_PLAYER_INTERNAL;
                goto ERROR;
        }
 
-       if (MMPLAYER_IS_HTTP_PD(player)) {
-               player->pd_downloader = NULL;
-               player->pd_file_save_path = NULL;
-       }
-
        /* create video bo lock and cond */
        g_mutex_init(&player->video_bo_mutex);
        g_cond_init(&player->video_bo_cond);
@@ -8305,10 +4633,6 @@ _mmplayer_create_player(MMHandleType handle)
        player->playback_rate = DEFAULT_PLAYBACK_RATE;
 
        player->play_subtitle = FALSE;
-       player->use_deinterleave = FALSE;
-       player->max_audio_channels = 0;
-       player->video_share_api_delta = 0;
-       player->video_share_clock_delta = 0;
        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;
@@ -8344,33 +4668,34 @@ _mmplayer_create_player(MMHandleType handle)
        player->video360_horizontal_fov = PLAYER_SPHERICAL_DEFAULT_H_FOV;
        player->video360_vertical_fov = PLAYER_SPHERICAL_DEFAULT_V_FOV;
 
+       __mmplayer_initialize_video_roi(player);
+
        /* set player state to null */
        MMPLAYER_STATE_CHANGE_TIMEOUT(player) = player->ini.localplayback_state_change_timeout;
        MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_NULL);
 
+       MMPLAYER_FLEAVE();
+
        return MM_ERROR_NONE;
 
 ERROR:
        /* free lock */
        g_mutex_clear(&player->fsink_lock);
-
        /* free update tag lock */
        g_mutex_clear(&player->update_tag_lock);
-
        g_queue_free(player->bus_msg_q);
+       /* free gapless play thread */
+       if (player->gapless_play_thread) {
+               MMPLAYER_GAPLESS_PLAY_THREAD_LOCK(player);
+               player->gapless_play_thread_exit = TRUE;
+               MMPLAYER_GAPLESS_PLAY_THREAD_SIGNAL(player);
+               MMPLAYER_GAPLESS_PLAY_THREAD_UNLOCK(player);
 
-       /* free next play thread */
-       if (player->next_play_thread) {
-               MMPLAYER_NEXT_PLAY_THREAD_LOCK(player);
-               player->next_play_thread_exit = TRUE;
-               MMPLAYER_NEXT_PLAY_THREAD_SIGNAL(player);
-               MMPLAYER_NEXT_PLAY_THREAD_UNLOCK(player);
-
-               g_thread_join(player->next_play_thread);
-               player->next_play_thread = NULL;
+               g_thread_join(player->gapless_play_thread);
+               player->gapless_play_thread = NULL;
 
-               g_mutex_clear(&player->next_play_thread_mutex);
-               g_cond_clear(&player->next_play_thread_cond);
+               g_mutex_clear(&player->gapless_play_thread_mutex);
+               g_cond_clear(&player->gapless_play_thread_cond);
        }
 
        /* release attributes */
@@ -8382,32 +4707,32 @@ ERROR:
 }
 
 static gboolean
-__mmplayer_init_gstreamer(mm_player_t* player)
+__mmplayer_init_gstreamer(mmplayer_t *player)
 {
        static gboolean initialized = FALSE;
        static const int max_argc = 50;
-       gintargc = NULL;
-       gchar** argv = NULL;
-       gchar** argv2 = NULL;
+       gint *argc = NULL;
+       gchar **argv = NULL;
+       gchar **argv2 = NULL;
        GError *err = NULL;
        int i = 0;
        int arg_count = 0;
 
        if (initialized) {
-               LOGD("gstreamer already initialized.\n");
+               LOGD("gstreamer already initialized.");
                return TRUE;
        }
 
        /* alloc */
        argc = malloc(sizeof(int));
-       argv = malloc(sizeof(gchar*) * max_argc);
-       argv2 = malloc(sizeof(gchar*) * max_argc);
+       argv = malloc(sizeof(gchar *) * max_argc);
+       argv2 = malloc(sizeof(gchar *) * max_argc);
 
        if (!argc || !argv || !argv2)
                goto ERROR;
 
-       memset(argv, 0, sizeof(gchar*) * max_argc);
-       memset(argv2, 0, sizeof(gchar*) * max_argc);
+       memset(argv, 0, sizeof(gchar *) * max_argc);
+       memset(argv2, 0, sizeof(gchar *) * max_argc);
 
        /* add initial */
        *argc = 1;
@@ -8438,18 +4763,18 @@ __mmplayer_init_gstreamer(mm_player_t* player)
                (*argc)++;
        }
 
-       LOGD("initializing gstreamer with following parameter\n");
-       LOGD("argc : %d\n", *argc);
+       LOGD("initializing gstreamer with following parameter");
+       LOGD("argc : %d", *argc);
        arg_count = *argc;
 
        for (i = 0; i < arg_count; i++) {
                argv2[i] = argv[i];
-               LOGD("argv[%d] : %s\n", i, argv2[i]);
+               LOGD("argv[%d] : %s", i, argv2[i]);
        }
 
        /* initializing gstreamer */
        if (!gst_init_check(argc, &argv, &err)) {
-               LOGE("Could not initialize GStreamer: %s\n", err ? err->message : "unknown error occurred");
+               LOGE("Could not initialize GStreamer: %s", err ? err->message : "unknown error occurred");
                if (err)
                        g_error_free(err);
 
@@ -8457,7 +4782,7 @@ __mmplayer_init_gstreamer(mm_player_t* player)
        }
        /* release */
        for (i = 0; i < arg_count; i++) {
-               //LOGD("release - argv[%d] : %s\n", i, argv2[i]);
+               //LOGD("release - argv[%d] : %s", i, argv2[i]);
                MMPLAYER_FREEIF(argv2[i]);
        }
 
@@ -8474,7 +4799,7 @@ ERROR:
 
        /* release */
        for (i = 0; i < arg_count; i++) {
-               LOGD("free[%d] : %s\n", i, argv2[i]);
+               LOGD("free[%d] : %s", i, argv2[i]);
                MMPLAYER_FREEIF(argv2[i]);
        }
 
@@ -8485,26 +4810,13 @@ ERROR:
        return FALSE;
 }
 
-int
-__mmplayer_destroy_streaming_ext(mm_player_t* player)
-{
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       if (player->pd_downloader || MMPLAYER_IS_HTTP_PD(player)) {
-               _mmplayer_destroy_pd_downloader((MMHandleType)player);
-               MMPLAYER_FREEIF(player->pd_file_save_path);
-       }
-
-       return MM_ERROR_NONE;
-}
-
 static void
-__mmplayer_check_async_state_transition(mm_player_t* player)
+__mmplayer_check_async_state_transition(mmplayer_t *player)
 {
        GstState element_state = GST_STATE_VOID_PENDING;
        GstState element_pending_state = GST_STATE_VOID_PENDING;
        GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
-       GstElement * element = NULL;
+       GstElement *element = NULL;
        gboolean async = FALSE;
 
        /* check player handle */
@@ -8525,10 +4837,10 @@ __mmplayer_check_async_state_transition(mm_player_t* player)
 
        /* wait for state transition */
        element = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
-       ret = gst_element_get_state(element, &element_state, &element_pending_state, 1*GST_SECOND);
+       ret = gst_element_get_state(element, &element_state, &element_pending_state, 1 * GST_SECOND);
 
        if (ret == GST_STATE_CHANGE_FAILURE) {
-               LOGE(" [%s] state : %s   pending : %s \n",
+               LOGE(" [%s] state : %s   pending : %s",
                        GST_ELEMENT_NAME(element),
                        gst_element_state_get_name(element_state),
                        gst_element_state_get_name(element_pending_state));
@@ -8539,14 +4851,14 @@ __mmplayer_check_async_state_transition(mm_player_t* player)
                return;
        }
 
-       LOGD("[%s] element state has changed\n", GST_ELEMENT_NAME(element));
+       LOGD("[%s] element state has changed", GST_ELEMENT_NAME(element));
        return;
 }
 
 int
 _mmplayer_destroy(MMHandleType handle)
 {
-       mm_player_t* player = MM_PLAYER_CAST(handle);
+       mmplayer_t *player = MM_PLAYER_CAST(handle);
 
        MMPLAYER_FENTER();
 
@@ -8559,20 +4871,18 @@ _mmplayer_destroy(MMHandleType handle)
        /* check async state transition */
        __mmplayer_check_async_state_transition(player);
 
-       __mmplayer_destroy_streaming_ext(player);
+       /* release gapless play thread */
+       if (player->gapless_play_thread) {
+               MMPLAYER_GAPLESS_PLAY_THREAD_LOCK(player);
+               player->gapless_play_thread_exit = TRUE;
+               MMPLAYER_GAPLESS_PLAY_THREAD_SIGNAL(player);
+               MMPLAYER_GAPLESS_PLAY_THREAD_UNLOCK(player);
 
-       /* release next play thread */
-       if (player->next_play_thread) {
-               MMPLAYER_NEXT_PLAY_THREAD_LOCK(player);
-               player->next_play_thread_exit = TRUE;
-               MMPLAYER_NEXT_PLAY_THREAD_SIGNAL(player);
-               MMPLAYER_NEXT_PLAY_THREAD_UNLOCK(player);
-
-               LOGD("waitting for next play thread exit\n");
-               g_thread_join(player->next_play_thread);
-               g_mutex_clear(&player->next_play_thread_mutex);
-               g_cond_clear(&player->next_play_thread_cond);
-               LOGD("next play thread released\n");
+               LOGD("waitting for gapless play thread exit");
+               g_thread_join(player->gapless_play_thread);
+               g_mutex_clear(&player->gapless_play_thread_mutex);
+               g_cond_clear(&player->gapless_play_thread_cond);
+               LOGD("gapless play thread released");
        }
 
        _mmplayer_release_video_capture(player);
@@ -8580,11 +4890,11 @@ _mmplayer_destroy(MMHandleType handle)
        /* de-initialize resource manager */
        if (MM_RESOURCE_MANAGER_ERROR_NONE != mm_resource_manager_destroy(
                        player->resource_manager))
-               LOGE("failed to deinitialize resource manager\n");
+               LOGE("failed to deinitialize resource manager");
 
        /* release pipeline */
        if (MM_ERROR_NONE != __mmplayer_gst_destroy_pipeline(player)) {
-               LOGE("failed to destory pipeline\n");
+               LOGE("failed to destory pipeline");
                return MM_ERROR_PLAYER_INTERNAL;
        }
 
@@ -8625,38 +4935,9 @@ _mmplayer_destroy(MMHandleType handle)
 }
 
 int
-__mmplayer_realize_streaming_ext(mm_player_t* player)
-{
-       int ret = MM_ERROR_NONE;
-
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       if (MMPLAYER_IS_HTTP_PD(player)) {
-               gboolean bret = FALSE;
-
-               player->pd_downloader = _mmplayer_create_pd_downloader();
-               if (!player->pd_downloader) {
-                       LOGE("Unable to create PD Downloader...");
-                       ret = MM_ERROR_PLAYER_NO_FREE_SPACE;
-               }
-
-               bret = _mmplayer_realize_pd_downloader((MMHandleType)player, player->profile.uri, player->pd_file_save_path, player->pipeline->mainbin[MMPLAYER_M_SRC].gst);
-
-               if (FALSE == bret) {
-                       LOGE("Unable to create PD Downloader...");
-                       ret = MM_ERROR_PLAYER_NOT_INITIALIZED;
-               }
-       }
-
-       MMPLAYER_FLEAVE();
-       return ret;
-}
-
-int
 _mmplayer_realize(MMHandleType hplayer)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        char *uri = NULL;
        void *param = NULL;
        MMHandleType attrs = 0;
@@ -8665,24 +4946,24 @@ _mmplayer_realize(MMHandleType hplayer)
        MMPLAYER_FENTER();
 
        /* check player handle */
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED)
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
        /* check current state */
        MMPLAYER_CHECK_STATE(player, MMPLAYER_COMMAND_REALIZE);
 
        attrs = MMPLAYER_GET_ATTRS(player);
        if (!attrs) {
-               LOGE("fail to get attributes.\n");
+               LOGE("fail to get attributes.");
                return MM_ERROR_PLAYER_INTERNAL;
        }
        mm_attrs_get_string_by_name(attrs, "profile_uri", &uri);
        mm_attrs_get_data_by_name(attrs, "profile_user_param", &param);
 
        if (player->profile.uri_type == MM_PLAYER_URI_TYPE_NONE) {
-               ret = __mmfplayer_parse_profile((const char*)uri, param, &player->profile);
+               ret = __mmplayer_parse_profile((const char *)uri, param, &player->profile);
 
                if (ret != MM_ERROR_NONE) {
-                       LOGE("failed to parse profile\n");
+                       LOGE("failed to parse profile");
                        return ret;
                }
        }
@@ -8695,7 +4976,7 @@ _mmplayer_realize(MMHandleType hplayer)
        }
 
        if (player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_MMS) {
-               LOGW("mms protocol is not supported format.\n");
+               LOGW("mms protocol is not supported format.");
                return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
        }
 
@@ -8706,23 +4987,49 @@ _mmplayer_realize(MMHandleType hplayer)
 
        player->smooth_streaming = FALSE;
        player->videodec_linked  = 0;
-       player->videosink_linked = 0;
        player->audiodec_linked  = 0;
-       player->audiosink_linked = 0;
        player->textsink_linked = 0;
        player->is_external_subtitle_present = FALSE;
        player->is_external_subtitle_added_now = FALSE;
-       /* set the subtitle ON default */
-       player->is_subtitle_off = FALSE;
+       player->is_subtitle_off = FALSE; /* set the subtitle ON default */
+       player->video360_metadata.is_spherical = -1;
+       player->is_openal_plugin_used = FALSE;
+       player->demux_pad_index = 0;
+       player->subtitle_language_list = NULL;
+       player->is_subtitle_force_drop = FALSE;
+
+       __mmplayer_track_initialize(player);
+       __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
+
+       if ((MMPLAYER_IS_STREAMING(player)) && (player->streamer == NULL)) {
+               gint prebuffer_ms = 0, rebuffer_ms = 0;
+
+               player->streamer = __mm_player_streaming_create();
+               __mm_player_streaming_initialize(player->streamer, TRUE);
+
+               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);
+
+               if (prebuffer_ms > 0) {
+                       prebuffer_ms = MAX(prebuffer_ms, 1000);
+                       player->streamer->buffering_req.prebuffer_time = prebuffer_ms;
+               }
+
+               if (rebuffer_ms > 0) {
+                       player->streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_FIXED;
+                       rebuffer_ms = MAX(rebuffer_ms, 1000);
+                       player->streamer->buffering_req.rebuffer_time = rebuffer_ms;
+               }
+
+               LOGD("buffering time %d ms, %d ms", player->streamer->buffering_req.prebuffer_time,
+                                                               player->streamer->buffering_req.rebuffer_time);
+       }
 
        /* realize pipeline */
-       ret = __gst_realize(player);
+       ret = __mmplayer_gst_realize(player);
        if (ret != MM_ERROR_NONE)
-               LOGE("fail to realize the player.\n");
-       else
-               ret = __mmplayer_realize_streaming_ext(player);
+               LOGE("fail to realize the player.");
 
-       player->bus_msg_timeout = PLAYER_BUS_MSG_PREPARE_TIMEOUT;
        MMPLAYER_BUS_MSG_THREAD_SIGNAL(player);
 
        MMPLAYER_FLEAVE();
@@ -8731,23 +5038,9 @@ _mmplayer_realize(MMHandleType hplayer)
 }
 
 int
-__mmplayer_unrealize_streaming_ext(mm_player_t *player)
-{
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       /* destroy can called at anytime */
-       if (player->pd_downloader && MMPLAYER_IS_HTTP_PD(player))
-               _mmplayer_unrealize_pd_downloader((MMHandleType)player);
-
-       MMPLAYER_FLEAVE();
-       return MM_ERROR_NONE;
-}
-
-int
 _mmplayer_unrealize(MMHandleType hplayer)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        int ret = MM_ERROR_NONE;
 
        MMPLAYER_FENTER();
@@ -8757,7 +5050,7 @@ _mmplayer_unrealize(MMHandleType hplayer)
        MMPLAYER_CMD_UNLOCK(player);
        /* destroy the gst bus msg thread which is created during realize.
           this funct have to be called before getting cmd lock. */
-       _mmplayer_bus_msg_thread_destroy(player);
+       __mmplayer_bus_msg_thread_destroy(player);
        MMPLAYER_CMD_LOCK(player);
 
        /* check current state */
@@ -8766,10 +5059,8 @@ _mmplayer_unrealize(MMHandleType hplayer)
        /* check async state transition */
        __mmplayer_check_async_state_transition(player);
 
-       __mmplayer_unrealize_streaming_ext(player);
-
        /* unrealize pipeline */
-       ret = __gst_unrealize(player);
+       ret = __mmplayer_gst_unrealize(player);
 
        /* set asm stop if success */
        if (MM_ERROR_NONE == ret) {
@@ -8778,7 +5069,7 @@ _mmplayer_unrealize(MMHandleType hplayer)
                                ret = mm_resource_manager_mark_for_release(player->resource_manager,
                                                player->video_decoder_resource);
                                if (ret != MM_RESOURCE_MANAGER_ERROR_NONE)
-                                       LOGE("failed to mark decoder resource for release, ret(0x%x)\n", ret);
+                                       LOGE("failed to mark decoder resource for release, ret(0x%x)", ret);
                                else
                                        player->video_decoder_resource = NULL;
                        }
@@ -8787,14 +5078,14 @@ _mmplayer_unrealize(MMHandleType hplayer)
                                ret = mm_resource_manager_mark_for_release(player->resource_manager,
                                                player->video_overlay_resource);
                                if (ret != MM_RESOURCE_MANAGER_ERROR_NONE)
-                                       LOGE("failed to mark overlay resource for release, ret(0x%x)\n", ret);
+                                       LOGE("failed to mark overlay resource for release, ret(0x%x)", ret);
                                else
                                        player->video_overlay_resource = NULL;
                        }
 
                        ret = mm_resource_manager_commit(player->resource_manager);
                        if (ret != MM_RESOURCE_MANAGER_ERROR_NONE)
-                               LOGE("failed to commit resource releases, ret(0x%x)\n", ret);
+                               LOGE("failed to commit resource releases, ret(0x%x)", ret);
                }
        } else
                LOGE("failed and don't change asm state to stop");
@@ -8807,17 +5098,17 @@ _mmplayer_unrealize(MMHandleType hplayer)
 int
 _mmplayer_set_message_callback(MMHandleType hplayer, MMMessageCallback callback, gpointer user_param)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       return __gst_set_message_callback(player, callback, user_param);
+       return __mmplayer_gst_set_message_callback(player, callback, user_param);
 }
 
 int
-_mmplayer_get_state(MMHandleType hplayer, intstate)
+_mmplayer_get_state(MMHandleType hplayer, int *state)
 {
-       mm_player_t *player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_RETURN_VAL_IF_FAIL(state, MM_ERROR_INVALID_ARGUMENT);
 
@@ -8826,140 +5117,132 @@ _mmplayer_get_state(MMHandleType hplayer, int* state)
        return MM_ERROR_NONE;
 }
 
-
-int
-_mmplayer_set_volume(MMHandleType hplayer, MMPlayerVolumeType volume)
+static int
+__mmplayer_gst_set_volume_property(mmplayer_t *player, const char *prop_name)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
-       GstElement* vol_element = NULL;
-       int i = 0;
+       GstElement *vol_element = NULL;
+       enum audio_element_id volume_elem_id = MMPLAYER_A_VOL;
 
        MMPLAYER_FENTER();
-
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       LOGD("volume [L]=%f:[R]=%f\n",
-               volume.level[MM_VOLUME_CHANNEL_LEFT], volume.level[MM_VOLUME_CHANNEL_RIGHT]);
-
-       /* invalid factor range or not */
-       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++) {
-               if (volume.level[i] < MM_VOLUME_FACTOR_MIN || volume.level[i] > MM_VOLUME_FACTOR_MAX) {
-                       LOGE("Invalid factor!(valid factor:0~1.0)\n");
-                       return MM_ERROR_INVALID_ARGUMENT;
-               }
-       }
-
-       /* not support to set other value into each channel */
-       if ((volume.level[MM_VOLUME_CHANNEL_LEFT] != volume.level[MM_VOLUME_CHANNEL_RIGHT]))
-               return MM_ERROR_INVALID_ARGUMENT;
-
-       /* Save volume to handle. Currently the first array element will be saved. */
-       player->sound.volume = volume.level[MM_VOLUME_CHANNEL_LEFT];
+       MMPLAYER_RETURN_VAL_IF_FAIL(prop_name, MM_ERROR_INVALID_ARGUMENT);
 
        /* check pipeline handle */
        if (!player->pipeline || !player->pipeline->audiobin) {
-               LOGD("audiobin is not created yet\n");
-               LOGD("but, current stored volume will be set when it's created.\n");
+               LOGD("'%s' will be applied when audiobin is created", prop_name);
 
-               /* NOTE : stored volume will be used in create_audiobin
+               /* NOTE : stored value will be used in create_audiobin
                 * returning MM_ERROR_NONE here makes application to able to
-                * set volume at anytime.
+                * set audio volume or mute at anytime.
                 */
                return MM_ERROR_NONE;
        }
 
-       /* setting volume to volume element */
-       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+       if (player->build_audio_offload) {
+               LOGD("offload pipeline");
+               volume_elem_id = MMPLAYER_A_SINK;
+       }
 
-       if (vol_element) {
-               LOGD("volume is set [%f]\n", player->sound.volume);
-               g_object_set(vol_element, "volume", player->sound.volume, NULL);
+       vol_element = player->pipeline->audiobin[volume_elem_id].gst;
+       if (!vol_element) {
+               LOGE("failed to get vol element %d", volume_elem_id);
+               return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       MMPLAYER_FLEAVE();
+       LOGD("set '%s' property to element[%s]", prop_name, GST_ELEMENT_NAME(vol_element));
+
+       if (!g_object_class_find_property(G_OBJECT_GET_CLASS(vol_element), prop_name)) {
+               LOGE("there is no '%s' property", prop_name);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       if (!strcmp(prop_name, "volume")) {
+               g_object_set(vol_element, "volume", player->sound.volume, NULL);
+       } else if (!strcmp(prop_name, "mute")) {
+               g_object_set(vol_element, "mute", player->sound.mute, NULL);
+       } else {
+               LOGE("invalid property %s", prop_name);
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
        return MM_ERROR_NONE;
 }
 
-
 int
-_mmplayer_get_volume(MMHandleType hplayer, MMPlayerVolumeType* volume)
+_mmplayer_set_volume(MMHandleType hplayer, float volume)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
-       int i = 0;
+       int ret = MM_ERROR_NONE;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
-
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(volume, MM_ERROR_INVALID_ARGUMENT);
 
-       /* returning stored volume */
-       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++)
-               volume->level[i] = player->sound.volume;
+       LOGD("volume = %f", volume);
 
-       MMPLAYER_FLEAVE();
+       /* invalid factor range or not */
+       if (volume < MM_VOLUME_FACTOR_MIN || volume > MM_VOLUME_FACTOR_MAX) {
+               LOGE("Invalid volume value");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
 
-       return MM_ERROR_NONE;
+       player->sound.volume = volume;
+
+       ret = __mmplayer_gst_set_volume_property(player, "volume");
+
+       MMPLAYER_FLEAVE();
+       return ret;
 }
 
 int
-_mmplayer_set_mute(MMHandleType hplayer, int mute)
+_mmplayer_get_volume(MMHandleType hplayer, float *volume)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
-       GstElement* vol_element = NULL;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(volume, MM_ERROR_INVALID_ARGUMENT);
 
-       /* mute value shoud 0 or 1 */
-       if (mute != 0 && mute != 1) {
-               LOGE("bad mute value\n");
+       *volume = player->sound.volume;
 
-               /* FIXIT : definitly, we need _BAD_PARAM error code */
-               return MM_ERROR_INVALID_ARGUMENT;
-       }
+       LOGD("current vol = %f", *volume);
 
-       player->sound.mute = mute;
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
+}
+
+int
+_mmplayer_set_mute(MMHandleType hplayer, bool mute)
+{
+       int ret = MM_ERROR_NONE;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       /* just hold mute value if pipeline is not ready */
-       if (!player->pipeline || !player->pipeline->audiobin) {
-               LOGD("pipeline is not ready. holding mute value\n");
-               return MM_ERROR_NONE;
-       }
+       LOGD("mute = %d", mute);
 
-       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+       player->sound.mute = mute;
 
-       /* NOTE : volume will only created when the bt is enabled */
-       if (vol_element) {
-               LOGD("mute : %d\n", mute);
-               g_object_set(vol_element, "mute", mute, NULL);
-       } else
-               LOGD("volume elemnet is not created. using volume in audiosink\n");
+       ret = __mmplayer_gst_set_volume_property(player, "mute");
 
        MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
+       return ret;
 }
 
 int
-_mmplayer_get_mute(MMHandleType hplayer, int* pmute)
+_mmplayer_get_mute(MMHandleType hplayer, bool *mute)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(pmute, MM_ERROR_INVALID_ARGUMENT);
+       MMPLAYER_RETURN_VAL_IF_FAIL(mute, MM_ERROR_INVALID_ARGUMENT);
 
-       /* just hold mute value if pipeline is not ready */
-       if (!player->pipeline || !player->pipeline->audiobin) {
-               LOGD("pipeline is not ready. returning stored value\n");
-               *pmute = player->sound.mute;
-               return MM_ERROR_NONE;
-       }
+       *mute = player->sound.mute;
 
-       *pmute = player->sound.mute;
+       LOGD("current mute = %d", *mute);
 
        MMPLAYER_FLEAVE();
 
@@ -8969,7 +5252,7 @@ _mmplayer_get_mute(MMHandleType hplayer, int* pmute)
 int
 _mmplayer_set_videostream_changed_cb(MMHandleType hplayer, mm_player_stream_changed_callback callback, void *user_param)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
 
@@ -8977,7 +5260,7 @@ _mmplayer_set_videostream_changed_cb(MMHandleType hplayer, mm_player_stream_chan
 
        player->video_stream_changed_cb = callback;
        player->video_stream_changed_cb_user_param = user_param;
-       LOGD("Handle value is %p : %p\n", player, player->video_stream_changed_cb);
+       LOGD("Handle value is %p : %p", player, player->video_stream_changed_cb);
 
        MMPLAYER_FLEAVE();
 
@@ -8987,7 +5270,7 @@ _mmplayer_set_videostream_changed_cb(MMHandleType hplayer, mm_player_stream_chan
 int
 _mmplayer_set_audiostream_changed_cb(MMHandleType hplayer, mm_player_stream_changed_callback callback, void *user_param)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
 
@@ -8995,7 +5278,7 @@ _mmplayer_set_audiostream_changed_cb(MMHandleType hplayer, mm_player_stream_chan
 
        player->audio_stream_changed_cb = callback;
        player->audio_stream_changed_cb_user_param = user_param;
-       LOGD("Handle value is %p : %p\n", player, player->audio_stream_changed_cb);
+       LOGD("Handle value is %p : %p", player, player->audio_stream_changed_cb);
 
        MMPLAYER_FLEAVE();
 
@@ -9003,18 +5286,18 @@ _mmplayer_set_audiostream_changed_cb(MMHandleType hplayer, mm_player_stream_chan
 }
 
 int
-_mmplayer_set_audiostream_cb_ex(MMHandleType hplayer, bool sync, mm_player_audio_stream_callback_ex callback, void *user_param)
+_mmplayer_set_audio_decoded_cb(MMHandleType hplayer, mmplayer_audio_extract_opt_e opt, mm_player_audio_decoded_callback callback, void *user_param)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       player->audio_stream_render_cb_ex = callback;
-       player->audio_stream_cb_user_param = user_param;
-       player->audio_stream_sink_sync = sync;
-       LOGD("Audio Stream cb Handle value is %p : %p audio_stream_sink_sync : %d\n", player, player->audio_stream_render_cb_ex, player->audio_stream_sink_sync);
+       player->audio_decoded_cb = callback;
+       player->audio_decoded_cb_user_param = user_param;
+       player->audio_extract_opt = opt;
+       LOGD("handle: %p, cb: %p, opt: 0x%X", player, player->audio_decoded_cb, player->audio_extract_opt);
 
        MMPLAYER_FLEAVE();
 
@@ -9022,9 +5305,9 @@ _mmplayer_set_audiostream_cb_ex(MMHandleType hplayer, bool sync, mm_player_audio
 }
 
 int
-_mmplayer_set_videostream_cb(MMHandleType hplayer, mm_player_video_stream_callback callback, void *user_param)
+_mmplayer_set_video_decoded_cb(MMHandleType hplayer, mm_player_video_decoded_callback callback, void *user_param)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
 
@@ -9033,102 +5316,39 @@ _mmplayer_set_videostream_cb(MMHandleType hplayer, mm_player_video_stream_callba
        if (callback && !player->bufmgr)
                player->bufmgr = tbm_bufmgr_init(-1);
 
-       player->set_mode.media_packet_video_stream = (callback) ? TRUE : FALSE;
-       player->video_stream_cb = callback;
-       player->video_stream_cb_user_param = user_param;
-
-       LOGD("Stream cb Handle value is %p : %p, enable:%d\n", player, player->video_stream_cb, player->set_mode.media_packet_video_stream);
-
-       MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
-}
-
-int
-_mmplayer_set_audiostream_cb(MMHandleType hplayer, mm_player_audio_stream_callback callback, void *user_param)
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       player->set_mode.video_export = (callback) ? true : false;
+       player->video_decoded_cb = callback;
+       player->video_decoded_cb_user_param = user_param;
 
-       player->audio_stream_cb = callback;
-       player->audio_stream_cb_user_param = user_param;
-       LOGD("Audio Stream cb Handle value is %p : %p\n", player, player->audio_stream_cb);
+       LOGD("Stream cb Handle value is %p : %p, enable:%d", player, player->video_decoded_cb, player->set_mode.video_export);
 
        MMPLAYER_FLEAVE();
 
        return MM_ERROR_NONE;
 }
 
-static int
-__mmplayer_start_streaming_ext(mm_player_t *player)
-{
-       gint ret = MM_ERROR_NONE;
-
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       if (MMPLAYER_IS_HTTP_PD(player)) {
-               if (!player->pd_downloader) {
-                       ret = __mmplayer_realize_streaming_ext(player);
-
-                       if (ret != MM_ERROR_NONE) {
-                               LOGE("failed to realize streaming ext\n");
-                               return ret;
-                       }
-               }
-
-               if (player->pd_downloader && player->pd_mode == MM_PLAYER_PD_MODE_URI) {
-                       ret = _mmplayer_start_pd_downloader((MMHandleType)player);
-                       if (!ret) {
-                               LOGE("ERROR while starting PD...\n");
-                               return MM_ERROR_PLAYER_NOT_INITIALIZED;
-                       }
-                       ret = MM_ERROR_NONE;
-               }
-       }
-
-       MMPLAYER_FLEAVE();
-       return ret;
-}
-
 int
 _mmplayer_start(MMHandleType hplayer)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        gint ret = MM_ERROR_NONE;
 
        MMPLAYER_FENTER();
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
        /* check current state */
        MMPLAYER_CHECK_STATE(player, MMPLAYER_COMMAND_START);
 
-       /* NOTE : we should check and create pipeline again if not created as we destroy
-        * whole pipeline when stopping in streamming playback
-        */
-       if (!player->pipeline) {
-               ret = __gst_realize(player);
-               if (MM_ERROR_NONE != ret) {
-                       LOGE("failed to realize before starting. only in streamming\n");
-                       /* unlock */
-                       return ret;
-               }
-       }
-
-       ret = __mmplayer_start_streaming_ext(player);
-       if (ret != MM_ERROR_NONE) {
-               LOGE("failed to start streaming ext 0x%X", ret);
-               return ret;
-       }
-
        /* start pipeline */
-       ret = __gst_start(player);
+       ret = __mmplayer_gst_start(player);
        if (ret != MM_ERROR_NONE)
-               LOGE("failed to start player.\n");
+               LOGE("failed to start player.");
+
+       if ((player->streamer) && (player->streamer->buffering_state & MM_PLAYER_BUFFERING_IN_PROGRESS)) {
+               LOGD("force playing start even during buffering");
+               player->streamer->buffering_state = MM_PLAYER_BUFFERING_ABORT;
+       }
 
        MMPLAYER_FLEAVE();
 
@@ -9137,12 +5357,12 @@ _mmplayer_start(MMHandleType hplayer)
 
 /* NOTE: post "not supported codec message" to application
  * when one codec is not found during AUTOPLUGGING in MSL.
- * So, it's separated with error of __mmplayer_gst_callback().
+ * So, it's separated with error of __mmplayer_gst_bus_msg_callback().
  * And, if any codec is not found, don't send message here.
  * Because GST_ERROR_MESSAGE is posted by other plugin internally.
  */
 int
-__mmplayer_handle_missed_plugin(mm_player_t* player)
+__mmplayer_handle_missed_plugin(mmplayer_t *player)
 {
        MMMessageParamType msg_param;
        memset(&msg_param, 0, sizeof(MMMessageParamType));
@@ -9152,7 +5372,7 @@ __mmplayer_handle_missed_plugin(mm_player_t* player)
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       LOGD("not_supported_codec = 0x%02x, can_support_codec = 0x%02x\n",
+       LOGD("not_supported_codec = 0x%02x, can_support_codec = 0x%02x",
                        player->not_supported_codec, player->can_support_codec);
 
        if (player->not_found_demuxer) {
@@ -9179,12 +5399,12 @@ __mmplayer_handle_missed_plugin(mm_player_t* player)
                        memset(&msg_param, 0, sizeof(MMMessageParamType));
 
                        if (player->not_supported_codec ==  MISSING_PLUGIN_AUDIO) {
-                               LOGW("not found AUDIO codec, posting error code to application.\n");
+                               LOGW("not found AUDIO codec, posting error code to application.");
 
                                msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
                                msg_param.data = g_strdup_printf("%s", player->unlinked_audio_mime);
                        } else if (player->not_supported_codec ==  MISSING_PLUGIN_VIDEO) {
-                               LOGW("not found VIDEO codec, posting error code to application.\n");
+                               LOGW("not found VIDEO codec, posting error code to application.");
 
                                msg_param.code = MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
                                msg_param.data = g_strdup_printf("%s", player->unlinked_video_mime);
@@ -9197,7 +5417,7 @@ __mmplayer_handle_missed_plugin(mm_player_t* player)
                        return MM_ERROR_NONE;
                } else {
                        // no any supported codec case
-                       LOGW("not found any codec, posting error code to application.\n");
+                       LOGW("not found any codec, posting error code to application.");
 
                        if (player->not_supported_codec ==  MISSING_PLUGIN_AUDIO) {
                                msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
@@ -9218,34 +5438,35 @@ __mmplayer_handle_missed_plugin(mm_player_t* player)
        return MM_ERROR_NONE;
 }
 
-static void __mmplayer_check_pipeline(mm_player_t* player)
+static void
+__mmplayer_check_pipeline(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;
 
-       if (player->gapless.reconfigure) {
-               LOGW("pipeline is under construction.\n");
+       if (!player->gapless.reconfigure)
+               return;
 
-               MMPLAYER_PLAYBACK_LOCK(player);
-               MMPLAYER_PLAYBACK_UNLOCK(player);
+       LOGW("pipeline is under construction.");
 
-               timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
+       MMPLAYER_PLAYBACK_LOCK(player);
+       MMPLAYER_PLAYBACK_UNLOCK(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);
+       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
 
-               if (ret == GST_STATE_CHANGE_FAILURE)
-                       LOGE("failed to change pipeline state within %d sec\n", timeout);
-       }
+       /* wait for state transition */
+       ret = gst_element_get_state(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &element_state, &element_pending_state, timeout * GST_SECOND);
+       if (ret == GST_STATE_CHANGE_FAILURE)
+               LOGE("failed to change pipeline state within %d sec", timeout);
 }
 
 /* NOTE : it should be able to call 'stop' anytime*/
 int
 _mmplayer_stop(MMHandleType hplayer)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        int ret = MM_ERROR_NONE;
 
        MMPLAYER_FENTER();
@@ -9262,16 +5483,14 @@ _mmplayer_stop(MMHandleType hplayer)
        /* NOTE : application should not wait for EOS after calling STOP */
        __mmplayer_cancel_eos_timer(player);
 
-       __mmplayer_unrealize_streaming_ext(player);
-
        /* reset */
-       player->doing_seek = FALSE;
+       player->seek_state = MMPLAYER_SEEK_NONE;
 
        /* stop pipeline */
-       ret = __gst_stop(player);
+       ret = __mmplayer_gst_stop(player);
 
        if (ret != MM_ERROR_NONE)
-               LOGE("failed to stop player.\n");
+               LOGE("failed to stop player.");
 
        MMPLAYER_FLEAVE();
 
@@ -9281,8 +5500,8 @@ _mmplayer_stop(MMHandleType hplayer)
 int
 _mmplayer_pause(MMHandleType hplayer)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
-       gint64 pos_msec = 0;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       gint64 pos_nsec = 0;
        gboolean async = FALSE;
        gint ret = MM_ERROR_NONE;
 
@@ -9319,10 +5538,10 @@ _mmplayer_pause(MMHandleType hplayer)
                        *(returning zero when getting current position in paused state) of some
                        * elements
                        */
-                       if (!gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_msec))
-                               LOGW("getting current position failed in paused\n");
+                       if (!gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_nsec))
+                               LOGW("getting current position failed in paused");
 
-                       player->last_position = pos_msec;
+                       player->last_position = pos_nsec;
 
                        /* For rtspsrc stack , npt-start value coming from server is used for finding the current position.
                           But when a rtsp clip (especially from Youtube Desktop View) is paused and kept for sometime,npt-start is still increasing.
@@ -9342,10 +5561,10 @@ _mmplayer_pause(MMHandleType hplayer)
        }
 
        /* pause pipeline */
-       ret = __gst_pause(player, async);
+       ret = __mmplayer_gst_pause(player, async);
 
        if (ret != MM_ERROR_NONE)
-               LOGE("failed to pause player. ret : 0x%x\n", ret);
+               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"))
@@ -9357,111 +5576,82 @@ _mmplayer_pause(MMHandleType hplayer)
        return ret;
 }
 
+/* in case of streaming, pause could take long time.*/
 int
-_mmplayer_resume(MMHandleType hplayer)
+_mmplayer_abort_pause(MMHandleType hplayer)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        int ret = MM_ERROR_NONE;
-       gboolean async = FALSE;
 
        MMPLAYER_FENTER();
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       /* Changing back sync mode rtspsrc to async */
-       if ((MMPLAYER_IS_RTSP_STREAMING(player))) {
-               LOGD("async resume for rtsp case");
-               async = TRUE;
-       }
-
-       /* check current state */
-       MMPLAYER_CHECK_STATE(player, MMPLAYER_COMMAND_RESUME);
-
-       ret = __gst_resume(player, async);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player &&
+                                               player->pipeline &&
+                                               player->pipeline->mainbin,
+                                               MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       if (ret != MM_ERROR_NONE)
-               LOGE("failed to resume player.\n");
+       LOGD("set the pipeline state to READY");
 
-       MMPLAYER_FLEAVE();
+       /* set state to READY */
+       ret = __mmplayer_gst_set_state(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+                                               GST_STATE_READY, FALSE, MMPLAYER_STATE_CHANGE_TIMEOUT(player));
+       if (ret != MM_ERROR_NONE) {
+               LOGE("fail to change state to READY");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
+       LOGD("succeeded in changing state to READY");
        return ret;
 }
 
-static int
-__mmplayer_set_pcm_extraction(mm_player_t* player)
+int
+_mmplayer_resume(MMHandleType hplayer)
 {
-       gint64 start_nsec = 0;
-       gint64 end_nsec = 0;
-       gint64 dur_nsec = 0;
-       gint64 dur_msec = 0;
-       int required_start = 0;
-       int required_end = 0;
-       int ret = 0;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       int ret = MM_ERROR_NONE;
+       gboolean async = FALSE;
 
        MMPLAYER_FENTER();
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-
-       mm_attrs_multiple_get(player->attrs,
-               NULL,
-               "pcm_extraction_start_msec", &required_start,
-               "pcm_extraction_end_msec", &required_end,
-               NULL);
-
-       LOGD("pcm extraction required position is from [%d] to [%d](msec)\n", required_start, required_end);
-
-       if (required_start == 0 && required_end == 0) {
-               LOGD("extracting entire stream");
-               return MM_ERROR_NONE;
-       } else if (required_start < 0 || required_start > required_end || required_end < 0) {
-               LOGD("invalid range for pcm extraction");
-               return MM_ERROR_INVALID_ARGUMENT;
-       }
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       /* get duration */
-       ret = gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &dur_nsec);
-       if (!ret) {
-               LOGE("failed to get duration");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-       dur_msec = GST_TIME_AS_MSECONDS(dur_nsec);
+       if ((MMPLAYER_IS_RTSP_STREAMING(player))) {
+               if (player->is_external_subtitle_added_now) { /* after setting external subtitle, seeking and buffering is in progress. */
+                       player->pending_resume = TRUE; /* will be resumed after finishing the buffering. */
+                       return ret;
+               }
 
-       if (dur_msec < required_end) {
-               // FIXME
-               LOGD("invalid end pos for pcm extraction");
-               return MM_ERROR_INVALID_ARGUMENT;
+               /* Changing back sync mode rtspsrc to async */
+               LOGD("async resume for rtsp case");
+               async = TRUE;
        }
 
-       start_nsec = required_start * G_GINT64_CONSTANT(1000000);
-       end_nsec = required_end * G_GINT64_CONSTANT(1000000);
+       /* check current state */
+       MMPLAYER_CHECK_STATE(player, MMPLAYER_COMMAND_RESUME);
 
-       if ((!__gst_seek(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
-                                       1.0,
-                                       GST_FORMAT_TIME,
-                                       (GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE),
-                                       GST_SEEK_TYPE_SET, start_nsec,
-                                       GST_SEEK_TYPE_SET, end_nsec))) {
-               LOGE("failed to seek for pcm extraction\n");
+       ret = __mmplayer_gst_resume(player, async);
+       if (ret != MM_ERROR_NONE)
+               LOGE("failed to resume player.");
 
-               return MM_ERROR_PLAYER_SEEK;
+       if ((player->streamer) && (player->streamer->buffering_state & MM_PLAYER_BUFFERING_IN_PROGRESS)) {
+               LOGD("force resume even during buffering");
+               player->streamer->buffering_state = MM_PLAYER_BUFFERING_ABORT;
        }
 
-       LOGD("succeeded to set up segment extraction from [%llu] to [%llu](nsec)\n", start_nsec, end_nsec);
-
        MMPLAYER_FLEAVE();
 
-       return MM_ERROR_NONE;
+       return ret;
 }
 
 int
 _mmplayer_set_playspeed(MMHandleType hplayer, float rate, bool streaming)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
-       gint64 pos_msec = 0;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       gint64 pos_nsec = 0;
        int ret = MM_ERROR_NONE;
-       int mute = FALSE;
+       bool mute = false;
        signed long long start = 0, stop = 0;
-       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
+       mmplayer_state_e current_state = MM_PLAYER_STATE_NONE;
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
@@ -9470,7 +5660,7 @@ _mmplayer_set_playspeed(MMHandleType hplayer, float rate, bool streaming)
        /* The sound of video is not supported under 0.0 and over 2.0. */
        if (rate >= TRICK_PLAY_MUTE_THRESHOLD_MAX || rate < TRICK_PLAY_MUTE_THRESHOLD_MIN) {
                if (player->can_support_codec & FOUND_PLUGIN_VIDEO)
-                       mute = TRUE;
+                       mute = true;
        }
        _mmplayer_set_mute(hplayer, mute);
 
@@ -9479,41 +5669,41 @@ _mmplayer_set_playspeed(MMHandleType hplayer, float rate, bool streaming)
 
        /* If the position is reached at start potion during fast backward, EOS is posted.
         * So, This EOS have to be classified with it which is posted at reaching the end of stream.
-        * */
+        */
        player->playback_rate = rate;
 
        current_state = MMPLAYER_CURRENT_STATE(player);
 
        if (current_state != MM_PLAYER_STATE_PAUSED)
-               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_msec);
+               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_nsec);
 
-       LOGD("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS(pos_msec), ret, current_state);
+       LOGD("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS(pos_nsec), ret, current_state);
 
        if ((current_state == MM_PLAYER_STATE_PAUSED)
                || (!ret) /*|| (player->last_position != 0 && pos_msec == 0)*/) {
-               LOGW("returning last point : %lld\n", player->last_position);
-               pos_msec = player->last_position;
+               LOGW("returning last point : %"G_GINT64_FORMAT, player->last_position);
+               pos_nsec = player->last_position;
        }
 
        if (rate >= 0) {
-               start = pos_msec;
+               start = pos_nsec;
                stop = GST_CLOCK_TIME_NONE;
        } else {
                start = GST_CLOCK_TIME_NONE;
-               stop = pos_msec;
+               stop = pos_nsec;
        }
 
-       if (!__gst_seek(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+       if (!__mmplayer_gst_seek(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
                                player->playback_rate,
                                GST_FORMAT_TIME,
                                (GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE),
                                GST_SEEK_TYPE_SET, start,
                                GST_SEEK_TYPE_SET, stop)) {
-               LOGE("failed to set speed playback\n");
+               LOGE("failed to set speed playback");
                return MM_ERROR_PLAYER_SEEK;
        }
 
-       LOGD("succeeded to set speed playback as %0.1f\n", rate);
+       LOGD("succeeded to set speed playback as %0.1f", rate);
 
        MMPLAYER_FLEAVE();
 
@@ -9521,9 +5711,9 @@ _mmplayer_set_playspeed(MMHandleType hplayer, float rate, bool streaming)
 }
 
 int
-_mmplayer_set_position(MMHandleType hplayer, int format, int position)
+_mmplayer_set_position(MMHandleType hplayer, gint64 position)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        int ret = MM_ERROR_NONE;
 
        MMPLAYER_FENTER();
@@ -9533,7 +5723,7 @@ _mmplayer_set_position(MMHandleType hplayer, int format, int position)
        /* check pipline building state */
        __mmplayer_check_pipeline(player);
 
-       ret = __gst_set_position(player, format, (unsigned long)position, FALSE);
+       ret = __mmplayer_gst_set_position(player, position, FALSE);
 
        MMPLAYER_FLEAVE();
 
@@ -9541,58 +5731,58 @@ _mmplayer_set_position(MMHandleType hplayer, int format, int position)
 }
 
 int
-_mmplayer_get_position(MMHandleType hplayer, int format, unsigned long *position)
+_mmplayer_get_position(MMHandleType hplayer, gint64 *position)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        int ret = MM_ERROR_NONE;
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       ret = __gst_get_position(player, format, position);
+       ret = __mmplayer_gst_get_position(player, position);
 
        return ret;
 }
 
 int
-_mmplayer_get_buffer_position(MMHandleType hplayer, int format, unsigned long* start_pos, unsigned long* stop_pos)
+_mmplayer_get_duration(MMHandleType hplayer, gint64 *duration)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        int ret = MM_ERROR_NONE;
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(duration, MM_ERROR_COMMON_INVALID_ARGUMENT);
 
-       ret = __gst_get_buffer_position(player, format, start_pos, stop_pos);
+       if (g_strrstr(player->type, "video/mpegts"))
+               __mmplayer_update_duration_value(player);
 
+       *duration = player->duration;
        return ret;
 }
 
 int
-_mmplayer_adjust_subtitle_postion(MMHandleType hplayer, int format, int position)
+_mmplayer_get_buffer_position(MMHandleType hplayer, int *start_pos, int *end_pos)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        int ret = MM_ERROR_NONE;
 
-       MMPLAYER_FENTER();
-
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       ret = __gst_adjust_subtitle_position(player, format, position);
-
-       MMPLAYER_FLEAVE();
+       ret = __mmplayer_gst_get_buffer_position(player, start_pos, end_pos);
 
        return ret;
 }
+
 int
-_mmplayer_adjust_video_postion(MMHandleType hplayer, int offset)
+_mmplayer_adjust_subtitle_postion(MMHandleType hplayer, int position)
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        int ret = MM_ERROR_NONE;
 
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       ret = __gst_adjust_video_position(player, offset);
+       ret = __mmplayer_gst_adjust_subtitle_position(player, position);
 
        MMPLAYER_FLEAVE();
 
@@ -9600,7 +5790,7 @@ _mmplayer_adjust_video_postion(MMHandleType hplayer, int offset)
 }
 
 static gboolean
-__mmplayer_is_midi_type(gcharstr_caps)
+__mmplayer_is_midi_type(gchar *str_caps)
 {
        if ((g_strrstr(str_caps, "audio/midi")) ||
                (g_strrstr(str_caps, "application/x-gst_ff-mmf")) ||
@@ -9609,7 +5799,7 @@ __mmplayer_is_midi_type(gchar* str_caps)
                (g_strrstr(str_caps, "audio/mobile-xmf")) ||
                (g_strrstr(str_caps, "audio/xmf")) ||
                (g_strrstr(str_caps, "audio/mxmf"))) {
-               LOGD("midi\n");
+               LOGD("midi");
                return TRUE;
        }
 
@@ -9620,15 +5810,15 @@ static gboolean
 __mmplayer_is_only_mp3_type(gchar *str_caps)
 {
        if (g_strrstr(str_caps, "application/x-id3") ||
-               (g_strrstr(str_caps, "audio/mpeg") && g_strrstr(str_caps, "mpegversion= (int)1")))
+               (g_strrstr(str_caps, "audio/mpeg") && g_strrstr(str_caps, "mpegversion=(int)1")))
                return TRUE;
        return FALSE;
 }
 
 static void
-__mmplayer_set_audio_attrs(mm_player_t* player, GstCaps* caps)
+__mmplayer_set_audio_attrs(mmplayer_t *player, GstCaps *caps)
 {
-       GstStructurecaps_structure = NULL;
+       GstStructure *caps_structure = NULL;
        gint samplerate = 0;
        gint channels = 0;
 
@@ -9644,40 +5834,58 @@ __mmplayer_set_audio_attrs(mm_player_t* player, GstCaps* caps)
        gst_structure_get_int(caps_structure, "channels", &channels);
        mm_attrs_set_int_by_name(player->attrs, "content_audio_channels", channels);
 
-       LOGD("audio samplerate : %d     channels : %d\n", samplerate, channels);
+       LOGD("audio samplerate : %d     channels : %d", samplerate, channels);
 }
 
 static void
-__mmplayer_update_content_type_info(mm_player_t* player)
+__mmplayer_update_content_type_info(mmplayer_t *player)
 {
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player && player->type);
 
        if (__mmplayer_is_midi_type(player->type)) {
                player->bypass_audio_effect = TRUE;
-       } else if (g_strrstr(player->type, "application/x-hls")) {
+               return;
+       }
+
+       if (!player->streamer) {
+               LOGD("no need to check streaming type");
+               return;
+       }
+
+       if (g_strrstr(player->type, "application/x-hls")) {
                /* If it can't know exact type when it parses uri because of redirection case,
                 * it will be fixed by typefinder or when doing autoplugging.
                 */
                player->profile.uri_type = MM_PLAYER_URI_TYPE_HLS;
-               if (player->streamer) {
-                       player->streamer->is_adaptive_streaming = TRUE;
-                       player->streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_FIXED;
-                       player->streamer->buffering_req.rebuffer_time = 5 * 1000;
-               }
+               player->streamer->is_adaptive_streaming = TRUE;
        } else if (g_strrstr(player->type, "application/dash+xml")) {
                player->profile.uri_type = MM_PLAYER_URI_TYPE_DASH;
+               player->streamer->is_adaptive_streaming = TRUE;
        }
 
+       /* in case of TS, fixed buffering mode should be used because player can not get exact duration time */
+       if ((player->streamer->is_adaptive_streaming) || (g_strrstr(player->type, "video/mpegts"))) {
+               player->streamer->buffering_req.mode = MM_PLAYER_BUFFERING_MODE_FIXED;
+
+               if (player->streamer->buffering_req.rebuffer_time <= MIN_BUFFERING_TIME) { /* if user did not set the rebuffer value */
+                       if (player->streamer->is_adaptive_streaming)
+                               player->streamer->buffering_req.rebuffer_time = DEFAULT_ADAPTIVE_REBUFFER_TIME;
+                       else
+                               player->streamer->buffering_req.rebuffer_time = DEFAULT_REBUFFERING_TIME;
+               }
+       }
+
+       LOGD("uri type : %d, %d", player->profile.uri_type, player->streamer->buffering_req.rebuffer_time);
        MMPLAYER_FLEAVE();
 }
 
-static void
+void
 __mmplayer_typefind_have_type(GstElement *tf, guint probability,
-GstCaps *caps, gpointer data)
+       GstCaps *caps, gpointer data)
 {
-       mm_player_t* player = (mm_player_t*)data;
-       GstPadpad = NULL;
+       mmplayer_t *player = (mmplayer_t *)data;
+       GstPad *pad = NULL;
 
        MMPLAYER_FENTER();
 
@@ -9686,14 +5894,13 @@ GstCaps *caps, gpointer data)
        /* store type string */
        MMPLAYER_FREEIF(player->type);
        player->type = gst_caps_to_string(caps);
-       if (player->type) {
-               LOGD("[handle: %p] media type %s found, probability %d%% / %d\n",
+       if (player->type)
+               LOGD("[handle: %p] media type %s found, probability %d%% / %d",
                                player, player->type, probability, gst_caps_get_size(caps));
-       }
 
        if ((!MMPLAYER_IS_RTSP_STREAMING(player)) &&
                (g_strrstr(player->type, "audio/x-raw-int"))) {
-               LOGE("not support media format\n");
+               LOGE("not support media format");
 
                if (player->msg_posted == FALSE) {
                        MMMessageParamType msg_param;
@@ -9712,23 +5919,21 @@ GstCaps *caps, gpointer data)
 
        pad = gst_element_get_static_pad(tf, "src");
        if (!pad) {
-               LOGE("fail to get typefind src pad.\n");
+               LOGE("fail to get typefind src pad.");
                return;
        }
 
-       if (!__mmplayer_try_to_plug_decodebin(player, pad, caps)) {
+       if (!__mmplayer_gst_create_decoder(player, pad, caps)) {
                gboolean async = FALSE;
-               LOGE("failed to autoplug %s\n", player->type);
+               LOGE("failed to autoplug %s", player->type);
 
                mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
 
                if (async && player->msg_posted == FALSE)
                        __mmplayer_handle_missed_plugin(player);
 
-               goto DONE;
        }
 
-DONE:
        gst_object_unref(GST_OBJECT(pad));
 
        MMPLAYER_FLEAVE();
@@ -9736,8 +5941,8 @@ DONE:
        return;
 }
 
-static GstElement *
-__mmplayer_create_decodebin(mm_player_t* player)
+GstElement *
+__mmplayer_gst_make_decodebin(mmplayer_t *player)
 {
        GstElement *decodebin = NULL;
 
@@ -9747,153 +5952,155 @@ __mmplayer_create_decodebin(mm_player_t* player)
        decodebin = gst_element_factory_make("decodebin", NULL);
 
        if (!decodebin) {
-               LOGE("fail to create decodebin\n");
+               LOGE("fail to create decodebin");
                goto ERROR;
        }
 
        /* raw pad handling signal */
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
-                                               G_CALLBACK(__mmplayer_gst_decode_pad_added), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-added",
+                                               G_CALLBACK(__mmplayer_gst_decode_pad_added), (gpointer)player);
 
        /* no-more-pad pad handling signal */
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
-                                               G_CALLBACK(__mmplayer_gst_decode_no_more_pads), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "no-more-pads",
+                                               G_CALLBACK(__mmplayer_gst_decode_no_more_pads), (gpointer)player);
 
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-removed",
-                                               G_CALLBACK(__mmplayer_gst_decode_pad_removed), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "pad-removed",
+                                               G_CALLBACK(__mmplayer_gst_decode_pad_removed), (gpointer)player);
 
        /* This signal is emitted when a pad for which there is no further possible
           decoding is added to the decodebin.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "unknown-type",
-                                               G_CALLBACK(__mmplayer_gst_decode_unknown_type), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "unknown-type",
+                                               G_CALLBACK(__mmplayer_gst_decode_unknown_type), (gpointer)player);
 
        /* This signal is emitted whenever decodebin finds a new stream. It is emitted
           before looking for any elements that can handle that stream.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue",
-                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_continue), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-continue",
+                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_continue), (gpointer)player);
 
        /* This signal is emitted whenever decodebin finds a new stream. It is emitted
           before looking for any elements that can handle that stream.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select",
-                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_select), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "autoplug-select",
+                                               G_CALLBACK(__mmplayer_gst_decode_autoplug_select), (gpointer)player);
 
        /* This signal is emitted once decodebin has finished decoding all the data.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "drained",
-                                               G_CALLBACK(__mmplayer_gst_decode_drained), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "drained",
+                                               G_CALLBACK(__mmplayer_gst_decode_drained), (gpointer)player);
 
        /* This signal is emitted when a element is added to the bin.*/
-       MMPLAYER_SIGNAL_CONNECT(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added",
-                                               G_CALLBACK(__mmplayer_gst_element_added), player);
+       __mmplayer_add_signal_connection(player, G_OBJECT(decodebin), MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "element-added",
+                                               G_CALLBACK(__mmplayer_gst_element_added), (gpointer)player);
 
 ERROR:
        return decodebin;
 }
 
-static gboolean
-__mmplayer_try_to_plug_decodebin(mm_player_t* player, GstPad *srcpad, const GstCaps *caps)
+static GstElement *
+__mmplayer_gst_make_queue2(mmplayer_t *player)
 {
-       MMPlayerGstElement* mainbin = NULL;
-       GstElement* decodebin = NULL;
-       GstElement* queue2 = NULL;
-       GstPad* sinkpad = NULL;
-       GstPad* qsrcpad = NULL;
+       GstElement *queue2 = NULL;
        gint64 dur_bytes = 0L;
-
-       guint max_buffer_size_bytes = 0;
-       gint init_buffering_time = player->streamer->buffering_req.prebuffer_time;
+       mmplayer_gst_element_t *mainbin = NULL;
+       muxed_buffer_type_e type = MUXED_BUFFER_TYPE_MEM_QUEUE;
 
        MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, FALSE);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, NULL);
 
        mainbin = player->pipeline->mainbin;
 
-       if ((!MMPLAYER_IS_HTTP_PD(player)) &&
-               (MMPLAYER_IS_HTTP_STREAMING(player))) {
-               LOGD("creating http streaming buffering queue(queue2)\n");
+       queue2 = gst_element_factory_make("queue2", "queue2");
+       if (!queue2) {
+               LOGE("failed to create buffering queue element");
+               return NULL;
+       }
 
-               if (mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst) {
-                       LOGE("MMPLAYER_M_MUXED_S_BUFFER is not null\n");
-               } else {
-                       queue2 = gst_element_factory_make("queue2", "queue2");
-                       if (!queue2) {
-                               LOGE("failed to create buffering queue element\n");
-                               goto ERROR;
-                       }
+       if (!gst_element_query_duration(mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
+               LOGW("failed to get duration from source %s", GST_ELEMENT_NAME(mainbin[MMPLAYER_M_SRC].gst));
 
-                       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue2)) {
-                               LOGE("failed to add buffering queue\n");
-                               goto ERROR;
-                       }
+       LOGD("dur_bytes = %"G_GINT64_FORMAT, dur_bytes);
 
-                       sinkpad = gst_element_get_static_pad(queue2, "sink");
-                       qsrcpad = gst_element_get_static_pad(queue2, "src");
+       /* NOTE : in case of ts streaming, player could not get the correct duration info *
+        *                skip the pull mode(file or ring buffering) setting. */
+       if (dur_bytes > 0) {
+               if (!g_strrstr(player->type, "video/mpegts")) {
+                       type = MUXED_BUFFER_TYPE_MEM_RING_BUFFER;
+                       player->streamer->ring_buffer_size = player->ini.http_ring_buffer_size;
+               }
+       } else {
+               dur_bytes = 0;
+       }
 
-                       if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) {
-                               LOGE("failed to link buffering queue\n");
-                               goto ERROR;
-                       }
+       __mm_player_streaming_set_queue2(player->streamer,
+                                                                       queue2,
+                                                                       FALSE,
+                                                                       type,
+                                                                       (guint64)dur_bytes); /* no meaning at the moment */
 
-                       if (!gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
-                               LOGE("fail to get duration.\n");
+       return queue2;
+}
 
-                       LOGD("dur_bytes = %lld\n", dur_bytes);
+gboolean
+__mmplayer_gst_create_decoder(mmplayer_t *player, GstPad *srcpad, const GstCaps *caps)
+{
+       mmplayer_gst_element_t *mainbin = NULL;
+       GstElement *decodebin = NULL;
+       GstElement *queue2 = NULL;
+       GstPad *sinkpad = NULL;
+       GstPad *qsrcpad = NULL;
 
-                       muxed_buffer_type_e type = MUXED_BUFFER_TYPE_MEM_QUEUE;
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin, FALSE);
 
-                       if (dur_bytes > 0) {
-                               if (MMPLAYER_USE_FILE_FOR_BUFFERING(player)) {
-                                       type = MUXED_BUFFER_TYPE_FILE;
-                               } else {
-                                       type = MUXED_BUFFER_TYPE_MEM_RING_BUFFER;
-                                       player->streamer->ring_buffer_size = player->ini.http_ring_buffer_size;
-                               }
-                       } else {
-                               dur_bytes = 0;
-                       }
+       mainbin = player->pipeline->mainbin;
 
-                       /* NOTE : we cannot get any duration info from ts container in case of streaming */
-                       // if (!g_strrstr(GST_ELEMENT_NAME(sinkelement), "mpegtsdemux"))
-                       if (!g_strrstr(player->type, "video/mpegts")) {
-                               max_buffer_size_bytes = (type == MUXED_BUFFER_TYPE_FILE) ? (player->ini.http_max_size_bytes) : (5*1024*1024);
-                               LOGD("max_buffer_size_bytes = %d\n", max_buffer_size_bytes);
-
-                               // FIXME : pass ini setting directly. is this ok?
-                               __mm_player_streaming_set_queue2(player->streamer,
-                                                                                               queue2,
-                                                                                               FALSE,
-                                                                                               max_buffer_size_bytes,
-                                                                                               player->ini.http_buffering_time,
-                                                                                               1.0,                                                            // no meaning
-                                                                                               player->ini.http_buffering_limit,       // no meaning
-                                                                                               type,
-                                                                                               player->http_file_buffering_path,
-                                                                                               (guint64)dur_bytes);
-                       }
+       if (MMPLAYER_IS_HTTP_STREAMING(player)) {
 
-                       if (GST_STATE_CHANGE_FAILURE == gst_element_sync_state_with_parent(queue2)) {
-                               LOGE("failed to sync queue2 state with parent\n");
-                               goto ERROR;
-                       }
+               if (mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst) {
+                       LOGW("need to check: muxed buffer is not null");
+               }
+
+               queue2 = __mmplayer_gst_make_queue2(player);
+               if (!queue2) {
+                       LOGE("failed to make queue2");
+                       goto ERROR;
+               }
+
+               if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue2)) {
+                       LOGE("failed to add buffering queue");
+                       goto ERROR;
+               }
 
-                       srcpad = qsrcpad;
+               sinkpad = gst_element_get_static_pad(queue2, "sink");
+               qsrcpad = gst_element_get_static_pad(queue2, "src");
 
-                       gst_object_unref(GST_OBJECT(sinkpad));
+               if (gst_pad_link(srcpad, sinkpad) != GST_PAD_LINK_OK) {
+                       LOGE("failed to link [%s:%s]-[%s:%s]",
+                                               GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
+                       goto ERROR;
+               }
 
-                       mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER;
-                       mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = queue2;
+               if (gst_element_sync_state_with_parent(queue2) == GST_STATE_CHANGE_FAILURE) {
+                       LOGE("failed to sync queue2 state with parent");
+                       goto ERROR;
                }
+
+               mainbin[MMPLAYER_M_MUXED_S_BUFFER].id = MMPLAYER_M_MUXED_S_BUFFER;
+               mainbin[MMPLAYER_M_MUXED_S_BUFFER].gst = queue2;
+
+               srcpad = qsrcpad;
+
+               gst_object_unref(GST_OBJECT(sinkpad));
+               sinkpad = NULL;
        }
 
        /* create decodebin */
-       decodebin = __mmplayer_create_decodebin(player);
-
+       decodebin = __mmplayer_gst_make_decodebin(player);
        if (!decodebin) {
-               LOGE("can not create autoplug element\n");
+               LOGE("failed to make decodebin");
                goto ERROR;
        }
 
        if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), decodebin)) {
-               LOGE("failed to add decodebin\n");
+               LOGE("failed to add decodebin");
                goto ERROR;
        }
 
@@ -9905,39 +6112,42 @@ __mmplayer_try_to_plug_decodebin(mm_player_t* player, GstPad *srcpad, const GstC
        sinkpad = gst_element_get_static_pad(decodebin, "sink");
 
        if (GST_PAD_LINK_OK != gst_pad_link(srcpad, sinkpad)) {
-               LOGE("failed to link decodebin\n");
+               LOGE("failed to link [%s:%s]-[%s:%s]",
+                               GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
                goto ERROR;
        }
 
        gst_object_unref(GST_OBJECT(sinkpad));
+       sinkpad = NULL;
+       gst_object_unref(GST_OBJECT(qsrcpad));
+       qsrcpad = NULL;
 
        mainbin[MMPLAYER_M_AUTOPLUG].id = MMPLAYER_M_AUTOPLUG;
        mainbin[MMPLAYER_M_AUTOPLUG].gst = decodebin;
 
        /* set decodebin property about buffer in streaming playback. *
-        * in case of HLS/DASH, it does not need to have big buffer        *
+        * in case of HLS/DASH, it does not need to have big buffer   *
         * because it is kind of adaptive streaming.                  */
-       if (!MMPLAYER_IS_HTTP_PD(player) && MMPLAYER_IS_HTTP_STREAMING(player)) {
-               guint max_size_bytes = MAX_DECODEBIN_BUFFER_BYTES;
-               guint64 max_size_time = MAX_DECODEBIN_BUFFER_TIME;
-               init_buffering_time = (init_buffering_time != 0) ? (init_buffering_time) : (player->ini.http_buffering_time);
+       if (MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_HTTP_LIVE_STREAMING(player) || MMPLAYER_IS_DASH_STREAMING(player)) {
+               gint init_buffering_time = DEFAULT_PREBUFFERING_TIME;
+               gint high_percent = 0;
 
-               if (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)
-                       || MMPLAYER_IS_DASH_STREAMING(player)) {
-                       max_size_bytes = MAX_DECODEBIN_ADAPTIVE_BUFFER_BYTES;
-                       max_size_time = MAX_DECODEBIN_ADAPTIVE_BUFFER_TIME;
-               }
+               if (player->streamer->buffering_req.prebuffer_time > MIN_BUFFERING_TIME)
+                       init_buffering_time = player->streamer->buffering_req.prebuffer_time;
+
+               high_percent = (gint)ceil((gdouble)(init_buffering_time * 100) / MAX_BUFFER_SIZE_TIME);
+
+               LOGD("buffering time %d, per: 1~%d", init_buffering_time, high_percent);
 
                g_object_set(G_OBJECT(decodebin), "use-buffering", TRUE,
-                                                                                       "high-percent", (gint)player->ini.http_buffering_limit,
-                                                                                       "low-percent", 1,   // 1%
-                                                                                       "max-size-bytes", max_size_bytes,
-                                                                                       "max-size-time", (guint64)(max_size_time * GST_SECOND),
+                                                                                       "high-percent", high_percent,
+                                                                                       "max-size-bytes", MAX_BUFFER_SIZE_BYTES,
+                                                                                       "max-size-time", (guint64)(MAX_BUFFER_SIZE_TIME * GST_MSECOND),
                                                                                        "max-size-buffers", 0, NULL);  // disable or automatic
        }
 
-       if (GST_STATE_CHANGE_FAILURE == gst_element_sync_state_with_parent(decodebin)) {
-               LOGE("failed to sync decodebin state with parent\n");
+       if (gst_element_sync_state_with_parent(decodebin) == GST_STATE_CHANGE_FAILURE) {
+               LOGE("failed to sync decodebin state with parent");
                goto ERROR;
        }
 
@@ -9950,6 +6160,9 @@ ERROR:
        if (sinkpad)
                gst_object_unref(GST_OBJECT(sinkpad));
 
+       if (qsrcpad)
+               gst_object_unref(GST_OBJECT(qsrcpad));
+
        if (queue2) {
                /* NOTE : Trying to dispose element queue0, but it is in READY instead of the NULL state.
                 * You need to explicitly set elements to the NULL state before
@@ -9985,14 +6198,14 @@ ERROR:
 }
 
 static int
-__mmplayer_check_not_supported_codec(mm_player_t* player, const gchar* factory_class, const gchar* mime)
+__mmplayer_check_not_supported_codec(mmplayer_t *player, const gchar *factory_class, const gchar *mime)
 {
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
        MMPLAYER_RETURN_VAL_IF_FAIL(mime, MM_ERROR_INVALID_ARGUMENT);
 
-       LOGD("class : %s, mime : %s \n", factory_class, mime);
+       LOGD("class : %s, mime : %s", factory_class, mime);
 
        /* add missing plugin */
        /* NOTE : msl should check missing plugin for image mime type.
@@ -10001,7 +6214,7 @@ __mmplayer_check_not_supported_codec(mm_player_t* player, const gchar* factory_c
         */
        if (!(player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst)) {
                if (!(player->can_support_codec | player->videodec_linked | player->audiodec_linked)) {
-                       LOGD("not found demuxer\n");
+                       LOGD("not found demuxer");
                        player->not_found_demuxer = TRUE;
                        player->unlinked_demuxer_mime = g_strdup_printf("%s", mime);
 
@@ -10011,22 +6224,22 @@ __mmplayer_check_not_supported_codec(mm_player_t* player, const gchar* factory_c
 
        if (!g_strrstr(factory_class, "Demuxer")) {
                if ((g_str_has_prefix(mime, "video")) || (g_str_has_prefix(mime, "image"))) {
-                       LOGD("can support codec=0x%X, vdec_linked=%d, adec_linked=%d\n",
+                       LOGD("can support codec=0x%X, vdec_linked=%d, adec_linked=%d",
                                player->can_support_codec, player->videodec_linked, player->audiodec_linked);
 
                        /* check that clip have multi tracks or not */
                        if ((player->can_support_codec & FOUND_PLUGIN_VIDEO) && (player->videodec_linked)) {
-                               LOGD("video plugin is already linked\n");
+                               LOGD("video plugin is already linked");
                        } else {
-                               LOGW("add VIDEO to missing plugin\n");
+                               LOGW("add VIDEO to missing plugin");
                                player->not_supported_codec |= MISSING_PLUGIN_VIDEO;
                                player->unlinked_video_mime = g_strdup_printf("%s", mime);
                        }
                } else if (g_str_has_prefix(mime, "audio")) {
                        if ((player->can_support_codec & FOUND_PLUGIN_AUDIO) && (player->audiodec_linked)) {
-                               LOGD("audio plugin is already linked\n");
+                               LOGD("audio plugin is already linked");
                        } else {
-                               LOGW("add AUDIO to missing plugin\n");
+                               LOGW("add AUDIO to missing plugin");
                                player->not_supported_codec |= MISSING_PLUGIN_AUDIO;
                                player->unlinked_audio_mime = g_strdup_printf("%s", mime);
                        }
@@ -10039,211 +6252,197 @@ DONE:
        return MM_ERROR_NONE;
 }
 
-
 static void
 __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data)
 {
-       mm_player_t* player = (mm_player_t*)data;
+       mmplayer_t *player = (mmplayer_t *)data;
 
        MMPLAYER_FENTER();
 
-       MMPLAYER_RETURN_IF_FAIL(player);
+       MMPLAYER_RETURN_IF_FAIL(player);
+
+       /* 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
+                * signaling mechanism(pad-added, no-more-pad, new-decoded-pad) from various
+                * source element are not same. To overcome this situation, this function will called
+                * several places and several times. Therefore, this is not an error case.
+                */
+               return;
+       }
+
+       LOGD("[handle: %p] pipeline has completely constructed", player);
+
+       if ((player->ini.async_start) &&
+               (player->msg_posted == FALSE) &&
+               (player->cmd >= MMPLAYER_COMMAND_START))
+               __mmplayer_handle_missed_plugin(player);
+
+       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-complete");
+}
+
+static int
+__mmplayer_check_profile(void)
+{
+       char *profileName;
+       static int profile_tv = -1;
+
+       if (__builtin_expect(profile_tv != -1, 1))
+               return profile_tv;
+
+       system_info_get_platform_string("http://tizen.org/feature/profile", &profileName);
+       switch (*profileName) {
+       case 't':
+       case 'T':
+               profile_tv = 1;
+               break;
+       default:
+               profile_tv = 0;
+               break;
+       }
+       free(profileName);
+
+       return profile_tv;
+}
+
+static gboolean
+__mmplayer_get_next_uri(mmplayer_t *player)
+{
+       mmplayer_parse_profile_t profile;
+       gint uri_idx = 0;
+       guint num_of_list = 0;
+       char *uri = NULL;
+
+       num_of_list = g_list_length(player->uri_info.uri_list);
+       uri_idx = player->uri_info.uri_idx;
+
+       LOGD("num of uri list = %d, current uri idx %d", num_of_list, uri_idx);
+       for (uri_idx++; uri_idx < num_of_list; uri_idx++) {
+               uri = g_list_nth_data(player->uri_info.uri_list, uri_idx);
+               if (!uri) {
+                       LOGW("next uri does not exist");
+                       continue;
+               }
+
+               if (__mmplayer_parse_profile((const char *)uri, NULL, &profile) != MM_ERROR_NONE) {
+                       LOGE("failed to parse profile");
+                       continue;
+               }
+
+               if ((profile.uri_type != MM_PLAYER_URI_TYPE_FILE) &&
+                       (profile.uri_type != MM_PLAYER_URI_TYPE_URL_HTTP)) {
+                       LOGW("uri type is not supported(%d)", profile.uri_type);
+                       continue;
+               }
+
+               LOGD("success to find next uri %d", uri_idx);
+               break;
+       }
 
-       /* 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
-                * signaling mechanism(pad-added, no-more-pad, new-decoded-pad) from various
-                * source element are not same. To overcome this situation, this function will called
-                * several places and several times. Therefore, this is not an error case.
-                */
-               return;
+       if (uri_idx == num_of_list) {
+               LOGE("failed to find next uri");
+               return FALSE;
        }
 
-       LOGD("[handle: %p] pipeline has completely constructed", player);
+       player->uri_info.uri_idx = uri_idx;
+       mm_attrs_set_string_by_name(player->attrs, "profile_uri", uri);
 
-       if ((player->ini.async_start) &&
-               (player->msg_posted == FALSE) &&
-               (player->cmd >= MMPLAYER_COMMAND_START))
-               __mmplayer_handle_missed_plugin(player);
+       if (mm_attrs_commit_all(player->attrs)) {
+               LOGE("failed to commit");
+               return FALSE;
+       }
 
-       MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-complete");
+       SECURE_LOGD("next playback uri: %s", uri);
+       return TRUE;
 }
 
 static gboolean
-__mmplayer_verify_next_play_path(mm_player_t *player)
+__mmplayer_verify_gapless_play_path(mmplayer_t *player)
 {
+#define REPEAT_COUNT_INFINITELY -1
+#define REPEAT_COUNT_MIN 2
+
        MMHandleType attrs = 0;
-       MMPlayerParseProfile profile;
-       gint uri_idx = 0, check_cnt = 0;
-       char *uri = NULL;
-       gint mode = MM_PLAYER_PD_MODE_NONE;
        gint video = 0;
        gint count = 0;
        gint gapless = 0;
        guint num_of_list = 0;
-       static int profile_tv = -1;
+       int profile_tv = -1;
 
        MMPLAYER_FENTER();
 
-       LOGD("checking for gapless play");
+       LOGD("checking for gapless play option");
 
        if (player->pipeline->textbin) {
-               LOGE("subtitle path is enabled. gapless play is not supported.\n");
+               LOGE("subtitle path is enabled. gapless play is not supported.");
                goto ERROR;
        }
 
        attrs = MMPLAYER_GET_ATTRS(player);
        if (!attrs) {
-               LOGE("fail to get attributes.\n");
+               LOGE("fail to get attributes.");
                goto ERROR;
        }
 
        mm_attrs_get_int_by_name(attrs, "content_video_found", &video);
 
-       if (__builtin_expect(profile_tv == -1, 0)) {
-               char *profileName;
-               system_info_get_platform_string("http://tizen.org/feature/profile", &profileName);
-               switch (*profileName) {
-               case 't':
-               case 'T':
-                       profile_tv = 1;
-                       break;
-               default:
-                       profile_tv = 0;
-               }
-               free(profileName);
-       }
        /* gapless playback is not supported in case of video at TV profile. */
+       profile_tv = __mmplayer_check_profile();
        if (profile_tv && video) {
                LOGW("not support video gapless playback");
                goto ERROR;
        }
 
-       if (mm_attrs_get_int_by_name(attrs, "pd_mode", &mode) == MM_ERROR_NONE) {
-               if (mode == TRUE) {
-                       LOGW("pd mode\n");
-                       goto ERROR;
-               }
-       }
-
        if (mm_attrs_get_int_by_name(attrs, "profile_play_count", &count) != MM_ERROR_NONE)
-               LOGE("can not get play count\n");
+               LOGE("failed to get play count");
 
        if (mm_attrs_get_int_by_name(attrs, "gapless_mode", &gapless) != MM_ERROR_NONE)
-               LOGE("can not get gapless mode\n");
+               LOGE("failed to get gapless mode");
 
-       if (video && !gapless) {
-               LOGW("not enabled video gapless playback");
-               goto ERROR;
-       }
-
-       if ((count == -1 || count > 1)) /* enable gapless when looping or repeat */
-               gapless = 1;
-
-       if (!gapless) {
-               LOGW("gapless is disabled\n");  /* FIXME: playlist(without gapless) is not implemented. */
+       /* check repeat count in case of audio */
+       if (!gapless &&
+               (video || (count != REPEAT_COUNT_INFINITELY && count < REPEAT_COUNT_MIN))) {
+               LOGW("gapless is disabled");
                goto ERROR;
        }
 
        num_of_list = g_list_length(player->uri_info.uri_list);
 
-       LOGD("repeat count = %d, num_of_list = %d\n", count, num_of_list);
+       LOGD("repeat count = %d, num_of_list = %d", count, num_of_list);
 
        if (num_of_list == 0) {
-               if (mm_attrs_get_string_by_name(player->attrs, "profile_uri", &uri) != MM_ERROR_NONE) {
-                       LOGE("can not get profile_uri\n");
-                       goto ERROR;
-               }
-
-               if (!uri) {
-                       LOGE("uri list is empty.\n");
+               /* audio looping path */
+               if (count >= REPEAT_COUNT_MIN) {
+                       /* decrease play count */
+                       /* we succeeded to rewind. update play count and then wait for next EOS */
+                       count--;
+                       mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
+                       /* commit attribute */
+                       if (mm_attrs_commit_all(attrs))
+                               LOGE("failed to commit attribute");
+
+               } else if (count != REPEAT_COUNT_INFINITELY) {
+                       LOGD("there is no next uri and no repeat");
                        goto ERROR;
                }
-
-               player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(uri));
-               LOGD("add original path : %s ", uri);
-
-               num_of_list = 1;
-               uri = NULL;
-       }
-
-       uri_idx = player->uri_info.uri_idx;
-
-       while (TRUE) {
-               check_cnt++;
-
-               if (check_cnt > num_of_list) {
-                       LOGE("there is no valid uri.");
+               LOGD("looping cnt %d", count);
+       } else {
+               /* gapless playback path */
+               if (!__mmplayer_get_next_uri(player)) {
+                       LOGE("failed to get next uri");
                        goto ERROR;
                }
-
-               LOGD("uri idx : %d / %d\n", uri_idx, num_of_list);
-
-               if (uri_idx < num_of_list-1) {
-                       uri_idx++;
-               } else {
-                       if ((count <= 1) && (count != -1)) {
-                               LOGD("no repeat.");
-                               goto ERROR;
-                       } else if (count > 1) {
-                               /* 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 (mmf_attrs_commit(attrs))
-                                       LOGE("failed to commit attribute\n");
-                       }
-
-                       /* count < 0 : repeat continually */
-                       uri_idx = 0;
-               }
-
-               uri = g_list_nth_data(player->uri_info.uri_list, uri_idx);
-               LOGD("uri idx : %d, uri = %s\n", uri_idx, uri);
-
-               if (uri == NULL) {
-                       LOGW("next uri does not exist\n");
-                       continue;
-               }
-
-               if (__mmfplayer_parse_profile((const char*)uri, NULL, &profile) != MM_ERROR_NONE) {
-                       LOGE("failed to parse profile\n");
-                       continue;
-               }
-
-               if ((profile.uri_type != MM_PLAYER_URI_TYPE_FILE) &&
-                       (profile.uri_type != MM_PLAYER_URI_TYPE_URL_HTTP)) {
-                       LOGW("uri type is not supported(%d).", profile.uri_type);
-                       continue;
-               }
-
-               break;
-       }
-
-       player->uri_info.uri_idx = uri_idx;
-       mm_attrs_set_string_by_name(player->attrs, "profile_uri", uri);
-
-       if (mmf_attrs_commit(player->attrs)) {
-               LOGE("failed to commit.\n");
-               goto ERROR;
        }
-
-       LOGD("next uri %s(%d)\n", uri, uri_idx);
-
        return TRUE;
 
 ERROR:
-
-       LOGE("unable to play next path. EOS will be posted soon.\n");
+       LOGE("unable to play gapless path. EOS will be posted soon");
        return FALSE;
 }
 
 static void
-__mmplayer_initialize_next_play(mm_player_t *player)
+__mmplayer_initialize_gapless_play(mmplayer_t *player)
 {
        int i;
 
@@ -10252,22 +6451,18 @@ __mmplayer_initialize_next_play(mm_player_t *player)
        player->smooth_streaming = FALSE;
        player->videodec_linked = 0;
        player->audiodec_linked = 0;
-       player->videosink_linked = 0;
-       player->audiosink_linked = 0;
        player->textsink_linked = 0;
        player->is_external_subtitle_present = FALSE;
        player->is_external_subtitle_added_now = FALSE;
        player->not_supported_codec = MISSING_PLUGIN_NONE;
        player->can_support_codec = FOUND_PLUGIN_NONE;
-       player->pending_seek.is_pending = FALSE;
-       player->pending_seek.format = MM_PLAYER_POS_FORMAT_TIME;
+       player->pending_seek.is_pending = false;
        player->pending_seek.pos = 0;
        player->msg_posted = FALSE;
        player->has_many_types = FALSE;
        player->no_more_pad = FALSE;
        player->not_found_demuxer = 0;
-       player->doing_seek = FALSE;
-       player->max_audio_channels = 0;
+       player->seek_state = MMPLAYER_SEEK_NONE;
        player->is_subtitle_force_drop = FALSE;
        player->play_subtitle = FALSE;
        player->adjust_subtitle_pos = 0;
@@ -10275,7 +6470,7 @@ __mmplayer_initialize_next_play(mm_player_t *player)
        player->total_bitrate = 0;
        player->total_maximum_bitrate = 0;
 
-       _mmplayer_track_initialize(player);
+       __mmplayer_track_initialize(player);
        __mmplayer_initialize_storage_info(player, MMPLAYER_PATH_MAX);
 
        for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++) {
@@ -10290,17 +6485,6 @@ __mmplayer_initialize_next_play(mm_player_t *player)
 
        mm_attrs_set_int_by_name(player->attrs, "content_video_found", 0);
 
-       /* clean found parsers */
-       if (player->parsers) {
-               GList *parsers = player->parsers;
-               for (; parsers; parsers = g_list_next(parsers)) {
-                       gchar *name = parsers->data;
-                       MMPLAYER_FREEIF(name);
-               }
-               g_list_free(player->parsers);
-               player->parsers = NULL;
-       }
-
        /* clean found audio decoders */
        if (player->audio_decoders) {
                GList *a_dec = player->audio_decoders;
@@ -10316,21 +6500,19 @@ __mmplayer_initialize_next_play(mm_player_t *player)
 }
 
 static void
-__mmplayer_activate_next_source(mm_player_t *player, GstState target)
+__mmplayer_activate_next_source(mmplayer_t *player, GstState target)
 {
-       MMPlayerGstElement *mainbin = NULL;
+       mmplayer_gst_element_t *mainbin = NULL;
        MMMessageParamType msg_param = {0,};
        GstElement *element = NULL;
        MMHandleType attrs = 0;
        char *uri = NULL;
-       enum MainElementID elemId = MMPLAYER_M_NUM;
+       main_element_id_e elem_idx = MMPLAYER_M_NUM;
 
        MMPLAYER_FENTER();
 
-       if ((player == NULL) ||
-               (player->pipeline == NULL) ||
-               (player->pipeline->mainbin == NULL)) {
-               LOGE("player is null.\n");
+       if (!player || !player->pipeline || !player->pipeline->mainbin) {
+               LOGE("player is not initialized");
                goto ERROR;
        }
 
@@ -10339,102 +6521,36 @@ __mmplayer_activate_next_source(mm_player_t *player, GstState target)
 
        attrs = MMPLAYER_GET_ATTRS(player);
        if (!attrs) {
-               LOGE("fail to get attributes.\n");
+               LOGE("fail to get attributes");
                goto ERROR;
        }
 
        /* Initialize Player values */
-       __mmplayer_initialize_next_play(player);
+       __mmplayer_initialize_gapless_play(player);
 
        mm_attrs_get_string_by_name(attrs, "profile_uri", &uri);
 
-       if (__mmfplayer_parse_profile((const char*)uri, NULL, &player->profile) != MM_ERROR_NONE) {
-               LOGE("failed to parse profile\n");
+       if (__mmplayer_parse_profile((const char *)uri, NULL, &player->profile) != MM_ERROR_NONE) {
+               LOGE("failed to parse profile");
                msg_param.code = MM_ERROR_PLAYER_INVALID_URI;
                goto ERROR;
        }
 
        if ((MMPLAYER_URL_HAS_DASH_SUFFIX(player)) ||
                (MMPLAYER_URL_HAS_HLS_SUFFIX(player))) {
-               LOGE("it's dash or hls. not support.");
+               LOGE("dash or hls is not supportable");
                msg_param.code = MM_ERROR_PLAYER_INVALID_URI;
                goto ERROR;
        }
 
-       /* setup source */
-       switch (player->profile.uri_type) {
-       /* file source */
-       case MM_PLAYER_URI_TYPE_FILE:
-       {
-               LOGD("using filesrc for 'file://' handler.\n");
-               if (!util_get_storage_info(player->profile.uri, &player->storage_info[MMPLAYER_PATH_VOD])) {
-                       LOGE("failed to get storage info");
-                       break;
-               }
-
-               element = gst_element_factory_make("filesrc", "source");
-
-               if (!element) {
-                       LOGE("failed to create filesrc\n");
-                       break;
-               }
-
-               g_object_set(G_OBJECT(element), "location", (player->profile.uri)+7, NULL);     /* uri+7 -> remove "file:// */
-               break;
-       }
-       case MM_PLAYER_URI_TYPE_URL_HTTP:
-       {
-               gchar *user_agent, *cookies, **cookie_list;
-               gint http_timeout = DEFAULT_HTTP_TIMEOUT;
-               user_agent = cookies = NULL;
-               cookie_list = NULL;
-
-               element = gst_element_factory_make(player->ini.httpsrc_element, "http_streaming_source");
-               if (!element) {
-                       LOGE("failed to create http streaming source element[%s].\n", player->ini.httpsrc_element);
-                       break;
-               }
-               LOGD("using http streamming source [%s].\n", player->ini.httpsrc_element);
-
-               /* get attribute */
-               mm_attrs_get_string_by_name(attrs, "streaming_cookie", &cookies);
-               mm_attrs_get_string_by_name(attrs, "streaming_user_agent", &user_agent);
-
-               if (player->ini.http_timeout != DEFAULT_HTTP_TIMEOUT) {
-                       LOGD("get timeout from ini\n");
-                       http_timeout = player->ini.http_timeout;
-               }
-
-               /* get attribute */
-               SECURE_LOGD("location : %s\n", player->profile.uri);
-               SECURE_LOGD("cookies : %s\n", cookies);
-               SECURE_LOGD("user_agent :  %s\n", user_agent);
-               LOGD("timeout : %d\n", http_timeout);
-
-               /* setting property to streaming source */
-               g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-               g_object_set(G_OBJECT(element), "timeout", http_timeout, NULL);
-               g_object_set(G_OBJECT(element), "blocksize", (unsigned long)(64*1024), NULL);
-
-               /* parsing cookies */
-               if ((cookie_list = util_get_cookie_list((const char*)cookies)))
-                       g_object_set(G_OBJECT(element), "cookies", cookie_list, NULL);
-               if (user_agent)
-                       g_object_set(G_OBJECT(element), "user_agent", user_agent, NULL);
-               break;
-       }
-       default:
-               LOGE("not support uri type %d\n", player->profile.uri_type);
-               break;
-       }
-
+       element = __mmplayer_gst_create_source(player);
        if (!element) {
-               LOGE("no source element was created.\n");
+               LOGE("no source element was created");
                goto ERROR;
        }
 
        if (gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element) == FALSE) {
-               LOGE("failed to add source element to pipeline\n");
+               LOGE("failed to add source element to pipeline");
                gst_object_unref(GST_OBJECT(element));
                element = NULL;
                goto ERROR;
@@ -10449,52 +6565,52 @@ __mmplayer_activate_next_source(mm_player_t *player, GstState target)
        if (MMPLAYER_IS_HTTP_STREAMING(player)) {
                if (player->streamer == NULL) {
                        player->streamer = __mm_player_streaming_create();
-                       __mm_player_streaming_initialize(player->streamer);
+                       __mm_player_streaming_initialize(player->streamer, TRUE);
                }
 
-               elemId = MMPLAYER_M_TYPEFIND;
+               elem_idx = MMPLAYER_M_TYPEFIND;
                element = gst_element_factory_make("typefind", "typefinder");
-               MMPLAYER_SIGNAL_CONNECT(player, element, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type",
-                       G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player);
+               __mmplayer_add_signal_connection(player, G_OBJECT(element),
+                       MM_PLAYER_SIGNAL_TYPE_AUTOPLUG, "have-type", G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player);
        } else {
-               elemId = MMPLAYER_M_AUTOPLUG;
-               element = __mmplayer_create_decodebin(player);
+               elem_idx = MMPLAYER_M_AUTOPLUG;
+               element = __mmplayer_gst_make_decodebin(player);
        }
 
        /* check autoplug element is OK */
        if (!element) {
-               LOGE("can not create element(%d)\n", elemId);
+               LOGE("can not create element(%d)", elem_idx);
                goto ERROR;
        }
 
        if (gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element) == FALSE) {
-               LOGE("failed to add sinkbin to pipeline\n");
+               LOGE("failed to add sinkbin to pipeline");
                gst_object_unref(GST_OBJECT(element));
                element = NULL;
                goto ERROR;
        }
 
-       mainbin[elemId].id = elemId;
-       mainbin[elemId].gst = element;
+       mainbin[elem_idx].id = elem_idx;
+       mainbin[elem_idx].gst = element;
 
-       if (gst_element_link(mainbin[MMPLAYER_M_SRC].gst, mainbin[elemId].gst) == FALSE) {
-               LOGE("Failed to link src - autoplug(or typefind)\n");
+       if (gst_element_link(mainbin[MMPLAYER_M_SRC].gst, mainbin[elem_idx].gst) == FALSE) {
+               LOGE("Failed to link src - autoplug(or typefind)");
                goto ERROR;
        }
 
        if (gst_element_set_state(mainbin[MMPLAYER_M_SRC].gst, target) == GST_STATE_CHANGE_FAILURE) {
-               LOGE("Failed to change state of src element\n");
+               LOGE("Failed to change state of src element");
                goto ERROR;
        }
 
        if (!MMPLAYER_IS_HTTP_STREAMING(player)) {
                if (gst_element_set_state(mainbin[MMPLAYER_M_AUTOPLUG].gst, target) == GST_STATE_CHANGE_FAILURE) {
-                       LOGE("Failed to change state of decodebin\n");
+                       LOGE("Failed to change state of decodebin");
                        goto ERROR;
                }
        } else {
                if (gst_element_set_state(mainbin[MMPLAYER_M_TYPEFIND].gst, target) == GST_STATE_CHANGE_FAILURE) {
-                       LOGE("Failed to change state of src element\n");
+                       LOGE("Failed to change state of src element");
                        goto ERROR;
                }
        }
@@ -10517,12 +6633,12 @@ ERROR:
 }
 
 static gboolean
-__mmplayer_deactivate_selector(mm_player_t *player, MMPlayerTrackType type)
+__mmplayer_deactivate_selector(mmplayer_t *player, mmplayer_track_type_e type)
 {
-       mm_player_selector_t *selector = &player->selector[type];
-       MMPlayerGstElement *sinkbin = NULL;
-       enum MainElementID selectorId = MMPLAYER_M_NUM;
-       enum MainElementID sinkId = MMPLAYER_M_NUM;
+       mmplayer_selector_t *selector = &player->selector[type];
+       mmplayer_gst_element_t *sinkbin = NULL;
+       main_element_id_e selectorId = MMPLAYER_M_NUM;
+       main_element_id_e sinkId = MMPLAYER_M_NUM;
        GstPad *srcpad = NULL;
        GstPad *sinkpad = NULL;
        gboolean send_notice = FALSE;
@@ -10575,7 +6691,7 @@ __mmplayer_deactivate_selector(mm_player_t *player, MMPlayerTrackType type)
                                /* send custom event to sink pad to handle it at video sink */
                                if (send_notice) {
                                        LOGD("send custom event to sinkpad");
-                                       GstStructure *s = gst_structure_new_empty("application/flush-buffer");
+                                       GstStructure *s = gst_structure_new_empty("tizen/flush-buffer");
                                        GstEvent *event = gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM, s);
                                        gst_pad_send_event(sinkpad, event);
                                }
@@ -10607,7 +6723,7 @@ __mmplayer_deactivate_selector(mm_player_t *player, MMPlayerTrackType type)
 }
 
 static void
-__mmplayer_deactivate_old_path(mm_player_t *player)
+__mmplayer_deactivate_old_path(mmplayer_t *player)
 {
        MMPLAYER_FENTER();
        MMPLAYER_RETURN_IF_FAIL(player);
@@ -10619,17 +6735,17 @@ __mmplayer_deactivate_old_path(mm_player_t *player)
                goto ERROR;
        }
 
-       _mmplayer_track_destroy(player);
+       __mmplayer_track_destroy(player);
        __mmplayer_release_signal_connection(player, MM_PLAYER_SIGNAL_TYPE_AUTOPLUG);
 
        if (player->streamer) {
-               __mm_player_streaming_deinitialize(player->streamer);
+               __mm_player_streaming_initialize(player->streamer, FALSE);
                __mm_player_streaming_destroy(player->streamer);
                player->streamer = NULL;
        }
 
        MMPLAYER_PLAYBACK_LOCK(player);
-       MMPLAYER_NEXT_PLAY_THREAD_SIGNAL(player);
+       MMPLAYER_GAPLESS_PLAY_THREAD_SIGNAL(player);
 
        MMPLAYER_FLEAVE();
        return;
@@ -10641,7 +6757,7 @@ ERROR:
 
                /*post error*/
                msg.code = MM_ERROR_PLAYER_INTERNAL;
-               LOGE("next_uri_play> deactivate error");
+               LOGE("gapless_uri_play> deactivate error");
 
                MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg);
                player->msg_posted = TRUE;
@@ -10649,46 +6765,32 @@ ERROR:
        return;
 }
 
-int _mmplayer_set_file_buffering_path(MMHandleType hplayer, const char* file_path)
-{
-       int result = MM_ERROR_NONE;
-       mm_player_t* player = (mm_player_t*) hplayer;
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       if (file_path) {
-               player->http_file_buffering_path = (gchar*)file_path;
-               LOGD("temp file path: %s\n", player->http_file_buffering_path);
-       }
-       MMPLAYER_FLEAVE();
-       return result;
-}
-
-int _mmplayer_set_uri(MMHandleType hplayer, const char* uri)
+int
+_mmplayer_set_uri(MMHandleType hplayer, const char *uri)
 {
        int result = MM_ERROR_NONE;
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
        mm_attrs_set_string_by_name(player->attrs, "profile_uri", uri);
-       if (mmf_attrs_commit(player->attrs)) {
-               LOGE("failed to commit the original uri.\n");
+       if (mm_attrs_commit_all(player->attrs)) {
+               LOGE("failed to commit the original uri.");
                result = MM_ERROR_PLAYER_INTERNAL;
        } else {
                if (_mmplayer_set_next_uri(hplayer, uri, TRUE) != MM_ERROR_NONE)
-                       LOGE("failed to add the original uri in the uri list.\n");
+                       LOGE("failed to add the original uri in the uri list.");
        }
 
        MMPLAYER_FLEAVE();
        return result;
 }
 
-int _mmplayer_set_next_uri(MMHandleType hplayer, const char* uri, bool is_first_path)
+int
+_mmplayer_set_next_uri(MMHandleType hplayer, const char *uri, bool is_first_path)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        guint num_of_list = 0;
 
        MMPLAYER_FENTER();
@@ -10697,21 +6799,21 @@ int _mmplayer_set_next_uri(MMHandleType hplayer, const char* uri, bool is_first_
        MMPLAYER_RETURN_VAL_IF_FAIL(uri, MM_ERROR_INVALID_ARGUMENT);
 
        if (player->pipeline && player->pipeline->textbin) {
-               LOGE("subtitle path is enabled.\n");
+               LOGE("subtitle path is enabled.");
                return MM_ERROR_PLAYER_INVALID_STATE;
        }
 
        num_of_list = g_list_length(player->uri_info.uri_list);
 
-       if (is_first_path == TRUE) {
+       if (is_first_path) {
                if (num_of_list == 0) {
                        player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(uri));
-                       LOGD("add original path : %s", uri);
+                       SECURE_LOGD("add original path : %s", uri);
                } else {
                        player->uri_info.uri_list = g_list_delete_link(player->uri_info.uri_list, g_list_nth(player->uri_info.uri_list, 0));
                        player->uri_info.uri_list = g_list_insert(player->uri_info.uri_list, g_strdup(uri), 0);
 
-                       LOGD("change original path : %s", uri);
+                       SECURE_LOGD("change original path : %s", uri);
                }
        } else {
                MMHandleType attrs = 0;
@@ -10731,21 +6833,22 @@ int _mmplayer_set_next_uri(MMHandleType hplayer, const char* uri, bool is_first_
                                player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(original_uri));
                                player->uri_info.uri_idx = 0;
 
-                               LOGD("add original path at first : %s(%d)", original_uri);
+                               SECURE_LOGD("add original path at first : %s", original_uri);
                        }
                }
 
                player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(uri));
-               LOGD("add new path : %s(total num of list = %d)", uri, g_list_length(player->uri_info.uri_list));
+               SECURE_LOGD("add new path : %s(total num of list = %d)", uri, g_list_length(player->uri_info.uri_list));
        }
 
        MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
 }
 
-int _mmplayer_get_next_uri(MMHandleType hplayer, char** uri)
+int
+_mmplayer_get_next_uri(MMHandleType hplayer, char **uri)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        char *next_uri = NULL;
        guint num_of_list = 0;
 
@@ -10763,7 +6866,7 @@ int _mmplayer_get_next_uri(MMHandleType hplayer, char** uri)
                        uri_idx = 0;
 
                next_uri = g_list_nth_data(player->uri_info.uri_list, uri_idx);
-               LOGE("next uri idx : %d, uri = %s\n", uri_idx, next_uri);
+               LOGE("next uri idx : %d, uri = %s", uri_idx, next_uri);
 
                *uri = g_strdup(next_uri);
        }
@@ -10773,13 +6876,13 @@ int _mmplayer_get_next_uri(MMHandleType hplayer, char** uri)
 }
 
 static void
-__mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPadpad,
-GstCaps *caps, gpointer data)
+__mmplayer_gst_decode_unknown_type(GstElement *elem,  GstPad *pad,
+       GstCaps *caps, gpointer data)
 {
-       mm_player_t* player = (mm_player_t*)data;
-       const gcharklass = NULL;
-       const gcharmime = NULL;
-       gcharcaps_str = NULL;
+       mmplayer_t *player = (mmplayer_t *)data;
+       const gchar *klass = NULL;
+       const gchar *mime = NULL;
+       gchar *caps_str = NULL;
 
        klass = gst_element_factory_get_metadata(gst_element_get_factory(elem), GST_ELEMENT_METADATA_KLASS);
        mime = gst_structure_get_name(gst_caps_get_structure(caps, 0));
@@ -10795,18 +6898,18 @@ GstCaps *caps, gpointer data)
 }
 
 static gboolean
-__mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPadpad,
-GstCaps * caps,  gpointer data)
+__mmplayer_gst_decode_autoplug_continue(GstElement *bin,  GstPad *pad,
+       GstCaps *caps,  gpointer data)
 {
-       mm_player_t* player = (mm_player_t*)data;
-       const charmime = NULL;
+       mmplayer_t *player = (mmplayer_t *)data;
+       const char *mime = NULL;
        gboolean ret = TRUE;
 
        MMPLAYER_LOG_GST_CAPS_TYPE(caps);
        mime = gst_structure_get_name(gst_caps_get_structure(caps, 0));
 
        if (g_str_has_prefix(mime, "audio")) {
-               GstStructurecaps_structure = NULL;
+               GstStructure *caps_structure = NULL;
                gint samplerate = 0;
                gint channels = 0;
                gchar *caps_str = NULL;
@@ -10842,16 +6945,225 @@ GstCaps * caps,  gpointer data)
        return ret;
 }
 
-static int
-__mmplayer_check_codec_info(mm_player_t* player, const char* klass, GstCaps* caps, char* factory_name)
+static gboolean
+__mmplayer_is_audio_offload_device_type(mmplayer_t *player)
 {
-       int ret = MM_ERROR_NONE;
+       gboolean ret = TRUE;
+       GDBusConnection *conn = NULL;
+       GError *err = NULL;
+       GVariant *result = NULL;
+       const gchar *dbus_device_type = NULL;
+       const gchar *dbus_ret = NULL;
+       gint idx = 0;
+
+       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);
+               g_error_free(err);
+               ret = FALSE;
+               goto DONE;
+       }
+
+       result = g_dbus_connection_call_sync(conn,
+                                       "org.pulseaudio.Server",
+                                       "/org/pulseaudio/StreamManager",
+                                       "org.pulseaudio.StreamManager",
+                                       "GetCurrentMediaRoutingPath",
+                                       g_variant_new("(s)", "out"),
+                                       G_VARIANT_TYPE("(ss)"),
+                                       G_DBUS_CALL_FLAGS_NONE,
+                                       2000,
+                                       NULL,
+                                       &err);
+       if (!result || err) {
+               LOGE("failed g_dbus_connection_call_sync() (%s)", err ? err->message : NULL);
+               g_error_free(err);
+               ret = FALSE;
+               goto DONE;
+       }
+
+       /* device type is listed in stream-map.json at mmfw-sysconf */
+       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;
+               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++) {
+               if (strstr(dbus_device_type, player->ini.audio_offload_device_type[idx])) {
+                       LOGD("audio offload is supportable");
+                       ret = TRUE;
+                       goto DONE;
+               }
+       }
+
+       LOGD("audio offload is not supportable");
+       ret = FALSE;
+
+DONE:
+       g_variant_unref(result);
+       g_object_unref(conn);
+
+       return ret;
+}
+
+static void __mmplayer_rebuild_audio_pipeline(mmplayer_t *player)
+{
+       mmplayer_state_e current_state = MM_PLAYER_STATE_NONE;
+       gint64 position = 0;
+
+       MMPLAYER_RETURN_IF_FAIL(player && player->attrs &&
+               player->pipeline && player->pipeline->mainbin);
+
+       MMPLAYER_CMD_LOCK(player);
+       current_state = MMPLAYER_CURRENT_STATE(player);
+
+       if (!gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &position))
+               LOGW("getting current position failed in paused");
+
+       _mmplayer_unrealize((MMHandleType)player);
+       _mmplayer_realize((MMHandleType)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");
+
+       _mmplayer_pause((MMHandleType)player);
+
+       if (current_state == MM_PLAYER_STATE_PLAYING)
+               _mmplayer_start((MMHandleType)player);
+       MMPLAYER_CMD_UNLOCK(player);
+
+       LOGD("rebuilding audio pipeline is completed.");
+}
+
+void __mmplayer_audio_device_connected_cb(MMSoundDevice_t device_h, bool is_connected, void *user_data)
+{
+       mmplayer_t *player = (mmplayer_t *)user_data;
+       mm_sound_device_type_e dev_type = MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER;
+       gboolean is_supportable = FALSE;
+
+       if (mm_sound_get_device_type(device_h, &dev_type) != MM_ERROR_NONE)
+               LOGW("failed to get device type");
+       else
+               LOGD("dev type (%d), connected (%d)", dev_type, is_connected);
+
+       if ((dev_type != MM_SOUND_DEVICE_TYPE_BLUETOOTH_A2DP) &&
+               (dev_type != MM_SOUND_DEVICE_TYPE_AUDIOJACK) &&
+               (dev_type != MM_SOUND_DEVICE_TYPE_USB_AUDIO)) {
+               LOGD("ignore this dev connected info");
+               return;
+       }
+
+       is_supportable = __mmplayer_is_audio_offload_device_type(player);
+       if (player->build_audio_offload == is_supportable) {
+               LOGD("keep current pipeline without re-building");
+               return;
+       }
+
+       /* rebuild pipeline */
+       LOGD("re-build pipeline - offload: %d", is_supportable);
+       player->build_audio_offload = FALSE;
+       __mmplayer_rebuild_audio_pipeline(player);
+
+       return;
+}
+
+static gboolean
+__mmplayer_add_audio_device_connected_cb(mmplayer_t *player)
+{
+       unsigned int id = 0;
+
+       if (player->audio_device_cb_id != 0) {
+               LOGW("audio device connected cb was already added (%u)", player->audio_device_cb_id);
+               return TRUE;
+       }
+
+       if (mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_IO_DIRECTION_OUT_FLAG,
+                               __mmplayer_audio_device_connected_cb, player, &id) == MM_ERROR_NONE) {
+               LOGD("added device connected cb (%u)", id);
+               player->audio_device_cb_id = id;
+       } else {
+               LOGW("failed to add device connected cb");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean
+__mmplayer_can_build_audio_offload_path(mmplayer_t *player)
+{
+       gboolean ret = FALSE;
+       GstElementFactory *factory = NULL;
+
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->attrs, FALSE);
+
+       LOGD("current stream : %s, sink: %s", player->type, player->ini.audio_offload_sink_element);
+       if (!__mmplayer_is_only_mp3_type(player->type))
+               goto DONE;
+
+       if (!strcmp(player->ini.audio_offload_sink_element, "")) {
+               LOGD("there is no audio offload sink");
+               goto DONE;
+       }
+
+       if (player->ini.audio_offload_device_type[0][0] == '\0') {
+               LOGW("there is no audio device type to support offload");
+               goto DONE;
+       }
+
+       factory = gst_element_factory_find(player->ini.audio_offload_sink_element);
+       if (!factory) {
+               LOGW("there is no installed audio offload sink element");
+               goto DONE;
+       }
+       gst_object_unref(factory);
+
+       if (!__mmplayer_add_audio_device_connected_cb(player))
+               goto DONE;
+
+       if (!__mmplayer_is_audio_offload_device_type(player))
+               goto DONE;
+
+       LOGD("audio offload can be built");
+       ret = TRUE;
+
+DONE:
+       MMPLAYER_FLEAVE();
+       return ret;
+}
+
+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"))) {
-               GstStructure* str = NULL;
-               gint channels = 0;
+               mm_attrs_get_int_by_name(player->attrs, MM_PLAYER_AUDIO_OFFLOAD, &audio_offload); /* user requirement */
+
+               if (audio_offload && __mmplayer_can_build_audio_offload_path(player)) {
+                       LOGD("expose audio path to build offload output path");
+                       player->build_audio_offload = TRUE;
+                       /* update codec info */
+                       player->not_supported_codec &= MISSING_PLUGIN_VIDEO;
+                       player->can_support_codec |= FOUND_PLUGIN_AUDIO;
+                       player->audiodec_linked = 1;
+
+                       ret = GST_AUTOPLUG_SELECT_EXPOSE;
+                       goto DONE;
+               }
+
                mm_attrs_get_int_by_name(player->attrs, "audio_codec_type", &codec_type);
 
                LOGD("audio codec type: %d", codec_type);
@@ -10860,7 +7172,7 @@ __mmplayer_check_codec_info(mm_player_t* player, const char* klass, GstCaps* cap
                        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 = MM_ERROR_PLAYER_INTERNAL;
+                                       ret = GST_AUTOPLUG_SELECT_SKIP;
                                        goto DONE;
                                }
                        }
@@ -10869,19 +7181,11 @@ __mmplayer_check_codec_info(mm_player_t* player, const char* klass, GstCaps* cap
                        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 = MM_ERROR_PLAYER_INTERNAL;
+                               ret = GST_AUTOPLUG_SELECT_SKIP;
                                goto DONE;
                        }
                }
 
-               str = gst_caps_get_structure(caps, 0);
-               if (str) {
-                       gst_structure_get_int(str, "channels", &channels);
-
-                       LOGD("check audio ch : %d %d\n", player->max_audio_channels, channels);
-                       if (player->max_audio_channels < channels)
-                               player->max_audio_channels = channels;
-               }
                /* set stream information */
                if (!player->audiodec_linked)
                        __mmplayer_set_audio_attrs(player, caps);
@@ -10901,7 +7205,7 @@ __mmplayer_check_codec_info(mm_player_t* player, const char* klass, GstCaps* cap
                        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 = MM_ERROR_PLAYER_INTERNAL;
+                                       ret = GST_AUTOPLUG_SELECT_SKIP;
                                        goto DONE;
                                }
                        }
@@ -10909,7 +7213,7 @@ __mmplayer_check_codec_info(mm_player_t* player, const char* klass, GstCaps* cap
                        /* 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 = MM_ERROR_PLAYER_INTERNAL;
+                               ret = GST_AUTOPLUG_SELECT_SKIP;
                                goto DONE;
                        }
                }
@@ -10925,12 +7229,12 @@ __mmplayer_check_codec_info(mm_player_t* player, const char* klass, GstCaps* cap
                                                &player->video_decoder_resource)
                                        != MM_RESOURCE_MANAGER_ERROR_NONE) {
                                        LOGE("could not mark video_decoder resource for acquire");
-                                       ret = MM_ERROR_PLAYER_INTERNAL;
+                                       ret = GST_AUTOPLUG_SELECT_SKIP;
                                        goto DONE;
                                }
                        } else {
                                LOGW("video decoder resource is already acquired, skip it.");
-                               ret = MM_ERROR_PLAYER_INTERNAL;
+                               ret = GST_AUTOPLUG_SELECT_SKIP;
                                goto DONE;
                        }
 
@@ -10938,8 +7242,8 @@ __mmplayer_check_codec_info(mm_player_t* player, const char* klass, GstCaps* cap
                        /* acquire resources for video playing */
                        if (mm_resource_manager_commit(player->resource_manager)
                                        != MM_RESOURCE_MANAGER_ERROR_NONE) {
-                               LOGE("could not acquire resources for video decoding\n");
-                               ret = MM_ERROR_PLAYER_INTERNAL;
+                               LOGE("could not acquire resources for video decoding");
+                               ret = GST_AUTOPLUG_SELECT_SKIP;
                                goto DONE;
                        }
                }
@@ -10954,24 +7258,16 @@ DONE:
        return ret;
 }
 
-static gint
-__mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPadpad,
-GstCaps* caps, GstElementFactory* factory, gpointer data)
+gint
+__mmplayer_gst_decode_autoplug_select(GstElement *bin,  GstPad *pad,
+       GstCaps *caps, GstElementFactory *factory, gpointer data)
 {
-       /* NOTE : GstAutoplugSelectResult is defined in gstplay-enum.h but not exposed
-        We are defining our own and will be removed when it actually exposed */
-       typedef enum {
-               GST_AUTOPLUG_SELECT_TRY,
-               GST_AUTOPLUG_SELECT_EXPOSE,
-               GST_AUTOPLUG_SELECT_SKIP
-       } GstAutoplugSelectResult;
-
        GstAutoplugSelectResult result = GST_AUTOPLUG_SELECT_TRY;
-       mm_player_t* player = (mm_player_t*)data;
+       mmplayer_t *player = (mmplayer_t *)data;
 
-       gcharfactory_name = NULL;
-       gcharcaps_str = NULL;
-       const gcharklass = NULL;
+       gchar *factory_name = NULL;
+       gchar *caps_str = NULL;
+       const gchar *klass = NULL;
        gint idx = 0;
 
        factory_name = GST_OBJECT_NAME(factory);
@@ -10989,7 +7285,7 @@ GstCaps* caps, GstElementFactory* factory, gpointer data)
        /* filtering exclude keyword */
        for (idx = 0; player->ini.exclude_element_keyword[idx][0] != '\0'; idx++) {
                if (strstr(factory_name, player->ini.exclude_element_keyword[idx])) {
-                       LOGW("skipping [%s] by exculde keyword [%s]\n",
+                       LOGW("skipping [%s] by exculde keyword [%s]",
                                        factory_name, player->ini.exclude_element_keyword[idx]);
 
                        result = GST_AUTOPLUG_SELECT_SKIP;
@@ -10997,6 +7293,15 @@ GstCaps* caps, GstElementFactory* factory, gpointer data)
                }
        }
 
+       for (idx = 0; player->ini.unsupported_codec_keyword[idx][0] != '\0'; idx++) {
+               if (caps_str && strstr(caps_str, player->ini.unsupported_codec_keyword[idx])) {
+                       LOGW("skipping [%s] by unsupported codec keyword [%s]",
+                               factory_name, player->ini.unsupported_codec_keyword[idx]);
+                       result = GST_AUTOPLUG_SELECT_SKIP;
+                       goto DONE;
+               }
+       }
+
        /* exclude webm format */
        /* NOTE : MSL have to post MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT
         * because webm format is not supportable.
@@ -11015,7 +7320,7 @@ GstCaps* caps, GstElementFactory* factory, gpointer data)
         * So, those plugins should be skipped for error handling.
         */
        if (g_strrstr(klass, "Codec/Decoder/Image")) {
-               LOGD("skipping [%s] by not required\n", factory_name);
+               LOGD("skipping [%s] by not required", factory_name);
                result = GST_AUTOPLUG_SELECT_SKIP;
                goto DONE;
        }
@@ -11023,13 +7328,13 @@ GstCaps* caps, GstElementFactory* factory, gpointer data)
        if ((MMPLAYER_IS_MS_BUFF_SRC(player)) &&
                (g_strrstr(klass, "Codec/Demuxer") || (g_strrstr(klass, "Codec/Parser")))) {
                // TO CHECK : subtitle if needed, add subparse exception.
-               LOGD("skipping parser/demuxer [%s] in es player by not required\n", factory_name);
+               LOGD("skipping parser/demuxer [%s] in es player by not required", factory_name);
                result = GST_AUTOPLUG_SELECT_SKIP;
                goto DONE;
        }
 
        if (g_strrstr(factory_name, "mpegpsdemux")) {
-               LOGD("skipping PS container - not support\n");
+               LOGD("skipping PS container - not support");
                result = GST_AUTOPLUG_SELECT_SKIP;
                goto DONE;
        }
@@ -11046,8 +7351,8 @@ GstCaps* caps, GstElementFactory* factory, gpointer data)
 
                /* don't make video because of not required */
                if ((stype == MM_DISPLAY_SURFACE_NULL) &&
-                       (player->set_mode.media_packet_video_stream == FALSE)) {
-                       LOGD("no video because it's not required. -> return expose");
+                       (!player->set_mode.video_export)) {
+                       LOGD("no need video decoding, expose pad");
                        result = GST_AUTOPLUG_SELECT_EXPOSE;
                        goto DONE;
                }
@@ -11070,9 +7375,9 @@ GstCaps* caps, GstElementFactory* factory, gpointer data)
        }
 
        if (g_strrstr(klass, "Codec/Decoder")) {
-               if (__mmplayer_check_codec_info(player, klass, caps, factory_name) != MM_ERROR_NONE) {
-                       LOGD("skipping %s codec", factory_name);
-                       result = GST_AUTOPLUG_SELECT_SKIP;
+               result = __mmplayer_check_codec_info(player, klass, caps, factory_name);
+               if (result != GST_AUTOPLUG_SELECT_TRY) {
+                       LOGW("skip add decoder");
                        goto DONE;
                }
        }
@@ -11084,30 +7389,33 @@ DONE:
 }
 
 static void
-__mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPadnew_pad,
-gpointer data)
+__mmplayer_gst_decode_pad_removed(GstElement *elem,  GstPad *new_pad,
+       gpointer data)
 {
-       //mm_player_t* player = (mm_player_t*)data;
-       GstCapscaps = NULL;
+       //mmplayer_t *player = (mmplayer_t *)data;
+       GstCaps *caps = NULL;
 
-       LOGD("[Decodebin2] pad-removed signal\n");
+       LOGD("[Decodebin2] pad-removed signal");
 
        caps = gst_pad_query_caps(new_pad, NULL);
-       if (caps) {
-               gchar* caps_str = NULL;
-               caps_str = gst_caps_to_string(caps);
+       if (!caps) {
+               LOGW("query caps is NULL");
+               return;
+       }
 
-               LOGD("pad removed caps : %s from %s", caps_str, GST_ELEMENT_NAME(elem));
+       gchar *caps_str = NULL;
+       caps_str = gst_caps_to_string(caps);
 
-               MMPLAYER_FREEIF(caps_str);
-               gst_caps_unref(caps);
-       }
+       LOGD("pad removed caps : %s from %s", caps_str, GST_ELEMENT_NAME(elem));
+
+       MMPLAYER_FREEIF(caps_str);
+       gst_caps_unref(caps);
 }
 
 static void
 __mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
 {
-       mm_player_t* player = (mm_player_t*)data;
+       mmplayer_t *player = (mmplayer_t *)data;
        GstIterator *iter = NULL;
        GValue item = { 0, };
        GstPad *pad = NULL;
@@ -11119,18 +7427,13 @@ __mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
 
        LOGD("__mmplayer_gst_decode_drained");
 
-       if (player->use_deinterleave == TRUE) {
-               LOGD("group playing mode.");
-               return;
-       }
-
        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_next_play_path(player)) {
+               !__mmplayer_verify_gapless_play_path(player)) {
                LOGD("decoding is finished.");
                __mmplayer_reset_gapless_state(player);
                MMPLAYER_CMD_UNLOCK(player);
@@ -11183,35 +7486,26 @@ __mmplayer_gst_decode_drained(GstElement *bin, gpointer data)
        MMPLAYER_FLEAVE();
 }
 
-static void
+void
 __mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data)
 {
-       mm_player_t* player = (mm_player_t*)data;
-       const gcharklass = NULL;
-       gcharfactory_name = NULL;
+       mmplayer_t *player = (mmplayer_t *)data;
+       const gchar *klass = NULL;
+       gchar *factory_name = NULL;
 
        klass = gst_element_factory_get_metadata(gst_element_get_factory(element), GST_ELEMENT_METADATA_KLASS);
        factory_name = GST_OBJECT_NAME(gst_element_get_factory(element));
 
-       LOGD("new elem klass: %s, factory_name: %s, new elem name : %s\n", klass, factory_name, GST_ELEMENT_NAME(element));
+       LOGD("new elem klass: %s, factory_name: %s, new elem name : %s", klass, factory_name, GST_ELEMENT_NAME(element));
 
        if (__mmplayer_add_dump_buffer_probe(player, element))
                LOGD("add buffer probe");
 
-       //<-
        if (g_strrstr(klass, "Codec/Decoder/Audio")) {
-               gcharselected = NULL;
+               gchar *selected = NULL;
                selected = g_strdup(GST_ELEMENT_NAME(element));
                player->audio_decoders = g_list_append(player->audio_decoders, selected);
        }
-       //-> temp code
-
-       if (g_strrstr(klass, "Parser")) {
-               gchar* selected = NULL;
-
-               selected = g_strdup(factory_name);
-               player->parsers = g_list_append(player->parsers, selected);
-       }
 
        if (g_strrstr(klass, "Demuxer/Adaptive")) {
                player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].id = MMPLAYER_M_ADAPTIVE_DEMUX;
@@ -11225,20 +7519,10 @@ __mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data
                                                "max-video-width", player->adaptive_info.limit.width,
                                                "max-video-height", player->adaptive_info.limit.height, NULL);
 
-       } else if (g_strrstr(klass, "Demux") || g_strrstr(klass, "Parse")) {
-               /* FIXIT : first value will be overwritten if there's more
-                * than 1 demuxer/parser
-                */
-
-               //LOGD("plugged element is demuxer. take it\n");
+       } else if (g_strrstr(klass, "Demuxer")) {
+               //LOGD("plugged element is demuxer. take it");
                player->pipeline->mainbin[MMPLAYER_M_DEMUX].id = MMPLAYER_M_DEMUX;
                player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst = element;
-
-               /*Added for multi audio support */ // Q. del?
-               if (g_strrstr(klass, "Demux")) {
-                       player->pipeline->mainbin[MMPLAYER_M_DEMUX_EX].id = MMPLAYER_M_DEMUX_EX;
-                       player->pipeline->mainbin[MMPLAYER_M_DEMUX_EX].gst = element;
-               }
        }
 
        if (g_strrstr(factory_name, "asfdemux") || g_strrstr(factory_name, "qtdemux") || g_strrstr(factory_name, "avidemux")) {
@@ -11249,13 +7533,10 @@ __mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data
 
        // to support trust-zone only
        if (g_strrstr(factory_name, "asfdemux")) {
-               LOGD("set file-location %s\n", player->profile.uri);
+               LOGD("set file-location %s", player->profile.uri);
                g_object_set(G_OBJECT(element), "file-location", player->profile.uri, NULL);
-
-               if (player->video_hub_download_mode == TRUE)
-                       g_object_set(G_OBJECT(element), "downloading-mode", player->video_hub_download_mode, NULL);
        } else if (g_strrstr(factory_name, "legacyh264parse")) {
-               LOGD("[%s] output-format to legacyh264parse\n", "mssdemux");
+               LOGD("[%s] output-format to legacyh264parse", "mssdemux");
                g_object_set(G_OBJECT(element), "output-format", 1, NULL); /* NALU/Byte Stream format */
        } else if (g_strrstr(factory_name, "mpegaudioparse")) {
                if ((MMPLAYER_IS_HTTP_STREAMING(player)) &&
@@ -11269,70 +7550,26 @@ __mmplayer_gst_element_added(GstElement *bin, GstElement *element, gpointer data
 
        if ((player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst) &&
                (g_strrstr(GST_ELEMENT_NAME(element), "multiqueue"))) {
-               LOGD("plugged element is multiqueue. take it\n");
+               LOGD("plugged element is multiqueue. take it %s", GST_ELEMENT_NAME(element));
 
                player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].id = MMPLAYER_M_DEMUXED_S_BUFFER;
                player->pipeline->mainbin[MMPLAYER_M_DEMUXED_S_BUFFER].gst = element;
 
-               if (!MMPLAYER_IS_HTTP_PD(player) &&
-                       ((MMPLAYER_IS_HTTP_STREAMING(player)) ||
-                       (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)))) {
+               if ((MMPLAYER_IS_HTTP_STREAMING(player)) ||
+                       (MMPLAYER_IS_HTTP_LIVE_STREAMING(player)) ||
+                       (MMPLAYER_IS_DASH_STREAMING(player))) {
                        /* in case of multiqueue, max bytes size is defined with fixed value in mm_player_streaming.h*/
-                       __mm_player_streaming_set_multiqueue(player->streamer,
-                               element,
-                               TRUE,
-                               player->ini.http_buffering_time,
-                               1.0,
-                               player->ini.http_buffering_limit);
-
+                       __mm_player_streaming_set_multiqueue(player->streamer, element);
                        __mm_player_streaming_sync_property(player->streamer, player->pipeline->mainbin[MMPLAYER_M_AUTOPLUG].gst);
                }
-       }
-
-       return;
-}
-
-static gboolean __mmplayer_configure_audio_callback(mm_player_t* player)
-{
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-
-       if (MMPLAYER_IS_STREAMING(player))
-               return FALSE;
-
-       /* This callback can be set to music player only. */
-       if ((player->can_support_codec & 0x02) == FOUND_PLUGIN_VIDEO) {
-               LOGW("audio callback is not supported for video");
-               return FALSE;
-       }
-
-       if (player->audio_stream_cb) {
-               GstPad *pad = NULL;
-
-               pad = gst_element_get_static_pad(player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
-
-               if (!pad) {
-                       LOGE("failed to get sink pad from audiosink to probe data\n");
-                       return FALSE;
-               }
-               player->audio_cb_probe_id = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER,
-                       __mmplayer_audio_stream_probe, player, NULL);
 
-               gst_object_unref(pad);
-
-               pad = NULL;
-       } else {
-               LOGE("There is no audio callback to configure.\n");
-               return FALSE;
        }
 
-       MMPLAYER_FLEAVE();
-
-       return TRUE;
+       return;
 }
 
 static void
-__mmplayer_release_misc(mm_player_t* player)
+__mmplayer_release_misc(mmplayer_t *player)
 {
        int i;
        bool cur_mode = player->set_mode.rich_audio;
@@ -11340,14 +7577,13 @@ __mmplayer_release_misc(mm_player_t* player)
 
        MMPLAYER_RETURN_IF_FAIL(player);
 
-       player->video_stream_cb = NULL;
-       player->video_stream_cb_user_param = NULL;
-       player->video_stream_prerolled = FALSE;
+       player->video_decoded_cb = NULL;
+       player->video_decoded_cb_user_param = NULL;
+       player->video_stream_prerolled = false;
 
-       player->audio_stream_cb = NULL;
-       player->audio_stream_render_cb_ex = NULL;
-       player->audio_stream_cb_user_param = NULL;
-       player->audio_stream_sink_sync = 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;
@@ -11358,7 +7594,7 @@ __mmplayer_release_misc(mm_player_t* player)
        player->sent_bos = FALSE;
        player->playback_rate = DEFAULT_PLAYBACK_RATE;
 
-       player->doing_seek = FALSE;
+       player->seek_state = MMPLAYER_SEEK_NONE;
 
        player->total_bitrate = 0;
        player->total_maximum_bitrate = 0;
@@ -11370,25 +7606,25 @@ __mmplayer_release_misc(mm_player_t* player)
        player->http_content_size = 0;
        player->not_supported_codec = MISSING_PLUGIN_NONE;
        player->can_support_codec = FOUND_PLUGIN_NONE;
-       player->pending_seek.is_pending = FALSE;
-       player->pending_seek.format = MM_PLAYER_POS_FORMAT_TIME;
+       player->pending_seek.is_pending = false;
        player->pending_seek.pos = 0;
        player->msg_posted = FALSE;
        player->has_many_types = FALSE;
-       player->max_audio_channels = 0;
-       player->video_share_api_delta = 0;
-       player->video_share_clock_delta = 0;
        player->is_subtitle_force_drop = FALSE;
        player->play_subtitle = FALSE;
        player->adjust_subtitle_pos = 0;
-       player->last_multiwin_status = FALSE;
        player->has_closed_caption = FALSE;
-       player->set_mode.media_packet_video_stream = FALSE;
+       player->set_mode.video_export = false;
        player->profile.uri_type = MM_PLAYER_URI_TYPE_NONE;
-       memset(&player->set_mode, 0, sizeof(MMPlayerSetMode));
+       memset(&player->set_mode, 0, sizeof(mmplayer_setting_mode_t));
        /* recover mode */
        player->set_mode.rich_audio = cur_mode;
 
+       if (player->audio_device_cb_id > 0 &&
+               mm_sound_remove_device_connected_callback(player->audio_device_cb_id) != MM_ERROR_NONE)
+               LOGW("failed to remove audio device_connected_callback");
+       player->audio_device_cb_id = 0;
+
        for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++) {
                player->bitrate[i] = 0;
                player->maximum_bitrate[i] = 0;
@@ -11435,11 +7671,12 @@ __mmplayer_release_misc(mm_player_t* player)
 
        player->sound.rg_enable = false;
 
+       __mmplayer_initialize_video_roi(player);
        MMPLAYER_FLEAVE();
 }
 
 static void
-__mmplayer_release_misc_post(mm_player_t* player)
+__mmplayer_release_misc_post(mmplayer_t *player)
 {
        char *original_uri = NULL;
        MMPLAYER_FENTER();
@@ -11450,17 +7687,6 @@ __mmplayer_release_misc_post(mm_player_t* player)
 
        mm_attrs_set_int_by_name(player->attrs, "content_video_found", 0);
 
-       /* clean found parsers */
-       if (player->parsers) {
-               GList *parsers = player->parsers;
-               for (; parsers; parsers = g_list_next(parsers)) {
-                       gchar *name = parsers->data;
-                       MMPLAYER_FREEIF(name);
-               }
-               g_list_free(player->parsers);
-               player->parsers = NULL;
-       }
-
        /* clean found audio decoders */
        if (player->audio_decoders) {
                GList *a_dec = player->audio_decoders;
@@ -11478,10 +7704,10 @@ __mmplayer_release_misc_post(mm_player_t* player)
 
                if (player->attrs) {
                        mm_attrs_set_string_by_name(player->attrs, "profile_uri", original_uri);
-                       LOGD("restore original uri = %s\n", original_uri);
+                       LOGD("restore original uri = %s", original_uri);
 
-                       if (mmf_attrs_commit(player->attrs))
-                               LOGE("failed to commit the original uri.\n");
+                       if (mm_attrs_commit_all(player->attrs))
+                               LOGE("failed to commit the original uri.");
                }
 
                GList *uri_list = player->uri_info.uri_list;
@@ -11511,49 +7737,8 @@ __mmplayer_release_misc_post(mm_player_t* player)
        MMPLAYER_FLEAVE();
 }
 
-static GstElement *__mmplayer_element_create_and_link(mm_player_t *player, GstPad* pad, const char* name)
-{
-       GstElement *element = NULL;
-       GstPad *sinkpad;
-
-       LOGD("creating %s to plug\n", name);
-
-       element = gst_element_factory_make(name, NULL);
-       if (!element) {
-               LOGE("failed to create queue\n");
-               return NULL;
-       }
-
-       if (GST_STATE_CHANGE_FAILURE == gst_element_set_state(element, GST_STATE_READY)) {
-               LOGE("failed to set state READY to %s\n", name);
-               gst_object_unref(element);
-               return NULL;
-       }
-
-       if (!gst_bin_add(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), element)) {
-               LOGE("failed to add %s\n", name);
-               gst_object_unref(element);
-               return NULL;
-       }
-
-       sinkpad = gst_element_get_static_pad(element, "sink");
-
-       if (GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad)) {
-               LOGE("failed to link %s\n", name);
-               gst_object_unref(sinkpad);
-               gst_object_unref(element);
-               return NULL;
-       }
-
-       LOGD("linked %s to pipeline successfully\n", name);
-
-       gst_object_unref(sinkpad);
-
-       return element;
-}
-
 gboolean
-__mmplayer_check_subtitle(mm_player_t* player)
+__mmplayer_check_subtitle(mmplayer_t *player)
 {
        MMHandleType attrs = 0;
        char *subtitle_uri = NULL;
@@ -11571,7 +7756,7 @@ __mmplayer_check_subtitle(mm_player_t* player)
        if (!subtitle_uri || !strlen(subtitle_uri))
                return FALSE;
 
-       LOGD("subtite uri is %s[%d]\n", subtitle_uri, strlen(subtitle_uri));
+       SECURE_LOGD("subtitle uri is %s[%zu]", subtitle_uri, strlen(subtitle_uri));
        player->is_external_subtitle_present = TRUE;
 
        MMPLAYER_FLEAVE();
@@ -11579,443 +7764,72 @@ __mmplayer_check_subtitle(mm_player_t* player)
        return TRUE;
 }
 
-static gboolean
-__mmplayer_can_extract_pcm(mm_player_t* player)
-{
-       MMHandleType attrs = 0;
-       gboolean sound_extraction = FALSE;
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if (!attrs) {
-               LOGE("fail to get attributes.");
-               return FALSE;
-       }
-
-       /* get sound_extraction property */
-       mm_attrs_get_int_by_name(attrs, "pcm_extraction", &sound_extraction);
-
-       if (!sound_extraction) {
-               LOGD("checking pcm extraction mode : %d ", sound_extraction);
-               return FALSE;
-       }
-
-       return TRUE;
-}
-
-static gboolean
-__mmplayer_handle_streaming_error(mm_player_t* player, GstMessage * message)
-{
-       LOGD("\n");
-       MMMessageParamType msg_param;
-       gchar *msg_src_element = NULL;
-       GstStructure *s = NULL;
-       guint error_id = 0;
-       gchar *error_string = NULL;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL(message, FALSE);
-
-       s = gst_structure_copy(gst_message_get_structure(message));
-
-
-       if (!gst_structure_get_uint(s, "error_id", &error_id))
-               error_id = MMPLAYER_STREAMING_ERROR_NONE;
-
-       switch (error_id) {
-       case MMPLAYER_STREAMING_ERROR_UNSUPPORTED_AUDIO:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_UNSUPPORTED_AUDIO;
-               break;
-       case MMPLAYER_STREAMING_ERROR_UNSUPPORTED_VIDEO:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_UNSUPPORTED_VIDEO;
-               break;
-       case MMPLAYER_STREAMING_ERROR_CONNECTION_FAIL:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_CONNECTION_FAIL;
-               break;
-       case MMPLAYER_STREAMING_ERROR_DNS_FAIL:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_DNS_FAIL;
-               break;
-       case MMPLAYER_STREAMING_ERROR_SERVER_DISCONNECTED:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_SERVER_DISCONNECTED;
-               break;
-       case MMPLAYER_STREAMING_ERROR_BAD_SERVER:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_SERVER;
-               break;
-       case MMPLAYER_STREAMING_ERROR_INVALID_PROTOCOL:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_INVALID_PROTOCOL;
-               break;
-       case MMPLAYER_STREAMING_ERROR_INVALID_URL:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_INVALID_URL;
-               break;
-       case MMPLAYER_STREAMING_ERROR_UNEXPECTED_MSG:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_UNEXPECTED_MSG;
-               break;
-       case MMPLAYER_STREAMING_ERROR_OUT_OF_MEMORIES:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_OUT_OF_MEMORIES;
-               break;
-       case MMPLAYER_STREAMING_ERROR_RTSP_TIMEOUT:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_RTSP_TIMEOUT;
-               break;
-       case MMPLAYER_STREAMING_ERROR_BAD_REQUEST:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_REQUEST;
-               break;
-       case MMPLAYER_STREAMING_ERROR_NOT_AUTHORIZED:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_AUTHORIZED;
-               break;
-       case MMPLAYER_STREAMING_ERROR_PAYMENT_REQUIRED:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_PAYMENT_REQUIRED;
-               break;
-       case MMPLAYER_STREAMING_ERROR_FORBIDDEN:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_FORBIDDEN;
-               break;
-       case MMPLAYER_STREAMING_ERROR_CONTENT_NOT_FOUND:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_CONTENT_NOT_FOUND;
-               break;
-       case MMPLAYER_STREAMING_ERROR_METHOD_NOT_ALLOWED:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_METHOD_NOT_ALLOWED;
-               break;
-       case MMPLAYER_STREAMING_ERROR_NOT_ACCEPTABLE:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_ACCEPTABLE;
-               break;
-       case MMPLAYER_STREAMING_ERROR_PROXY_AUTHENTICATION_REQUIRED:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_PROXY_AUTHENTICATION_REQUIRED;
-               break;
-       case MMPLAYER_STREAMING_ERROR_SERVER_TIMEOUT:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_SERVER_TIMEOUT;
-               break;
-       case MMPLAYER_STREAMING_ERROR_GONE:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_GONE;
-               break;
-       case MMPLAYER_STREAMING_ERROR_LENGTH_REQUIRED:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_LENGTH_REQUIRED;
-               break;
-       case MMPLAYER_STREAMING_ERROR_PRECONDITION_FAILED:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_PRECONDITION_FAILED;
-               break;
-       case MMPLAYER_STREAMING_ERROR_REQUEST_ENTITY_TOO_LARGE:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_REQUEST_ENTITY_TOO_LARGE;
-               break;
-       case MMPLAYER_STREAMING_ERROR_REQUEST_URI_TOO_LARGE:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_REQUEST_URI_TOO_LARGE;
-               break;
-       case MMPLAYER_STREAMING_ERROR_UNSUPPORTED_MEDIA_TYPE:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_UNSUPPORTED_MEDIA_TYPE;
-               break;
-       case MMPLAYER_STREAMING_ERROR_PARAMETER_NOT_UNDERSTOOD:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_PARAMETER_NOT_UNDERSTOOD;
-               break;
-       case MMPLAYER_STREAMING_ERROR_CONFERENCE_NOT_FOUND:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_CONFERENCE_NOT_FOUND;
-               break;
-       case MMPLAYER_STREAMING_ERROR_NOT_ENOUGH_BANDWIDTH:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_ENOUGH_BANDWIDTH;
-               break;
-       case MMPLAYER_STREAMING_ERROR_NO_SESSION_ID:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_NO_SESSION_ID;
-               break;
-       case MMPLAYER_STREAMING_ERROR_METHOD_NOT_VALID_IN_THIS_STATE:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_METHOD_NOT_VALID_IN_THIS_STATE;
-               break;
-       case MMPLAYER_STREAMING_ERROR_HEADER_FIELD_NOT_VALID_FOR_SOURCE:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_HEADER_FIELD_NOT_VALID_FOR_SOURCE;
-               break;
-       case MMPLAYER_STREAMING_ERROR_INVALID_RANGE:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_INVALID_RANGE;
-               break;
-       case MMPLAYER_STREAMING_ERROR_PARAMETER_IS_READONLY:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_PARAMETER_IS_READONLY;
-               break;
-       case MMPLAYER_STREAMING_ERROR_AGGREGATE_OP_NOT_ALLOWED:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_AGGREGATE_OP_NOT_ALLOWED;
-               break;
-       case MMPLAYER_STREAMING_ERROR_ONLY_AGGREGATE_OP_ALLOWED:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_ONLY_AGGREGATE_OP_ALLOWED;
-               break;
-       case MMPLAYER_STREAMING_ERROR_BAD_TRANSPORT:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_TRANSPORT;
-               break;
-       case MMPLAYER_STREAMING_ERROR_DESTINATION_UNREACHABLE:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_DESTINATION_UNREACHABLE;
-               break;
-       case MMPLAYER_STREAMING_ERROR_INTERNAL_SERVER_ERROR:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_INTERNAL_SERVER_ERROR;
-               break;
-       case MMPLAYER_STREAMING_ERROR_NOT_IMPLEMENTED:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_NOT_IMPLEMENTED;
-               break;
-       case MMPLAYER_STREAMING_ERROR_BAD_GATEWAY:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_BAD_GATEWAY;
-               break;
-       case MMPLAYER_STREAMING_ERROR_SERVICE_UNAVAILABLE:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_SERVICE_UNAVAILABLE;
-               break;
-       case MMPLAYER_STREAMING_ERROR_GATEWAY_TIME_OUT:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_GATEWAY_TIME_OUT;
-               break;
-       case MMPLAYER_STREAMING_ERROR_RTSP_VERSION_NOT_SUPPORTED:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_RTSP_VERSION_NOT_SUPPORTED;
-               break;
-       case MMPLAYER_STREAMING_ERROR_OPTION_NOT_SUPPORTED:
-               msg_param.code = MM_ERROR_PLAYER_STREAMING_OPTION_NOT_SUPPORTED;
-               break;
-       default:
-               {
-                       gst_structure_free(s);
-                       return MM_ERROR_PLAYER_STREAMING_FAIL;
-               }
-       }
-
-       error_string = g_strdup(gst_structure_get_string(s, "error_string"));
-       if (error_string)
-               msg_param.data = (void *) error_string;
-
-       if (message->src) {
-               msg_src_element = GST_ELEMENT_NAME(GST_ELEMENT_CAST(message->src));
-
-               LOGE("-Msg src : [%s] Code : [%x] Error : [%s]  \n",
-                       msg_src_element, msg_param.code, (char*)msg_param.data);
-       }
-
-       /* post error to application */
-       if (!player->msg_posted) {
-               MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
-
-               /* don't post more if one was sent already */
-               player->msg_posted = TRUE;
-       } else
-               LOGD("skip error post because it's sent already.\n");
-
-       gst_structure_free(s);
-       MMPLAYER_FLEAVE();
-       g_free(error_string);
-
-       return TRUE;
-
-}
-
-static void
-__mmplayer_handle_eos_delay(mm_player_t* player, int delay_in_ms)
-{
-       MMPLAYER_RETURN_IF_FAIL(player);
-
-       /* post now if delay is zero */
-       if (delay_in_ms == 0 || player->set_mode.pcm_extraction) {
-               LOGD("eos delay is zero. posting EOS now\n");
-               MMPLAYER_POST_MSG(player, MM_MESSAGE_END_OF_STREAM, NULL);
-
-               if (player->set_mode.pcm_extraction)
-                       __mmplayer_cancel_eos_timer(player);
-
-               return;
-       }
-
-       /* cancel if existing */
-       __mmplayer_cancel_eos_timer(player);
-
-       /* init new timeout */
-       /* NOTE : consider give high priority to this timer */
-       LOGD("posting EOS message after [%d] msec\n", delay_in_ms);
-
-       player->eos_timer = g_timeout_add(delay_in_ms,
-               __mmplayer_eos_timer_cb, player);
-
-       player->context.global_default = g_main_context_default();
-       LOGD("global default context = %p, eos timer id = %d", player->context.global_default, player->eos_timer);
-
-       /* check timer is valid. if not, send EOS now */
-       if (player->eos_timer == 0) {
-               LOGW("creating timer for delayed EOS has failed. sending EOS now\n");
-               MMPLAYER_POST_MSG(player, MM_MESSAGE_END_OF_STREAM, NULL);
-       }
-}
-
-static void
-__mmplayer_cancel_eos_timer(mm_player_t* player)
+void
+__mmplayer_cancel_eos_timer(mmplayer_t *player)
 {
        MMPLAYER_RETURN_IF_FAIL(player);
 
        if (player->eos_timer) {
                LOGD("cancel eos timer");
                __mmplayer_remove_g_source_from_context(player->context.global_default, player->eos_timer);
-               player->eos_timer = 0;
-       }
-
-       return;
-}
-
-static gboolean
-__mmplayer_eos_timer_cb(gpointer u_data)
-{
-       mm_player_t* player = NULL;
-       MMHandleType attrs = 0;
-       int count = 0;
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(u_data, FALSE);
-
-       player = (mm_player_t*) u_data;
-       attrs = MMPLAYER_GET_ATTRS(player);
-
-       mm_attrs_get_int_by_name(attrs, "profile_play_count", &count);
-
-       if (count == -1) {
-               gint ret_value = 0;
-               ret_value = __gst_set_position(player, MM_PLAYER_POS_FORMAT_TIME, 0, TRUE);
-               if (ret_value != MM_ERROR_NONE)
-                       LOGE("seeking to 0 failed in repeat play");
-       } else {
-               /* posting eos */
-               MMPLAYER_POST_MSG(player, MM_MESSAGE_END_OF_STREAM, NULL);
-       }
-
-       /* we are returning FALSE as we need only one posting */
-       return FALSE;
-}
-
-/* sending event to one of sinkelements */
-static gboolean
-__gst_send_event_to_sink(mm_player_t* player, GstEvent* event)
-{
-       GstEvent * event2 = NULL;
-       GList *sinks = NULL;
-       gboolean res = FALSE;
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL(event, FALSE);
-
-       /* While adding subtitles in live feeds seek is getting called.
-          Adding defensive check in framework layer.*/
-       if (GST_EVENT_TYPE(event) == GST_EVENT_SEEK) {
-               if (MMPLAYER_IS_LIVE_STREAMING(player)) {
-                       LOGE("Should not send seek event during live playback");
-                       return TRUE;
-               }
-       }
-
-       if (player->play_subtitle)
-               event2 = gst_event_copy((const GstEvent *)event);
-
-       sinks = player->sink_elements;
-       while (sinks) {
-               GstElement *sink = GST_ELEMENT_CAST(sinks->data);
-
-               if (GST_IS_ELEMENT(sink)) {
-                       /* keep ref to the event */
-                       gst_event_ref(event);
-
-                       if ((res = gst_element_send_event(sink, event))) {
-                               LOGD("sending event[%s] to sink element [%s] success!\n",
-                                       GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(sink));
-
-                               /* rtsp case, asyn_done is not called after seek during pause state */
-                               if (MMPLAYER_IS_RTSP_STREAMING(player)) {
-                                       if (GST_EVENT_TYPE(event) == GST_EVENT_SEEK) {
-                                               if (MMPLAYER_TARGET_STATE(player) == MM_PLAYER_STATE_PAUSED) {
-                                                       LOGD("RTSP seek completed, after pause state..\n");
-                                                       player->doing_seek = FALSE;
-                                                       MMPLAYER_POST_MSG(player, MM_MESSAGE_SEEK_COMPLETED, NULL);
-                                               }
-
-                                       }
-                               }
-
-                               if (MMPLAYER_IS_MS_BUFF_SRC(player)) {
-                                       sinks = g_list_next(sinks);
-                                       continue;
-                               } else {
-                                       break;
-                               }
-                       }
-
-                       LOGD("sending event[%s] to sink element [%s] failed. try with next one.\n",
-                               GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(sink));
-               }
-
-               sinks = g_list_next(sinks);
-       }
-
-       /* Note : Textbin is not linked to the video or audio bin.
-        * It needs to send the event to the text sink seperatelly.
-        */
-        if (player->play_subtitle && player->pipeline) {
-               GstElement *text_sink = GST_ELEMENT_CAST(player->pipeline->textbin[MMPLAYER_T_FAKE_SINK].gst);
-
-               if (GST_IS_ELEMENT(text_sink)) {
-                       /* keep ref to the event */
-                       gst_event_ref(event2);
-
-                       if ((res = gst_element_send_event(text_sink, event2)))
-                               LOGD("sending event[%s] to subtitle sink element [%s] success!\n",
-                                       GST_EVENT_TYPE_NAME(event2), GST_ELEMENT_NAME(text_sink));
-                       else
-                               LOGE("sending event[%s] to subtitle sink element [%s] failed!\n",
-                                       GST_EVENT_TYPE_NAME(event2), GST_ELEMENT_NAME(text_sink));
-
-                       gst_event_unref(event2);
-               }
-        }
-
-       gst_event_unref(event);
-
-       MMPLAYER_FLEAVE();
+               player->eos_timer = 0;
+       }
 
-       return res;
+       return;
 }
 
 static void
-__mmplayer_add_sink(mm_player_t* player, GstElement* sink)
+__mmplayer_add_sink(mmplayer_t *player, GstElement *sink)
 {
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_IF_FAIL(player);
        MMPLAYER_RETURN_IF_FAIL(sink);
 
-       player->sink_elements =
-               g_list_append(player->sink_elements, sink);
+       player->sink_elements = g_list_append(player->sink_elements, sink);
 
        MMPLAYER_FLEAVE();
 }
 
 static void
-__mmplayer_del_sink(mm_player_t* player, GstElement* sink)
+__mmplayer_del_sink(mmplayer_t *player, GstElement *sink)
 {
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_IF_FAIL(player);
        MMPLAYER_RETURN_IF_FAIL(sink);
 
-       player->sink_elements =
-                       g_list_remove(player->sink_elements, sink);
+       player->sink_elements = g_list_remove(player->sink_elements, sink);
 
        MMPLAYER_FLEAVE();
 }
 
-static gboolean
-__gst_seek(mm_player_t* player, GstElement * element, gdouble rate,
-                       GstFormat format, GstSeekFlags flags, GstSeekType cur_type,
-                       gint64 cur, GstSeekType stop_type, gint64 stop)
+void
+__mmplayer_add_signal_connection(mmplayer_t *player, GObject *object,
+       mmplayer_signal_type_e type, const gchar *signal, GCallback cb_funct, gpointer u_data)
 {
-       GstEvent* event = NULL;
-       gboolean result = FALSE;
+       mmplayer_signal_item_t *item = NULL;
 
        MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player);
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-
-       if (player->pipeline && player->pipeline->textbin)
-               __mmplayer_drop_subtitle(player, FALSE);
+       if (type >= MM_PLAYER_SIGNAL_TYPE_MAX) {
+               LOGE("invalid signal type [%d]", type);
+               return;
+       }
 
-       event = gst_event_new_seek(rate, format, flags, cur_type,
-               cur, stop_type, stop);
+       item = (mmplayer_signal_item_t *)g_try_malloc(sizeof(mmplayer_signal_item_t));
+       if (!item) {
+               LOGE("cannot connect signal [%s]", signal);
+               return;
+       }
 
-       result = __gst_send_event_to_sink(player, event);
+       item->obj = object;
+       item->sig = g_signal_connect(object, signal, cb_funct, u_data);
+       player->signals[type] = g_list_append(player->signals[type], item);
 
        MMPLAYER_FLEAVE();
-
-       return result;
+       return;
 }
 
 /* NOTE : be careful with calling this api. please refer to below glib comment
@@ -12036,10 +7850,10 @@ __gst_seek(mm_player_t* player, GstElement * element, gdouble rate,
  *    g_signal_handler_disconnect(instance, id);
  */
 static void
-__mmplayer_release_signal_connection(mm_player_t* player, MMPlayerSignalType type)
+__mmplayer_release_signal_connection(mmplayer_t *player, mmplayer_signal_type_e type)
 {
-       GListsig_list = NULL;
-       MMPlayerSignalItem* item = NULL;
+       GList *sig_list = NULL;
+       mmplayer_signal_item_t *item = NULL;
 
        MMPLAYER_FENTER();
 
@@ -12077,16 +7891,12 @@ __mmplayer_release_signal_connection(mm_player_t* player, MMPlayerSignalType typ
        return;
 }
 
-int _mmplayer_change_videosink(MMHandleType handle, MMDisplaySurfaceType surface_type, void *display_overlay)
+int
+_mmplayer_change_videosink(MMHandleType handle, MMDisplaySurfaceType surface_type, void *display_overlay)
 {
-       mm_player_t* player = 0;
+       mmplayer_t *player = 0;
        int prev_display_surface_type = 0;
        void *prev_display_overlay = NULL;
-       const gchar *klass = NULL;
-       gchar *cur_videosink_name = NULL;
-       int ret = 0;
-       int i = 0;
-       int num_of_dec = 2; /* DEC1, DEC2 */
 
        MMPLAYER_FENTER();
 
@@ -12095,6 +7905,14 @@ int _mmplayer_change_videosink(MMHandleType handle, MMDisplaySurfaceType surface
 
        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");
+               return MM_ERROR_NONE;
+       }
+
+       LOGD("videosink element is not yet ready");
+
        if (surface_type >= MM_DISPLAY_SURFACE_NUM) {
                LOGE("Not support this surface type(%d) for changing vidoesink", surface_type);
                MMPLAYER_FLEAVE();
@@ -12117,350 +7935,25 @@ int _mmplayer_change_videosink(MMHandleType handle, MMDisplaySurfaceType surface
                return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       /* check videosink element is created */
-       if (!player->pipeline || !player->pipeline->videobin ||
-               !player->pipeline->videobin[MMPLAYER_V_SINK].gst) {
-               LOGD("videosink element is not yet ready");
-
-               /* 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 (mmf_attrs_commit(player->attrs)) {
-                       LOGE("failed to commit attribute");
-                       MMPLAYER_FLEAVE();
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-               MMPLAYER_FLEAVE();
-               return MM_ERROR_NONE;
-       } else {
-               /* get player command status */
-               if (!(player->cmd == MMPLAYER_COMMAND_START || player->cmd == MMPLAYER_COMMAND_RESUME || player->cmd == MMPLAYER_COMMAND_PAUSE)) {
-                       LOGE("invalid player command status(%d), __mmplayer_do_change_videosink() is only available with START/RESUME/PAUSE command", player->cmd);
-                       MMPLAYER_FLEAVE();
-                       return MM_ERROR_PLAYER_INVALID_STATE;
-               }
-
-               /* surface change */
-               for (i = 0 ; i < num_of_dec ; i++) {
-                       if (player->pipeline->mainbin &&
-                               player->pipeline->mainbin[MMPLAYER_M_DEC1+i].gst) {
-                               GstElementFactory *decfactory;
-                               decfactory = gst_element_get_factory(player->pipeline->mainbin[MMPLAYER_M_DEC1+i].gst);
-
-                               klass = gst_element_factory_get_metadata(decfactory, GST_ELEMENT_METADATA_KLASS);
-                               if ((g_strrstr(klass, "Codec/Decoder/Video"))) {
-                                       if ((prev_display_surface_type == MM_DISPLAY_SURFACE_OVERLAY) && (surface_type == MM_DISPLAY_SURFACE_REMOTE)) {
-                                               ret = __mmplayer_do_change_videosink(player, MMPLAYER_M_DEC1+i, "fakesink", surface_type, display_overlay);
-                                               if (ret) {
-                                                       goto ERROR_CASE;
-                                               } else {
-                                                       LOGW("success to changing display surface(%d)", surface_type);
-                                                       MMPLAYER_FLEAVE();
-                                                       return MM_ERROR_NONE;
-                                               }
-                                       } else if ((prev_display_surface_type == MM_DISPLAY_SURFACE_REMOTE) && (surface_type == MM_DISPLAY_SURFACE_OVERLAY)) {
-                                               ret = __mmplayer_do_change_videosink(player, MMPLAYER_M_DEC1+i, player->ini.videosink_element_overlay, surface_type, display_overlay);
-                                               if (ret) {
-                                                       goto ERROR_CASE;
-                                               } else {
-                                                       LOGW("success to changing display surface(%d)", surface_type);
-                                                       MMPLAYER_FLEAVE();
-                                                       return MM_ERROR_NONE;
-                                               }
-                                       } else {
-                                               LOGE("invalid incoming surface type(%d) and current videosink_name(%s) for changing display surface", surface_type, cur_videosink_name);
-                                               ret = MM_ERROR_PLAYER_INTERNAL;
-                                               goto ERROR_CASE;
-                                       }
-                               }
-                       }
-               }
-       }
-
-ERROR_CASE:
-       /* rollback to previous attributes */
-       mm_attrs_set_int_by_name(player->attrs, "display_surface_type", prev_display_surface_type);
-       mm_attrs_set_data_by_name(player->attrs, "display_overlay", prev_display_overlay, sizeof(void*));
-       if (mmf_attrs_commit(player->attrs)) {
-               LOGE("failed to commit attributes to rollback");
-               MMPLAYER_FLEAVE();
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-       MMPLAYER_FLEAVE();
-       return ret;
-}
-
-/* NOTE : It does not support some use cases, eg using colorspace converter */
-int
-__mmplayer_do_change_videosink(mm_player_t* player, const int dec_index, const char *videosink_element, MMDisplaySurfaceType surface_type, void *display_overlay)
-{
-       GstPad *src_pad_dec = NULL;
-       GstPad *sink_pad_videosink = NULL;
-       GstPad *sink_pad_videobin = NULL;
-       GstClock *clock = NULL;
-       MMPlayerStateType previous_state = MM_PLAYER_STATE_NUM;
-       int ret = MM_ERROR_NONE;
-       gboolean is_audiobin_created = TRUE;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_COMMON_INVALID_ARGUMENT);
-       MMPLAYER_RETURN_VAL_IF_FAIL(videosink_element, MM_ERROR_COMMON_INVALID_ARGUMENT);
-       MMPLAYER_RETURN_VAL_IF_FAIL(display_overlay, MM_ERROR_COMMON_INVALID_ARGUMENT);
-
-       LOGD("video dec is found(idx:%d), we are going to change videosink to %s", dec_index, videosink_element);
-       LOGD("surface type(%d), display overlay(%x)", surface_type, display_overlay);
-
-       /* get information whether if audiobin is created */
-       if (!player->pipeline->audiobin ||
-                    !player->pipeline->audiobin[MMPLAYER_A_SINK].gst) {
-               LOGW("audiobin is null, this video content may not have audio data");
-               is_audiobin_created = FALSE;
-       }
-
-       /* get current state of player */
-       previous_state = MMPLAYER_CURRENT_STATE(player);
-       LOGD("previous state(%d)", previous_state);
-
-
-       /* get src pad of decoder and block it */
-       src_pad_dec = gst_element_get_static_pad(GST_ELEMENT(player->pipeline->mainbin[dec_index].gst), "src");
-       if (!src_pad_dec) {
-               LOGE("failed to get src pad from decode in mainbin");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       if (!player->doing_seek && previous_state == MM_PLAYER_STATE_PLAYING) {
-               LOGW("trying to block pad(video)");
-//             if (!gst_pad_set_blocked(src_pad_dec, TRUE))
-               gst_pad_add_probe(src_pad_dec, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
-                       NULL, NULL, NULL);
-               {
-                       LOGE("failed to set block pad(video)");
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-               LOGW("pad is blocked(video)");
-       } else {
-               /* no data flows, so no need to do pad_block */
-               if (player->doing_seek)
-                       LOGW("not completed seek(%d), do nothing", player->doing_seek);
-
-               LOGD("MM_PLAYER_STATE is not PLAYING now, skip pad-block(TRUE)");
-       }
-
-       /* remove pad */
-       if (!gst_element_remove_pad(player->pipeline->videobin[MMPLAYER_V_BIN].gst,
-               GST_PAD_CAST(GST_GHOST_PAD(player->ghost_pad_for_videobin)))) {
-               LOGE("failed to remove previous ghost_pad for videobin");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       /* change state of videobin to NULL */
-       LOGD("setting [%s] state to : %d", GST_ELEMENT_NAME(player->pipeline->videobin[MMPLAYER_V_BIN].gst), GST_STATE_NULL);
-       ret = gst_element_set_state(player->pipeline->videobin[MMPLAYER_V_BIN].gst, GST_STATE_NULL);
-       if (ret != GST_STATE_CHANGE_SUCCESS) {
-               LOGE("failed to change state of videobin to NULL");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       /* unlink between decoder and videobin and remove previous videosink from videobin */
-       gst_element_unlink(GST_ELEMENT(player->pipeline->mainbin[dec_index].gst), GST_ELEMENT(player->pipeline->videobin[MMPLAYER_V_BIN].gst));
-       if (!gst_bin_remove(GST_BIN(player->pipeline->videobin[MMPLAYER_V_BIN].gst), GST_ELEMENT(player->pipeline->videobin[MMPLAYER_V_SINK].gst))) {
-               LOGE("failed to remove former videosink from videobin");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       __mmplayer_del_sink(player, player->pipeline->videobin[MMPLAYER_V_SINK].gst);
-
-       /* create a new videosink and add it to videobin */
-       player->pipeline->videobin[MMPLAYER_V_SINK].gst = gst_element_factory_make(videosink_element, "videosink");
-       if (!player->pipeline->videobin[MMPLAYER_V_SINK].gst) {
-               LOGE("failed to create videosink element\n");
-               MMPLAYER_FLEAVE();
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-       gst_bin_add(GST_BIN(player->pipeline->videobin[MMPLAYER_V_BIN].gst), GST_ELEMENT(player->pipeline->videobin[MMPLAYER_V_SINK].gst));
-       __mmplayer_add_sink(player, player->pipeline->videobin[MMPLAYER_V_SINK].gst);
-       g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "qos", TRUE, NULL);
-
-       /* save attributes */
-       if (player->attrs) {
-               /* set a new display surface type */
-               mm_attrs_set_int_by_name(player->attrs, "display_surface_type", surface_type);
-               /* set a new diplay overlay */
-               switch (surface_type) {
-               case MM_DISPLAY_SURFACE_OVERLAY:
-                       LOGD("save attributes related to video display surface : id = %d", *(int*)display_overlay);
-                       mm_attrs_set_data_by_name(player->attrs, "display_overlay", display_overlay, sizeof(display_overlay));
-                       break;
-               default:
-                       LOGE("invalid type(%d) for changing display surface", surface_type);
-                       MMPLAYER_FLEAVE();
-                       return MM_ERROR_INVALID_ARGUMENT;
-               }
-               if (mmf_attrs_commit(player->attrs)) {
-                       LOGE("failed to commit");
-                       MMPLAYER_FLEAVE();
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-       } else {
-               LOGE("player->attrs is null, failed to save attributes");
+       /* 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;
        }
 
-       /* update video param */
-       if (MM_ERROR_NONE != _mmplayer_update_video_param(player, "update_all_param")) {
-               LOGE("failed to update video param");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       /* change state of videobin to READY */
-       LOGD("setting [%s] state to : %d", GST_ELEMENT_NAME(player->pipeline->videobin[MMPLAYER_V_BIN].gst), GST_STATE_READY);
-       ret = gst_element_set_state(player->pipeline->videobin[MMPLAYER_V_BIN].gst, GST_STATE_READY);
-       if (ret != GST_STATE_CHANGE_SUCCESS) {
-               LOGE("failed to change state of videobin to READY");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       /* change ghostpad */
-       sink_pad_videosink = gst_element_get_static_pad(GST_ELEMENT(player->pipeline->videobin[MMPLAYER_V_SINK].gst), "sink");
-       if (!sink_pad_videosink) {
-               LOGE("failed to get sink pad from videosink element");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-       player->ghost_pad_for_videobin = gst_ghost_pad_new("sink", sink_pad_videosink);
-       if (!gst_pad_set_active(player->ghost_pad_for_videobin, TRUE)) {
-               LOGE("failed to set active to ghost_pad");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-       if (FALSE == gst_element_add_pad(player->pipeline->videobin[MMPLAYER_V_BIN].gst, player->ghost_pad_for_videobin)) {
-               LOGE("failed to change ghostpad for videobin");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-       gst_object_unref(sink_pad_videosink);
-
-       /* link decoder with videobin */
-       sink_pad_videobin = gst_element_get_static_pad(GST_ELEMENT(player->pipeline->videobin[MMPLAYER_V_BIN].gst), "sink");
-       if (!sink_pad_videobin) {
-               LOGE("failed to get sink pad from videobin");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-       if (GST_PAD_LINK_OK != gst_pad_link(src_pad_dec, sink_pad_videobin)) {
-               LOGE("failed to link");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-       gst_object_unref(sink_pad_videobin);
-
-       /* clock setting for a new videosink plugin */
-       /* NOTE : Below operation is needed, because a new videosink plugin doesn't have clock for basesink,
-                       so we set it from audiosink plugin or pipeline(system clock) */
-       if (!is_audiobin_created) {
-               LOGW("audiobin is not created, get clock from pipeline..");
-               clock = GST_ELEMENT_CLOCK(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
-       } else {
-               clock = GST_ELEMENT_CLOCK(player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
-       }
-       if (clock) {
-               GstClockTime now;
-               GstClockTime base_time;
-               LOGD("set the clock to videosink");
-               gst_element_set_clock(GST_ELEMENT_CAST(player->pipeline->videobin[MMPLAYER_V_SINK].gst), clock);
-               clock = GST_ELEMENT_CLOCK(player->pipeline->videobin[MMPLAYER_V_SINK].gst);
-               if (clock) {
-                       LOGD("got clock of videosink");
-                       now = gst_clock_get_time(clock);
-                       base_time = GST_ELEMENT_CAST(player->pipeline->videobin[MMPLAYER_V_SINK].gst)->base_time;
-                       LOGD("at time %" GST_TIME_FORMAT ", base %"
-                                       GST_TIME_FORMAT, GST_TIME_ARGS(now), GST_TIME_ARGS(base_time));
-               } else {
-                       LOGE("failed to get clock of videosink after setting clock");
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-       } else
-               LOGW("failed to get clock, maybe it is the time before first playing");
-
-       if (!player->doing_seek && previous_state == MM_PLAYER_STATE_PLAYING) {
-               /* change state of videobin to PAUSED */
-               LOGD("setting [%s] state to : %d", GST_ELEMENT_NAME(player->pipeline->videobin[MMPLAYER_V_BIN].gst), GST_STATE_PLAYING);
-               ret = gst_element_set_state(player->pipeline->videobin[MMPLAYER_V_BIN].gst, GST_STATE_PLAYING);
-               if (ret != GST_STATE_CHANGE_FAILURE) {
-                       LOGW("change state of videobin to PLAYING, ret(%d)", ret);
-               } else {
-                       LOGE("failed to change state of videobin to PLAYING");
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-
-               /* release blocked and unref src pad of video decoder */
-               #if 0
-               if (!gst_pad_set_blocked(src_pad_dec, FALSE)) {
-                       LOGE("failed to set pad blocked FALSE(video)");
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-               #endif
-               LOGW("pad is unblocked(video)");
-       } else {
-               if (player->doing_seek)
-                       LOGW("not completed seek(%d)", player->doing_seek);
-               /* change state of videobin to PAUSED */
-               LOGD("setting [%s] state to : %d", GST_ELEMENT_NAME(player->pipeline->videobin[MMPLAYER_V_BIN].gst), GST_STATE_PAUSED);
-               ret = gst_element_set_state(player->pipeline->videobin[MMPLAYER_V_BIN].gst, GST_STATE_PAUSED);
-               if (ret != GST_STATE_CHANGE_FAILURE) {
-                       LOGW("change state of videobin to PAUSED, ret(%d)", ret);
-               } else {
-                       LOGE("failed to change state of videobin to PLAYING");
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-
-               /* already skipped pad block */
-               LOGD("previous MM_PLAYER_STATE is not PLAYING, skip pad-block(FALSE)");
-       }
-
-       /* do get/set position for new videosink plugin */
-       {
-               unsigned long position = 0;
-               gint64 pos_msec = 0;
-
-               LOGD("do get/set position for new videosink plugin");
-               if (__gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, &position)) {
-                       LOGE("failed to get position");
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-#ifdef SINKCHANGE_WITH_ACCURATE_SEEK
-               /* accurate seek */
-               if (__gst_set_position(player, MM_PLAYER_POS_FORMAT_TIME, position, TRUE)) {
-                       LOGE("failed to set position");
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-#else
-               /* key unit seek */
-               pos_msec = position * G_GINT64_CONSTANT(1000000);
-               ret = __gst_seek(player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, 1.0,
-                               GST_FORMAT_TIME, (GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT),
-                                                       GST_SEEK_TYPE_SET, pos_msec,
-                                                       GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
-               if (!ret) {
-                       LOGE("failed to set position");
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-#endif
-       }
-
-       if (src_pad_dec)
-               gst_object_unref(src_pad_dec);
-       LOGD("success to change sink");
-
        MMPLAYER_FLEAVE();
-
        return MM_ERROR_NONE;
 }
 
-
 /* Note : if silent is true, then subtitle would not be displayed. :*/
-int _mmplayer_set_subtitle_silent(MMHandleType hplayer, int silent)
+int
+_mmplayer_set_subtitle_silent(MMHandleType hplayer, int silent)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
 
@@ -12469,17 +7962,18 @@ int _mmplayer_set_subtitle_silent(MMHandleType hplayer, int silent)
 
        player->set_mode.subtitle_off = silent;
 
-       LOGD("subtitle is %s.\n", player->set_mode.subtitle_off ? "ON" : "OFF");
+       LOGD("subtitle is %s.", player->set_mode.subtitle_off ? "ON" : "OFF");
 
        MMPLAYER_FLEAVE();
 
        return MM_ERROR_NONE;
 }
 
-int _mmplayer_sync_subtitle_pipeline(mm_player_t* player)
+int
+_mmplayer_sync_subtitle_pipeline(mmplayer_t *player)
 {
-       MMPlayerGstElement* mainbin = NULL;
-       MMPlayerGstElement* textbin = NULL;
+       mmplayer_gst_element_t *mainbin = NULL;
+       mmplayer_gst_element_t *textbin = NULL;
        GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
        GstState current_state = GST_STATE_VOID_PENDING;
        GstState element_state = GST_STATE_VOID_PENDING;
@@ -12523,12 +8017,11 @@ int _mmplayer_sync_subtitle_pipeline(mm_player_t* player)
 
                ret = gst_element_get_state(mainbin[MMPLAYER_M_SUBSRC].gst, &element_state, &element_pending_state, 5 * GST_SECOND);
                if (GST_STATE_CHANGE_FAILURE == ret) {
-                       LOGE("fail to state change.\n");
+                       LOGE("fail to state change.");
                        result = MM_ERROR_PLAYER_INTERNAL;
                        goto ERROR;
                }
        }
-
        gst_element_set_base_time(textbin[MMPLAYER_T_BIN].gst, base_time);
        gst_element_set_start_time(textbin[MMPLAYER_T_BIN].gst, start_time);
 
@@ -12540,14 +8033,14 @@ int _mmplayer_sync_subtitle_pipeline(mm_player_t* player)
        // seek to current position
        if (!gst_element_query_position(mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &time)) {
                result = MM_ERROR_PLAYER_INVALID_STATE;
-               LOGE("gst_element_query_position failed, invalid state\n");
+               LOGE("gst_element_query_position failed, invalid state");
                goto ERROR;
        }
 
-       LOGD("seek time = %lld, rate = %f\n", time, player->playback_rate);
+       LOGD("seek time = %"G_GINT64_FORMAT", rate = %f", time, player->playback_rate);
        event = gst_event_new_seek(player->playback_rate, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_FLUSH), GST_SEEK_TYPE_SET, time, GST_SEEK_TYPE_NONE, -1);
        if (event) {
-               __gst_send_event_to_sink(player, event);
+               __mmplayer_gst_send_event_to_sink(player, event);
        } else {
                result = MM_ERROR_PLAYER_INTERNAL;
                LOGE("gst_event_new_seek failed"); /* pipeline will got error and can not be recovered */
@@ -12581,16 +8074,16 @@ ERROR:
 }
 
 static int
-__mmplayer_change_external_subtitle_language(mm_player_t* player, const char* filepath)
+__mmplayer_change_external_subtitle_language(mmplayer_t *player, const char *filepath)
 {
        GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
        GstState current_state = GST_STATE_VOID_PENDING;
 
        MMHandleType attrs = 0;
-       MMPlayerGstElement* mainbin = NULL;
-       MMPlayerGstElement* textbin = NULL;
+       mmplayer_gst_element_t *mainbin = NULL;
+       mmplayer_gst_element_t *textbin = NULL;
 
-       gcharsubtitle_uri = NULL;
+       gchar *subtitle_uri = NULL;
        int result = MM_ERROR_NONE;
        const gchar *charset = NULL;
 
@@ -12609,20 +8102,20 @@ __mmplayer_change_external_subtitle_language(mm_player_t* player, const char* fi
        current_state = GST_STATE(mainbin[MMPLAYER_M_PIPE].gst);
        if (current_state < GST_STATE_READY) {
                result = MM_ERROR_PLAYER_INVALID_STATE;
-               LOGE("Pipeline is not in proper state\n");
+               LOGE("Pipeline is not in proper state");
                goto EXIT;
        }
 
        attrs = MMPLAYER_GET_ATTRS(player);
        if (!attrs) {
-               LOGE("cannot get content attribute\n");
+               LOGE("cannot get content attribute");
                result = MM_ERROR_PLAYER_INTERNAL;
                goto EXIT;
        }
 
        mm_attrs_get_string_by_name(attrs, "subtitle_uri", &subtitle_uri);
        if (!subtitle_uri || strlen(subtitle_uri) < 1) {
-               LOGE("subtitle uri is not proper filepath\n");
+               LOGE("subtitle uri is not proper filepath");
                result = MM_ERROR_PLAYER_INVALID_URI;
                goto EXIT;
        }
@@ -12633,16 +8126,16 @@ __mmplayer_change_external_subtitle_language(mm_player_t* player, const char* fi
                goto EXIT;
        }
 
-       LOGD("old subtitle file path is [%s]\n", subtitle_uri);
-       LOGD("new subtitle file path is [%s]\n", filepath);
+       LOGD("old subtitle file path is [%s]", subtitle_uri);
+       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\n");
+               LOGD("No need to swtich subtitle, as input filepath is same as current filepath");
                goto EXIT;
        } else {
                mm_attrs_set_string_by_name(player->attrs, "subtitle_uri", filepath);
-               if (mmf_attrs_commit(player->attrs)) {
-                       LOGE("failed to commit.\n");
+               if (mm_attrs_commit_all(player->attrs)) {
+                       LOGE("failed to commit.");
                        goto EXIT;
                }
        }
@@ -12679,7 +8172,7 @@ __mmplayer_change_external_subtitle_language(mm_player_t* player, const char* fi
 
        charset = util_get_charset(filepath);
        if (charset) {
-               LOGD("detected charset is %s\n", charset);
+               LOGD("detected charset is %s", charset);
                g_object_set(G_OBJECT(mainbin[MMPLAYER_M_SUBPARSE].gst), "subtitle-encoding", charset, NULL);
        }
 
@@ -12691,10 +8184,11 @@ EXIT:
 }
 
 /* API to switch between external subtitles */
-int _mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char* filepath)
+int
+_mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char *filepath)
 {
        int result = MM_ERROR_NONE;
-       mm_player_t* player = (mm_player_t*)hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
        char *path = NULL;
 
        MMPLAYER_FENTER();
@@ -12719,7 +8213,7 @@ int _mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char* filep
        if (!player->pipeline) {
                /* IDLE state */
                mm_attrs_set_string_by_name(player->attrs, "subtitle_uri", filepath);
-               if (mmf_attrs_commit(player->attrs)) {
+               if (mm_attrs_commit_all(player->attrs)) {
                        LOGE("failed to commit");       /* subtitle path will not be created */
                        return MM_ERROR_PLAYER_INTERNAL;
                }
@@ -12730,7 +8224,7 @@ int _mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char* filep
 
                if (!__mmplayer_check_subtitle(player)) {
                        mm_attrs_set_string_by_name(player->attrs, "subtitle_uri", filepath);
-                       if (mmf_attrs_commit(player->attrs)) {
+                       if (mm_attrs_commit_all(player->attrs)) {
                                LOGE("failed to commit");
                                return MM_ERROR_PLAYER_INTERNAL;
                        }
@@ -12762,14 +8256,14 @@ int _mmplayer_set_external_subtitle_path(MMHandleType hplayer, const char* filep
 }
 
 static int
-__mmplayer_change_selector_pad(mm_player_t* player, MMPlayerTrackType type, int index)
+__mmplayer_change_selector_pad(mmplayer_t *player, mmplayer_track_type_e type, int index)
 {
        int result = MM_ERROR_NONE;
-       gcharchange_pad_name = NULL;
-       GstPadsinkpad = NULL;
-       MMPlayerGstElement* mainbin = NULL;
-       enum MainElementID elemId = MMPLAYER_M_NUM;
-       GstCapscaps = NULL;
+       gchar *change_pad_name = NULL;
+       GstPad *sinkpad = NULL;
+       mmplayer_gst_element_t *mainbin = NULL;
+       main_element_id_e elem_idx = MMPLAYER_M_NUM;
+       GstCaps *caps = NULL;
        gint total_track_num = 0;
 
        MMPLAYER_FENTER();
@@ -12777,36 +8271,36 @@ __mmplayer_change_selector_pad(mm_player_t* player, MMPlayerTrackType type, int
        MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline && player->pipeline->mainbin,
                                                                                                        MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       LOGD("Change Track(%d) to %d\n", type, index);
+       LOGD("Change Track(%d) to %d", type, index);
 
        mainbin = player->pipeline->mainbin;
 
        if (type == MM_PLAYER_TRACK_TYPE_AUDIO) {
-               elemId = MMPLAYER_M_A_INPUT_SELECTOR;
+               elem_idx = MMPLAYER_M_A_INPUT_SELECTOR;
        } else if (type == MM_PLAYER_TRACK_TYPE_TEXT) {
-               elemId = MMPLAYER_M_T_INPUT_SELECTOR;
+               elem_idx = MMPLAYER_M_T_INPUT_SELECTOR;
        } else {
                /* Changing Video Track is not supported. */
-               LOGE("Track Type Error\n");
+               LOGE("Track Type Error");
                goto EXIT;
        }
 
-       if (mainbin[elemId].gst == NULL) {
+       if (mainbin[elem_idx].gst == NULL) {
                result = MM_ERROR_PLAYER_NO_OP;
-               LOGD("Req track doesn't exist\n");
+               LOGD("Req track doesn't exist");
                goto EXIT;
        }
 
        total_track_num = player->selector[type].total_track_num;
        if (total_track_num <= 0) {
                result = MM_ERROR_PLAYER_NO_OP;
-               LOGD("Language list is not available \n");
+               LOGD("Language list is not available");
                goto EXIT;
        }
 
        if ((index < 0) || (index >= total_track_num)) {
                result = MM_ERROR_INVALID_ARGUMENT;
-               LOGD("Not a proper index : %d \n", index);
+               LOGD("Not a proper index : %d", index);
                goto EXIT;
        }
 
@@ -12814,21 +8308,21 @@ __mmplayer_change_selector_pad(mm_player_t* player, MMPlayerTrackType type, int
        change_pad_name = g_strdup_printf("sink_%u", index);
        if (change_pad_name == NULL) {
                result = MM_ERROR_PLAYER_INTERNAL;
-               LOGD("Pad does not exists\n");
+               LOGD("Pad does not exists");
                goto EXIT;
        }
 
-       LOGD("new active pad name: %s\n", change_pad_name);
+       LOGD("new active pad name: %s", change_pad_name);
 
-       sinkpad = gst_element_get_static_pad(mainbin[elemId].gst, change_pad_name);
+       sinkpad = gst_element_get_static_pad(mainbin[elem_idx].gst, change_pad_name);
        if (sinkpad == NULL) {
                LOGD("sinkpad is NULL");
                result = MM_ERROR_PLAYER_INTERNAL;
                goto EXIT;
        }
 
-       LOGD("Set Active Pad - %s:%s\n", GST_DEBUG_PAD_NAME(sinkpad));
-       g_object_set(mainbin[elemId].gst, "active-pad", sinkpad, NULL);
+       LOGD("Set Active Pad - %s:%s", GST_DEBUG_PAD_NAME(sinkpad));
+       g_object_set(mainbin[elem_idx].gst, "active-pad", sinkpad, NULL);
 
        caps = gst_pad_get_current_caps(sinkpad);
        MMPLAYER_LOG_GST_CAPS_TYPE(caps);
@@ -12840,973 +8334,1203 @@ __mmplayer_change_selector_pad(mm_player_t* player, MMPlayerTrackType type, int
                __mmplayer_set_audio_attrs(player, caps);
 
 EXIT:
-
        MMPLAYER_FREEIF(change_pad_name);
        return result;
 }
 
-int _mmplayer_change_track_language(MMHandleType hplayer, MMPlayerTrackType type, int index)
+int
+_mmplayer_change_track_language(MMHandleType hplayer, mmplayer_track_type_e type, int index)
 {
        int result = MM_ERROR_NONE;
-       mm_player_t* player = NULL;
-       MMPlayerGstElement* mainbin = NULL;
+       mmplayer_t *player = NULL;
+       mmplayer_gst_element_t *mainbin = NULL;
 
        gint current_active_index = 0;
 
        GstState current_state = GST_STATE_VOID_PENDING;
-       GstEventevent = NULL;
+       GstEvent *event = NULL;
        gint64 time = 0;
 
        MMPLAYER_FENTER();
 
-       player = (mm_player_t*)hplayer;
+       player = (mmplayer_t *)hplayer;
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
        if (!player->pipeline) {
-               LOGE("Track %d pre setting -> %d\n", type, index);
+               LOGE("Track %d pre setting -> %d", type, index);
+
+               player->selector[type].active_pad_index = index;
+               goto EXIT;
+       }
+
+       mainbin = player->pipeline->mainbin;
+
+       current_active_index = player->selector[type].active_pad_index;
+
+       /*If index is same as running index no need to change the pad*/
+       if (current_active_index == index)
+               goto EXIT;
+
+       if (!gst_element_query_position(mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &time)) {
+               result = MM_ERROR_PLAYER_INVALID_STATE;
+               goto EXIT;
+       }
+
+       current_state = GST_STATE(mainbin[MMPLAYER_M_PIPE].gst);
+       if (current_state < GST_STATE_PAUSED) {
+               result = MM_ERROR_PLAYER_INVALID_STATE;
+               LOGW("Pipeline not in porper state");
+               goto EXIT;
+       }
+
+       result = __mmplayer_change_selector_pad(player, type, index);
+       if (result != MM_ERROR_NONE) {
+               LOGE("change selector pad error");
+               goto EXIT;
+       }
+
+       player->selector[type].active_pad_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;
+               }
+       }
+
+EXIT:
+       return result;
+}
+
+int
+_mmplayer_get_subtitle_silent(MMHandleType hplayer, int *silent)
+{
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+
+       MMPLAYER_FENTER();
+
+       /* check player handle */
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       *silent = player->set_mode.subtitle_off;
+
+       LOGD("subtitle is %s.", silent ? "ON" : "OFF");
+
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
+
+static gboolean
+__mmplayer_add_dump_buffer_probe(mmplayer_t *player, GstElement *element)
+{
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+       MMPLAYER_RETURN_VAL_IF_FAIL(element, FALSE);
+
+       gchar *factory_name = GST_OBJECT_NAME(gst_element_get_factory(element));
+       gchar dump_file_name[PLAYER_INI_MAX_STRLEN*2];
+
+       int idx = 0;
+
+       for (idx = 0; player->ini.dump_element_keyword[idx][0] != '\0'; idx++) {
+               if (g_strrstr(factory_name, player->ini.dump_element_keyword[idx])) {
+                       LOGD("dump [%s] sink pad", player->ini.dump_element_keyword[idx]);
+                       mmplayer_dump_t *dump_s;
+                       dump_s = g_try_malloc(sizeof(mmplayer_dump_t));
+                       if (dump_s == NULL) {
+                               LOGE("malloc fail");
+                               return FALSE;
+                       }
+
+                       dump_s->dump_element_file = NULL;
+                       dump_s->dump_pad = NULL;
+                       dump_s->dump_pad = gst_element_get_static_pad(element, "sink");
+
+                       if (dump_s->dump_pad) {
+                               memset(dump_file_name, 0x00, PLAYER_INI_MAX_STRLEN * 2);
+                               snprintf(dump_file_name, PLAYER_INI_MAX_STRLEN * 2, "%s/%s_sink_pad.dump", player->ini.dump_element_path, player->ini.dump_element_keyword[idx]);
+                               dump_s->dump_element_file = fopen(dump_file_name, "w+");
+                               dump_s->probe_handle_id = gst_pad_add_probe(dump_s->dump_pad, GST_PAD_PROBE_TYPE_BUFFER, __mmplayer_dump_buffer_probe_cb, dump_s->dump_element_file, NULL);
+                               /* add list for removed buffer probe and close FILE */
+                               player->dump_list = g_list_append(player->dump_list, dump_s);
+                               LOGD("%s sink pad added buffer probe for dump", factory_name);
+                               return TRUE;
+                       } else {
+                               MMPLAYER_FREEIF(dump_s);
+                               LOGE("failed to get %s sink pad added", factory_name);
+                       }
+               }
+       }
+       return FALSE;
+}
+
+static GstPadProbeReturn
+__mmplayer_dump_buffer_probe_cb(GstPad *pad,  GstPadProbeInfo *info, gpointer u_data)
+{
+       FILE *dump_data = (FILE *)u_data;
+//     int written = 0;
+       GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
+       GstMapInfo probe_info = GST_MAP_INFO_INIT;
 
-               player->selector[type].active_pad_index = index;
-               goto EXIT;
-       }
+       MMPLAYER_RETURN_VAL_IF_FAIL(dump_data, GST_PAD_PROBE_PASS);
 
-       mainbin = player->pipeline->mainbin;
+       gst_buffer_map(buffer, &probe_info, GST_MAP_READ);
 
-       current_active_index = player->selector[type].active_pad_index;
+//     LOGD("buffer timestamp = %" GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
 
-       /*If index is same as running index no need to change the pad*/
-       if (current_active_index == index)
-               goto EXIT;
+       fwrite(probe_info.data, 1, probe_info.size , dump_data);
 
-       if (!gst_element_query_position(mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &time)) {
-               result = MM_ERROR_PLAYER_INVALID_STATE;
-               goto EXIT;
-       }
+       gst_buffer_unmap(buffer, &probe_info);
 
-       current_state = GST_STATE(mainbin[MMPLAYER_M_PIPE].gst);
-       if (current_state < GST_STATE_PAUSED) {
-               result = MM_ERROR_PLAYER_INVALID_STATE;
-               LOGW("Pipeline not in porper state\n");
-               goto EXIT;
-       }
+       return GST_PAD_PROBE_OK;
+}
 
-       result = __mmplayer_change_selector_pad(player, type, index);
-       if (result != MM_ERROR_NONE) {
-               LOGE("change selector pad error\n");
-               goto EXIT;
-       }
+static void
+__mmplayer_release_dump_list(GList *dump_list)
+{
+       GList *d_list = dump_list;
 
-       player->selector[type].active_pad_index = index;
+       if (!d_list)
+               return;
 
-       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) {
-                       __gst_send_event_to_sink(player, event);
-               } else {
-                       result = MM_ERROR_PLAYER_INTERNAL;
-                       goto EXIT;
+       for (; d_list; d_list = g_list_next(d_list)) {
+               mmplayer_dump_t *dump_s = d_list->data;
+               if (dump_s->dump_pad) {
+                       if (dump_s->probe_handle_id)
+                               gst_pad_remove_probe(dump_s->dump_pad, dump_s->probe_handle_id);
+                       gst_object_unref(GST_OBJECT(dump_s->dump_pad));
+               }
+               if (dump_s->dump_element_file) {
+                       fclose(dump_s->dump_element_file);
+                       dump_s->dump_element_file = NULL;
                }
+               MMPLAYER_FREEIF(dump_s);
        }
-
-EXIT:
-       return result;
+       g_list_free(dump_list);
+       dump_list = NULL;
 }
 
-int _mmplayer_get_subtitle_silent(MMHandleType hplayer, int* silent)
+int
+_mmplayer_has_closed_caption(MMHandleType hplayer, bool *exist)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
 
-       /* check player handle */
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(exist, MM_ERROR_INVALID_ARGUMENT);
 
-       *silent = player->set_mode.subtitle_off;
-
-       LOGD("subtitle is %s.\n", silent ? "ON" : "OFF");
+       *exist = (bool)player->has_closed_caption;
 
        MMPLAYER_FLEAVE();
 
        return MM_ERROR_NONE;
 }
 
-gboolean
-__is_ms_buff_src(mm_player_t* player)
-{
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-
-       return (player->profile.uri_type == MM_PLAYER_URI_TYPE_MS_BUFF) ? TRUE : FALSE;
-}
-
-gboolean
-__has_suffix(mm_player_t* player, const gchar* suffix)
+void
+_mm_player_video_stream_internal_buffer_unref(void *buffer)
 {
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL(suffix, FALSE);
-
-       gboolean ret = FALSE;
-       gchar* t_url = g_ascii_strdown(player->profile.uri, -1);
-       gchar* t_suffix = g_ascii_strdown(suffix, -1);
-
-       if (g_str_has_suffix(player->profile.uri, suffix))
-               ret = TRUE;
-
-       MMPLAYER_FREEIF(t_url);
-       MMPLAYER_FREEIF(t_suffix);
-
-       return ret;
+       MMPLAYER_FENTER();
+       if (buffer) {
+               // LOGD("unref internal gst buffer %p", buffer);
+               gst_buffer_unref((GstBuffer *)buffer);
+               buffer = NULL;
+       }
+       MMPLAYER_FLEAVE();
 }
 
 int
-_mmplayer_set_video_hub_download_mode(MMHandleType hplayer, bool mode)
+_mmplayer_get_timeout(MMHandleType hplayer, int *timeout)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+
+       MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(timeout, MM_ERROR_COMMON_INVALID_ARGUMENT);
 
-       if (MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_NULL) {
-               MMPLAYER_PRINT_STATE(player);
-               LOGE("wrong-state : can't set the download mode to parse");
-               return MM_ERROR_PLAYER_INVALID_STATE;
-       }
+       if (MMPLAYER_IS_STREAMING(player))
+               *timeout = (int)player->ini.live_state_change_timeout;
+       else
+               *timeout = (int)player->ini.localplayback_state_change_timeout;
 
-       LOGD("set video hub download mode to %s", (mode) ? "ON" : "OFF");
-       player->video_hub_download_mode = mode;
+       LOGD("timeout = %d", *timeout);
 
+       MMPLAYER_FLEAVE();
        return MM_ERROR_NONE;
 }
 
 int
-_mmplayer_enable_sync_handler(MMHandleType hplayer, bool enable)
+_mmplayer_get_num_of_video_out_buffers(MMHandleType hplayer, int *num, int *extra_num)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       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);
 
-       LOGD("enable sync handler : %s", (enable) ? "ON" : "OFF");
-       player->sync_handler = enable;
+       *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;
 }
 
-int
-_mmplayer_set_video_share_master_clock(MMHandleType hplayer,
-                                       long long clock,
-                                       long long clock_delta,
-                                       long long video_time,
-                                       long long media_clock,
-                                       long long audio_time)
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       MMPlayerGstElement* mainbin = NULL;
-       GstClockTime start_time_audio = 0, start_time_video = 0;
-       GstClockTimeDiff base_time = 0, new_base_time = 0;
-       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
-       gint64 api_delta = 0;
-       gint64 position = 0, position_delta = 0;
-       gint64 adj_base_time = 0;
-       GstClock *curr_clock = NULL;
-       GstClockTime curr_time = 0;
-       gboolean query_ret = TRUE;
-       int result = MM_ERROR_NONE;
-
+static void
+__mmplayer_initialize_storage_info(mmplayer_t *player, mmplayer_path_type_e path_type)
+{
+       int i = 0;
        MMPLAYER_FENTER();
+       MMPLAYER_RETURN_IF_FAIL(player);
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       for (i = 0; i < MMPLAYER_PATH_MAX; i++) {
 
-       // LOGD("in(us) : %lld, %lld, %lld, %lld, %lld", clock, clock_delta, video_time, media_clock, audio_time);
+               if (path_type == MMPLAYER_PATH_MAX || path_type == i) {
+                       player->storage_info[i].type = STORAGE_TYPE_INTERNAL;
+                       player->storage_info[i].state = STORAGE_STATE_UNMOUNTABLE;
+                       player->storage_info[i].id = -1;
+                       memset(player->storage_info[i].path, 0x00, MM_MAX_URL_LEN);
 
-       if ((video_time < 0) || (player->doing_seek)) {
-               LOGD("skip setting master clock.  %lld", video_time);
-               goto EXIT;
+                       if (path_type != MMPLAYER_PATH_MAX)
+                               break;
+               }
        }
 
-       mainbin = player->pipeline->mainbin;
-
-       curr_clock = gst_pipeline_get_clock(GST_PIPELINE_CAST(mainbin[MMPLAYER_M_PIPE].gst));
-       curr_time = gst_clock_get_time(curr_clock);
-
-       current_state = MMPLAYER_CURRENT_STATE(player);
-
-       if (current_state == MM_PLAYER_STATE_PLAYING)
-               query_ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &position);
+       MMPLAYER_FLEAVE();
+}
 
-       if ((current_state != MM_PLAYER_STATE_PLAYING) ||
-               (!query_ret)) {
-               position = player->last_position;
-               LOGD("query fail. %lld", position);
-       }
+int
+_mmplayer_manage_external_storage_state(MMHandleType hplayer, int id, int state)
+{
+       int ret = MM_ERROR_NONE;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       MMMessageParamType msg_param = {0, };
 
-       clock *= GST_USECOND;
-       clock_delta *= GST_USECOND;
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       api_delta = clock - curr_time;
-       if ((player->video_share_api_delta == 0) || (player->video_share_api_delta > api_delta))
-               player->video_share_api_delta = api_delta;
-       else
-               clock_delta += (api_delta - player->video_share_api_delta);
+       LOGW("state changed storage %d:%d", id, state);
 
-       if ((player->video_share_clock_delta == 0) || (player->video_share_clock_delta > clock_delta)) {
-               player->video_share_clock_delta = (gint64)clock_delta;
+       if (state != STORAGE_STATE_UNMOUNTABLE && state != STORAGE_STATE_REMOVED)
+               return MM_ERROR_NONE;
 
-               position_delta = (position/GST_USECOND) - video_time;
-               position_delta *= GST_USECOND;
+       /* FIXME: text path should be handled seperately. */
+       if (((player->storage_info[MMPLAYER_PATH_VOD].type == STORAGE_TYPE_EXTERNAL)
+               && (player->storage_info[MMPLAYER_PATH_VOD].id == id)) ||
+               ((player->storage_info[MMPLAYER_PATH_TEXT].type == STORAGE_TYPE_EXTERNAL)
+               && (player->storage_info[MMPLAYER_PATH_TEXT].id == id))) {
+               LOGW("external storage is removed");
 
-               adj_base_time = position_delta;
-               LOGD("video_share_clock_delta = %lld, adj = %lld", player->video_share_clock_delta, adj_base_time);
+               if (player->msg_posted == FALSE) {
+                       memset(&msg_param, 0, sizeof(MMMessageParamType));
+                       msg_param.code = MM_ERROR_PLAYER_INVALID_URI;
+                       MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
+                       player->msg_posted = TRUE;
+               }
 
-       } else {
-               gint64 new_play_time = 0;
-               gint64 network_delay = 0;
+               /* unrealize the player */
+               ret = _mmplayer_unrealize(hplayer);
+               if (ret != MM_ERROR_NONE)
+                       LOGE("failed to unrealize");
+       }
 
-               video_time *= GST_USECOND;
+       MMPLAYER_FLEAVE();
+       return ret;
+}
 
-               network_delay = clock_delta - player->video_share_clock_delta;
-               new_play_time = video_time + network_delay;
+int
+_mmplayer_get_adaptive_variant_info(MMHandleType hplayer, int *num, char **var_info)
+{
+       int ret = MM_ERROR_NONE;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       int idx = 0, total = 0;
+       gchar *result = NULL, *tmp = NULL;
 
-               adj_base_time = position - new_play_time;
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(num && var_info, MM_ERROR_COMMON_INVALID_ARGUMENT);
 
-               LOGD("%lld(delay) = %lld - %lld / %lld(adj) = %lld(slave_pos) - %lld(master_pos) - %lld(delay)",
-                       network_delay, clock_delta, player->video_share_clock_delta, adj_base_time, position, video_time, network_delay);
+       total = *num = g_list_length(player->adaptive_info.var_list);
+       if (total <= 0) {
+               LOGW("There is no stream variant info.");
+               return ret;
        }
 
-       /* Adjust Current Stream Time with base_time of sink
-        * 1. Set Start time to CLOCK NONE, to control the base time by MSL
-        * 2. Set new base time
-        *    if adj_base_time is positive value, the stream time will be decreased.
-        * 3. If seek event is occurred, the start time will be reset. */
-       if ((player->pipeline->audiobin) &&
-               (player->pipeline->audiobin[MMPLAYER_A_SINK].gst)) {
-               start_time_audio = gst_element_get_start_time(player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
-
-               if (start_time_audio != GST_CLOCK_TIME_NONE) {
-                       LOGD("audio sink : gst_element_set_start_time -> NONE");
-                       gst_element_set_start_time(player->pipeline->audiobin[MMPLAYER_A_SINK].gst, GST_CLOCK_TIME_NONE);
-               }
-
-               base_time = gst_element_get_base_time(player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
-       }
+       result = g_strdup("");
+       for (idx = 0 ; idx < total ; idx++) {
+               stream_variant_t *v_data = NULL;
+               v_data = g_list_nth_data(player->adaptive_info.var_list, idx);
 
-       if ((player->pipeline->videobin) &&
-               (player->pipeline->videobin[MMPLAYER_V_SINK].gst)) {
-               start_time_video = gst_element_get_start_time(player->pipeline->videobin[MMPLAYER_V_SINK].gst);
+               if (v_data) {
+                       gchar data[64] = {0};
+                       snprintf(data, sizeof(data), "%d,%d,%d,", v_data->bandwidth, v_data->width, v_data->height);
 
-               if (start_time_video != GST_CLOCK_TIME_NONE) {
-                       LOGD("video sink : gst_element_set_start_time -> NONE");
-                       gst_element_set_start_time(player->pipeline->videobin[MMPLAYER_V_SINK].gst, GST_CLOCK_TIME_NONE);
+                       tmp = g_strconcat(result, data, NULL);
+                       g_free(result);
+                       result = tmp;
+               } else {
+                       LOGW("There is no variant data in %d", idx);
+                       (*num)--;
                }
-
-               // if videobin exist, get base_time from videobin.
-               base_time = gst_element_get_base_time(player->pipeline->videobin[MMPLAYER_V_SINK].gst);
        }
 
-       new_base_time = base_time + adj_base_time;
-
-       if ((player->pipeline->audiobin) &&
-               (player->pipeline->audiobin[MMPLAYER_A_SINK].gst))
-               gst_element_set_base_time(GST_ELEMENT_CAST(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), (GstClockTime)new_base_time);
-
-       if ((player->pipeline->videobin) &&
-               (player->pipeline->videobin[MMPLAYER_V_SINK].gst))
-               gst_element_set_base_time(GST_ELEMENT_CAST(player->pipeline->videobin[MMPLAYER_V_SINK].gst), (GstClockTime)new_base_time);
+       *var_info = (char *)result;
 
-EXIT:
+       LOGD("variant info %d:%s", *num, *var_info);
        MMPLAYER_FLEAVE();
-
-       return result;
+       return ret;
 }
 
 int
-_mmplayer_get_video_share_master_clock(MMHandleType hplayer,
-                                       long long *video_time,
-                                       long long *media_clock,
-                                       long long *audio_time)
+_mmplayer_set_max_adaptive_variant_limit(MMHandleType hplayer, int bandwidth, int width, int height)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
-       MMPlayerGstElement* mainbin = NULL;
-       GstClock *curr_clock = NULL;
-       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
-       gint64 position = 0;
-       gboolean query_ret = TRUE;
+       int ret = MM_ERROR_NONE;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
        MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->mainbin, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       LOGD("set limit to [b]%d, [w]%d, [h]%d", bandwidth, width, height);
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(video_time, MM_ERROR_COMMON_INVALID_ARGUMENT);
-       MMPLAYER_RETURN_VAL_IF_FAIL(media_clock, MM_ERROR_COMMON_INVALID_ARGUMENT);
-       MMPLAYER_RETURN_VAL_IF_FAIL(audio_time, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       player->adaptive_info.limit.bandwidth = (bandwidth >= ADAPTIVE_VARIANT_DEFAULT_VALUE) ? (bandwidth) : (ADAPTIVE_VARIANT_DEFAULT_VALUE);
+       player->adaptive_info.limit.width = (width >= ADAPTIVE_VARIANT_DEFAULT_VALUE) ? (width) : (ADAPTIVE_VARIANT_DEFAULT_VALUE);
+       player->adaptive_info.limit.height = (height >= ADAPTIVE_VARIANT_DEFAULT_VALUE) ? (height) : (ADAPTIVE_VARIANT_DEFAULT_VALUE);
 
-       mainbin = player->pipeline->mainbin;
+       if (player->pipeline && player->pipeline->mainbin && player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst) {
+               LOGD("update max limit of %s", GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst));
+               g_object_set(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst,
+                                               "max-bandwidth", bandwidth, "max-video-width", width, "max-video-height", height, NULL);
 
-       curr_clock = gst_pipeline_get_clock(GST_PIPELINE_CAST(mainbin[MMPLAYER_M_PIPE].gst));
+               /* FIXME: seek to current position for applying new variant limitation */
+       }
 
-       current_state = MMPLAYER_CURRENT_STATE(player);
+       MMPLAYER_FLEAVE();
+       return ret;
 
-       if (current_state != MM_PLAYER_STATE_PAUSED)
-               query_ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &position);
+}
 
-       if ((current_state == MM_PLAYER_STATE_PAUSED) ||
-               (!query_ret))
-               position = player->last_position;
+int
+_mmplayer_get_max_adaptive_variant_limit(MMHandleType hplayer, int *bandwidth, int *width, int *height)
+{
+       int ret = MM_ERROR_NONE;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
-       *media_clock = *video_time = *audio_time = (position/GST_USECOND);
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(bandwidth && width && height, MM_ERROR_COMMON_INVALID_ARGUMENT);
 
-       LOGD("media_clock: %lld, video_time: %lld(us)", *media_clock, *video_time);
+       *bandwidth = player->adaptive_info.limit.bandwidth;
+       *width = player->adaptive_info.limit.width;
+       *height = player->adaptive_info.limit.height;
 
-       if (curr_clock)
-               gst_object_unref(curr_clock);
+       LOGD("get limit to [b]%d, [w]%d, [h]%d", *bandwidth, *width, *height);
 
        MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
+       return ret;
 }
 
-static gboolean
-__mmplayer_add_dump_buffer_probe(mm_player_t *player, GstElement *element)
+int
+_mmplayer_get_streaming_buffering_time(MMHandleType hplayer, int *prebuffer_ms, int *rebuffer_ms)
 {
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
-       MMPLAYER_RETURN_VAL_IF_FAIL(element, FALSE);
-
-       gchar *factory_name = GST_OBJECT_NAME(gst_element_get_factory(element));
-       gchar dump_file_name[PLAYER_INI_MAX_STRLEN*2];
-
-       int idx = 0;
-
-       for (idx = 0; player->ini.dump_element_keyword[idx][0] != '\0'; idx++) {
-               if (g_strrstr(factory_name, player->ini.dump_element_keyword[idx])) {
-                       LOGD("dump [%s] sink pad", player->ini.dump_element_keyword[idx]);
-                       mm_player_dump_t *dump_s;
-                       dump_s = g_malloc(sizeof(mm_player_dump_t));
+       int ret = MM_ERROR_NONE;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
 
-                       if (dump_s == NULL) {
-                               LOGE("malloc fail");
-                               return FALSE;
-                       }
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player && player->streamer, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(prebuffer_ms && rebuffer_ms, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       MMPLAYER_RETURN_VAL_IF_FAIL(MMPLAYER_IS_STREAMING(player), MM_ERROR_PLAYER_NO_OP);
 
-                       dump_s->dump_element_file = NULL;
-                       dump_s->dump_pad = NULL;
-                       dump_s->dump_pad = gst_element_get_static_pad(element, "sink");
+       *prebuffer_ms = player->streamer->buffering_req.prebuffer_time;
 
-                       if (dump_s->dump_pad) {
-                               memset(dump_file_name, 0x00, PLAYER_INI_MAX_STRLEN*2);
-                               snprintf(dump_file_name, PLAYER_INI_MAX_STRLEN*2, "%s/%s_sink_pad.dump", player->ini.dump_element_path, player->ini.dump_element_keyword[idx]);
-                               dump_s->dump_element_file = fopen(dump_file_name, "w+");
-                               dump_s->probe_handle_id = gst_pad_add_probe(dump_s->dump_pad, GST_PAD_PROBE_TYPE_BUFFER, __mmplayer_dump_buffer_probe_cb, dump_s->dump_element_file, NULL);
-                               /* add list for removed buffer probe and close FILE */
-                               player->dump_list = g_list_append(player->dump_list, dump_s);
-                               LOGD("%s sink pad added buffer probe for dump", factory_name);
-                               return TRUE;
-                       } else {
-                               g_free(dump_s);
-                               dump_s = NULL;
-                               LOGE("failed to get %s sink pad added", factory_name);
-                       }
+       if (player->streamer->buffering_req.rebuffer_time > MIN_BUFFERING_TIME)
+               *rebuffer_ms = player->streamer->buffering_req.rebuffer_time;
+       else /* live case */
+               *rebuffer_ms = DEFAULT_LIVE_REBUFFER_TIME;
 
+       LOGD("buffering time %d ms / %d ms", *prebuffer_ms, *rebuffer_ms);
 
-               }
-       }
-       return FALSE;
+       MMPLAYER_FLEAVE();
+       return ret;
 }
 
-static GstPadProbeReturn
-__mmplayer_dump_buffer_probe_cb(GstPad *pad,  GstPadProbeInfo *info, gpointer u_data)
+int
+_mmplayer_set_codec_type(MMHandleType hplayer, mmplayer_stream_type_e stream_type, mmplayer_video_codec_type_e codec_type)
 {
-       FILE *dump_data = (FILE *) u_data;
-//     int written = 0;
-       GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
-       GstMapInfo probe_info = GST_MAP_INFO_INIT;
+#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_RETURN_VAL_IF_FAIL(dump_data, FALSE);
+       MMPLAYER_FENTER();
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       gst_buffer_map(buffer, &probe_info, GST_MAP_READ);
+       LOGD("ini setting : [a][h:%s][s:%s] / [v][h:%s][s:%s]",
+               player->ini.audiocodec_element_hw, player->ini.audiocodec_element_sw[IDX_FIRST_SW_CODEC],
+               player->ini.videocodec_element_hw, player->ini.videocodec_element_sw[IDX_FIRST_SW_CODEC]);
 
-//     LOGD("buffer timestamp = %" GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
+       switch (stream_type) {
+       case MM_PLAYER_STREAM_TYPE_AUDIO:
+       /* to support audio codec selection, codec info have to be added in ini file as below.
+          audio codec element hw = xxxx
+          audio codec element sw = avdec */
+               if (((codec_type == MM_PLAYER_CODEC_TYPE_HW) &&
+                        (!strcmp(player->ini.audiocodec_element_hw, ""))) ||
+                       ((codec_type == MM_PLAYER_CODEC_TYPE_SW) &&
+                        (!strcmp(player->ini.audiocodec_element_sw[IDX_FIRST_SW_CODEC], "")))) {
+                       LOGE("There is no audio codec info for codec_type %d", codec_type);
+                       return MM_ERROR_PLAYER_NO_OP;
+               }
+       break;
+       case MM_PLAYER_STREAM_TYPE_VIDEO:
+       /* to support video codec selection, codec info have to be added in ini file as below.
+          video codec element hw = omx
+          video codec element sw = avdec */
+               if (((codec_type == MM_PLAYER_CODEC_TYPE_HW) &&
+                        (!strcmp(player->ini.videocodec_element_hw, ""))) ||
+                       ((codec_type == MM_PLAYER_CODEC_TYPE_SW) &&
+                        (!strcmp(player->ini.videocodec_element_sw[IDX_FIRST_SW_CODEC], "")))) {
+                       LOGE("There is no video codec info for codec_type %d", codec_type);
+                       return MM_ERROR_PLAYER_NO_OP;
+               }
+       break;
+       default:
+               LOGE("Invalid stream type %s", MMPLAYER_STREAM_TYPE_GET_NAME(stream_type));
+               return MM_ERROR_COMMON_INVALID_ARGUMENT;
+       break;
+       }
 
-       fwrite(probe_info.data, 1, probe_info.size , dump_data);
+       LOGD("update %s codec_type to %d", attr_name, codec_type);
 
-       return GST_PAD_PROBE_OK;
-}
+       attrs = MMPLAYER_GET_ATTRS(player);
+       mm_attrs_set_int_by_name(attrs, attr_name, codec_type);
 
-static void
-__mmplayer_release_dump_list(GList *dump_list)
-{
-       if (dump_list) {
-               GList *d_list = dump_list;
-               for (; d_list; d_list = g_list_next(d_list)) {
-                       mm_player_dump_t *dump_s = d_list->data;
-                       if (dump_s->dump_pad) {
-                               if (dump_s->probe_handle_id)
-                                       gst_pad_remove_probe(dump_s->dump_pad, dump_s->probe_handle_id);
-                       }
-                       if (dump_s->dump_element_file) {
-                               fclose(dump_s->dump_element_file);
-                               dump_s->dump_element_file = NULL;
-                       }
-                       MMPLAYER_FREEIF(dump_s);
-               }
-               g_list_free(dump_list);
-               dump_list = NULL;
+       if (mm_attrs_commit_all(player->attrs)) {
+               LOGE("failed to commit codec_type attributes");
+               return MM_ERROR_PLAYER_INTERNAL;
        }
+
+       MMPLAYER_FLEAVE();
+       return MM_ERROR_NONE;
 }
 
 int
-_mmplayer_has_closed_caption(MMHandleType hplayer, bool* exist)
+_mmplayer_set_replaygain_enabled(MMHandleType hplayer, bool enabled)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       GstElement *rg_vol_element = NULL;
 
        MMPLAYER_FENTER();
 
        MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(exist, MM_ERROR_INVALID_ARGUMENT);
 
-       *exist = player->has_closed_caption;
+       player->sound.rg_enable = enabled;
+
+       /* just hold rgvolume enable value if pipeline is not ready */
+       if (!player->pipeline || !player->pipeline->audiobin) {
+               LOGD("pipeline is not ready. holding rgvolume enable value");
+               return MM_ERROR_NONE;
+       }
+
+       rg_vol_element = player->pipeline->audiobin[MMPLAYER_A_RGVOL].gst;
+
+       if (!rg_vol_element) {
+               LOGD("rgvolume element is not created");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       if (enabled)
+               g_object_set(rg_vol_element, "enable-rgvolume", TRUE, NULL);
+       else
+               g_object_set(rg_vol_element, "enable-rgvolume", FALSE, NULL);
 
        MMPLAYER_FLEAVE();
 
        return MM_ERROR_NONE;
 }
 
-void _mm_player_video_stream_internal_buffer_unref(void *buffer)
+int
+_mmplayer_is_replaygain_enabled(MMHandleType hplayer, bool *enabled)
 {
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       GstElement *rg_vol_element = NULL;
+       gboolean enable = FALSE;
+
        MMPLAYER_FENTER();
-       if (buffer) {
-               // LOGD("unref internal gst buffer %p", buffer);
-               gst_buffer_unref((GstBuffer *)buffer);
-               buffer = NULL;
-       }
-       MMPLAYER_FLEAVE();
-}
 
-void
-__gst_appsrc_feed_audio_data(GstElement *element, guint size, gpointer user_data)
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_AUDIO;
-       guint64 current_level_bytes = 0;
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(enabled, MM_ERROR_INVALID_ARGUMENT);
 
-       MMPLAYER_RETURN_IF_FAIL(player);
+       /* just hold enable_rg value if pipeline is not ready */
+       if (!player->pipeline || !player->pipeline->audiobin) {
+               LOGD("pipeline is not ready. holding rgvolume value (%d)", player->sound.rg_enable);
+               *enabled = player->sound.rg_enable;
+               return MM_ERROR_NONE;
+       }
 
-       g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
+       rg_vol_element = player->pipeline->audiobin[MMPLAYER_A_RGVOL].gst;
 
-       LOGI("app-src: feed audio(%llu)\n", current_level_bytes);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
+       if (!rg_vol_element) {
+               LOGD("rgvolume element is not created");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-       if (player->media_stream_buffer_status_cb[type])
-               player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param[type]);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
+       g_object_get(rg_vol_element, "enable-rgvolume", &enable, NULL);
+       *enabled = (bool)enable;
 
+       MMPLAYER_FLEAVE();
+
+       return MM_ERROR_NONE;
 }
 
-void
-__gst_appsrc_feed_video_data(GstElement *element, guint size, gpointer user_data)
+int
+_mmplayer_set_video_roi_area(MMHandleType hplayer, double scale_x, double scale_y, double scale_width, double scale_height)
 {
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_VIDEO;
-       guint64 current_level_bytes = 0;
-
-       MMPLAYER_RETURN_IF_FAIL(player);
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       MMHandleType attrs = 0;
+       void *handle = NULL;
+       int ret = MM_ERROR_NONE;
 
-       g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
+       MMPLAYER_FENTER();
 
-       LOGI("app-src: feed video(%llu)\n", current_level_bytes);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-       if (player->media_stream_buffer_status_cb[type])
-               player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param[type]);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
-}
+       attrs = MMPLAYER_GET_ATTRS(player);
+       MMPLAYER_RETURN_VAL_IF_FAIL(attrs, MM_ERROR_PLAYER_INTERNAL);
 
-void
-__gst_appsrc_feed_subtitle_data(GstElement *element, guint size, gpointer user_data)
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_TEXT;
-       guint64 current_level_bytes = 0;
+       mm_attrs_get_data_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;
+       }
 
-       MMPLAYER_RETURN_IF_FAIL(player);
+       player->video_roi.scale_x = scale_x;
+       player->video_roi.scale_y = scale_y;
+       player->video_roi.scale_width = scale_width;
+       player->video_roi.scale_height = scale_height;
 
-       LOGI("app-src: feed subtitle\n");
+       /* check video sinkbin is created */
+       if (__mmplayer_video_param_check_video_sink_bin(player) != MM_ERROR_NONE)
+               return MM_ERROR_NONE;
 
-       g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
+       if (!gst_video_overlay_set_video_roi_area(
+               GST_VIDEO_OVERLAY(player->pipeline->videobin[MMPLAYER_V_SINK].gst),
+               scale_x, scale_y, scale_width, scale_height))
+               ret = MM_ERROR_PLAYER_INTERNAL;
+       else
+               LOGD("set video param : video roi area scale value: x(%f) y(%f) width(%f) height(%f)",
+                       scale_x, scale_y, scale_width, scale_height);
 
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-       if (player->media_stream_buffer_status_cb[type])
-               player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_UNDERRUN, current_level_bytes, player->buffer_cb_user_param[type]);
+       MMPLAYER_FLEAVE();
 
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
+       return ret;
 }
 
-void
-__gst_appsrc_enough_audio_data(GstElement *element, gpointer user_data)
+int
+_mmplayer_get_video_roi_area(MMHandleType hplayer, double *scale_x, double *scale_y, double *scale_width, double *scale_height)
 {
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_AUDIO;
-       guint64 current_level_bytes = 0;
-
-       MMPLAYER_RETURN_IF_FAIL(player);
+       mmplayer_t *player = (mmplayer_t *)hplayer;
+       int ret = MM_ERROR_NONE;
 
-       LOGI("app-src: audio buffer is full.\n");
+       MMPLAYER_FENTER();
 
-       g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(scale_x && scale_y && scale_width && scale_height, MM_ERROR_INVALID_ARGUMENT);
 
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
+       *scale_x = player->video_roi.scale_x;
+       *scale_y = player->video_roi.scale_y;
+       *scale_width = player->video_roi.scale_width;
+       *scale_height = player->video_roi.scale_height;
 
-       if (player->media_stream_buffer_status_cb[type])
-               player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW, current_level_bytes, player->buffer_cb_user_param[type]);
+       LOGD("get video param : video roi area scale value: x(%f) y(%f) width(%f) height(%f)",
+               *scale_x, *scale_y, *scale_width, *scale_height);
 
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
+       return ret;
 }
 
-void
-__gst_appsrc_enough_video_data(GstElement *element, gpointer user_data)
+static gboolean
+__mmplayer_update_duration_value(mmplayer_t *player)
 {
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_VIDEO;
-       guint64 current_level_bytes = 0;
+       gboolean ret = FALSE;
+       gint64 dur_nsec = 0;
+       LOGD("try to update duration");
 
-       MMPLAYER_RETURN_IF_FAIL(player);
+       if (gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &dur_nsec) && (dur_nsec > 0)) {
+               player->duration = dur_nsec;
+               LOGW("duration : %"G_GINT64_FORMAT" msec", GST_TIME_AS_MSECONDS(dur_nsec));
+               ret = TRUE;
+       }
 
-       LOGI("app-src: video buffer is full.\n");
+       if (player->duration < 0) {
+               LOGW("duration is Non-Initialized !!!");
+               player->duration = 0;
+       }
 
-       g_object_get(G_OBJECT(element), "current-level-bytes", &current_level_bytes, NULL);
+       /* update streaming service type */
+       player->streaming_type =  __mmplayer_get_stream_service_type(player);
 
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-       if (player->media_stream_buffer_status_cb[type])
-               player->media_stream_buffer_status_cb[type](type, MM_PLAYER_MEDIA_STREAM_BUFFER_OVERFLOW, current_level_bytes, player->buffer_cb_user_param[type]);
+       /* check duration is OK */
+       if (dur_nsec == 0 && !MMPLAYER_IS_LIVE_STREAMING(player))
+               /* FIXIT : find another way to get duration here. */
+               LOGW("finally it's failed to get duration from pipeline. progressbar will not work correctely!");
 
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
+       return ret;
 }
 
-gboolean
-__gst_seek_audio_data(GstElement * appsrc, guint64 position, gpointer user_data)
+static gboolean
+__mmplayer_update_audio_attrs(mmplayer_t *player, MMHandleType attrs)
 {
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_AUDIO;
+       /* update audio params
+       NOTE : We need original audio params and it can be only obtained from src pad of audio
+       decoder. Below code only valid when we are not using 'resampler' just before
+       'audioconverter'. */
+       GstCaps *caps_a = NULL;
+       GstPad *pad = NULL;
+       gint samplerate = 0, channels = 0;
+       GstStructure *p = NULL;
+       GstElement *aconv = NULL;
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+       LOGD("try to update audio attrs");
 
-       LOGD("app-src: seek audio data %llu\n", position);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->audiobin, FALSE);
 
-       if (player->media_stream_seek_data_cb[type])
-               player->media_stream_seek_data_cb[type](type, position, player->seek_cb_user_param[type]);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
+       if (player->pipeline->audiobin[MMPLAYER_A_CONV].gst) {
+               aconv = player->pipeline->audiobin[MMPLAYER_A_CONV].gst;
+       } else if (player->pipeline->audiobin[MMPLAYER_A_EXTRACT_CONV].gst) {
+               aconv = player->pipeline->audiobin[MMPLAYER_A_EXTRACT_CONV].gst;
+       } else {
+               LOGE("there is no audio converter");
+               return FALSE;
+       }
 
-       return TRUE;
-}
+       pad = gst_element_get_static_pad(aconv, "sink");
 
-gboolean
-__gst_seek_video_data(GstElement * appsrc, guint64 position, gpointer user_data)
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_VIDEO;
+       if (!pad) {
+               LOGW("failed to get pad from audio converter");
+               return FALSE;
+       }
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+       caps_a = gst_pad_get_current_caps(pad);
+       if (!caps_a) {
+               LOGW("not ready to get audio caps");
+               gst_object_unref(pad);
+               return FALSE;
+       }
 
-       LOGD("app-src: seek video data %llu\n", position);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
-       if (player->media_stream_seek_data_cb[type])
-               player->media_stream_seek_data_cb[type](type, position, player->seek_cb_user_param[type]);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
+       p = gst_caps_get_structure(caps_a, 0);
 
-       return TRUE;
-}
+       mm_attrs_get_int_by_name(attrs, "content_audio_samplerate", &samplerate);
 
-gboolean
-__gst_seek_subtitle_data(GstElement * appsrc, guint64 position, gpointer user_data)
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-       MMPlayerStreamType type = MM_PLAYER_STREAM_TYPE_TEXT;
+       gst_structure_get_int(p, "rate", &samplerate);
+       mm_attrs_set_int_by_name(attrs, "content_audio_samplerate", samplerate);
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, FALSE);
+       gst_structure_get_int(p, "channels", &channels);
+       mm_attrs_set_int_by_name(attrs, "content_audio_channels", channels);
 
-       LOGD("app-src: seek subtitle data\n");
-       MMPLAYER_MEDIA_STREAM_CALLBACK_LOCK(player);
+       SECURE_LOGD("samplerate : %d    channels : %d", samplerate, channels);
 
-       if (player->media_stream_seek_data_cb[type])
-               player->media_stream_seek_data_cb[type](type, position, player->seek_cb_user_param[type]);
-       MMPLAYER_MEDIA_STREAM_CALLBACK_UNLOCK(player);
+       gst_caps_unref(caps_a);
+       gst_object_unref(pad);
 
        return TRUE;
 }
 
-int
-_mmplayer_set_pcm_spec(MMHandleType hplayer, int samplerate, int channel)
+static gboolean
+__mmplayer_update_video_attrs(mmplayer_t *player, MMHandleType attrs)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       LOGD("try to update video attrs");
 
-       MMPLAYER_FENTER();
+       GstCaps *caps_v = NULL;
+       GstPad *pad = NULL;
+       gint tmpNu, tmpDe;
+       gint width, height;
+       GstStructure *p = NULL;
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin, FALSE);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player->pipeline->videobin[MMPLAYER_V_SINK].gst, FALSE);
 
-       player->pcm_samplerate = samplerate;
-       player->pcm_channel = channel;
+       pad = gst_element_get_static_pad(player->pipeline->videobin[MMPLAYER_V_SINK].gst, "sink");
+       if (!pad) {
+               LOGD("no videosink sink pad");
+               return FALSE;
+       }
 
-       MMPLAYER_FLEAVE();
-       return MM_ERROR_NONE;
-}
+       caps_v = gst_pad_get_current_caps(pad);
+       /* Use v_stream_caps, if fail to get video_sink sink pad*/
+       if (!caps_v && player->v_stream_caps) {
+               caps_v = player->v_stream_caps;
+               gst_caps_ref(caps_v);
+       }
 
-int _mmplayer_get_timeout(MMHandleType hplayer, int *timeout)
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
+       if (!caps_v) {
+               LOGD("no negitiated caps from videosink");
+               gst_object_unref(pad);
+               return FALSE;
+       }
 
-       MMPLAYER_FENTER();
+       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);
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(timeout, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       gst_structure_get_int(p, "height", &height);
+       mm_attrs_set_int_by_name(attrs, "content_video_height", height);
 
-       if (MMPLAYER_IS_STREAMING(player))
-               *timeout = player->ini.live_state_change_timeout;
-       else
-               *timeout = player->ini.localplayback_state_change_timeout;
+       gst_structure_get_fraction(p, "framerate", &tmpNu, &tmpDe);
 
-       LOGD("timeout = %d\n", *timeout);
+       SECURE_LOGD("width : %d     height : %d", width, height);
 
-       MMPLAYER_FLEAVE();
-       return MM_ERROR_NONE;
+       gst_caps_unref(caps_v);
+       gst_object_unref(pad);
+
+       if (tmpDe > 0) {
+               mm_attrs_set_int_by_name(attrs, "content_video_fps", tmpNu / tmpDe);
+               SECURE_LOGD("fps : %d", tmpNu / tmpDe);
+       }
+
+       return TRUE;
 }
 
-int _mmplayer_get_num_of_video_out_buffers(MMHandleType hplayer, int *num, int *extra_num)
+static gboolean
+__mmplayer_update_bitrate_attrs(mmplayer_t *player, MMHandleType attrs)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       gboolean ret = FALSE;
+       guint64 data_size = 0;
+       gchar *path = NULL;
+       struct stat sb;
 
-       MMPLAYER_FENTER();
+       /* FIXIT : please make it clear the dependancy with duration/codec/uritype */
+       if (!player->duration)
+               return FALSE;
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(num && extra_num, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       if (!MMPLAYER_IS_STREAMING(player) && (player->can_support_codec & FOUND_PLUGIN_VIDEO)) {
+               mm_attrs_get_string_by_name(attrs, "profile_uri", &path);
+               if (stat(path, &sb) == 0)
+                       data_size = (guint64)sb.st_size;
 
-       *num = player->video_num_buffers;
-       *extra_num = player->video_extra_num_buffers;
+       } else if (MMPLAYER_IS_HTTP_STREAMING(player)) {
+               data_size = player->http_content_size;
+       }
 
-       LOGD("state %d, num %d(%d)\n", MMPLAYER_CURRENT_STATE(player), *num, *extra_num);
+       LOGD("try to update bitrate : data_size = %"G_GUINT64_FORMAT, data_size);
 
-       MMPLAYER_FLEAVE();
-       return MM_ERROR_NONE;
+       if (data_size) {
+               guint64 bitrate = 0;
+               guint64 msec_dur = 0;
+
+               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);
+
+                       ret = TRUE;
+               } else {
+                       LOGD("player duration is less than 0");
+               }
+       }
+
+       if (MMPLAYER_IS_RTSP_STREAMING(player)) {
+               if (player->total_bitrate) {
+                       mm_attrs_set_int_by_name(attrs, "content_video_bitrate", player->total_bitrate);
+                       ret = TRUE;
+               }
+       }
+
+       return ret;
 }
 
 static void
-__mmplayer_initialize_storage_info(mm_player_t* player, MMPlayerPathType path_type)
+__mmplayer_copy_uri_and_set_type(mmplayer_parse_profile_t *data, const char *uri, int uri_type)
 {
-       int i = 0;
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_IF_FAIL(player);
-
-       for (i = 0; i < MMPLAYER_PATH_MAX; i++) {
-
-               if (path_type == MMPLAYER_PATH_MAX || path_type == i) {
-                       player->storage_info[i].type = STORAGE_TYPE_INTERNAL;
-                       player->storage_info[i].state = STORAGE_STATE_UNMOUNTABLE;
-                       player->storage_info[i].id = -1;
-                       memset(player->storage_info[i].path, 0x00, MM_MAX_URL_LEN);
+       strncpy(data->uri, uri, MM_MAX_URL_LEN - 1);
+       data->uri_type = uri_type;
+}
 
-                       if (path_type != MMPLAYER_PATH_MAX)
-                               break;
+static int
+__mmplayer_set_mem_uri(mmplayer_parse_profile_t *data, char *path, void *param)
+{
+       int ret = MM_ERROR_PLAYER_INVALID_URI;
+       int mem_size = 0;
+       char *buffer = NULL;
+       char *seperator = strchr(path, ',');
+       char ext[100] = {0,}, size[100] = {0,};
+
+       if (seperator) {
+               if ((buffer = strstr(path, "ext="))) {
+                       buffer += strlen("ext=");
+
+                       if (strlen(buffer)) {
+                               strncpy(ext, buffer, 99);
+
+                               if ((seperator = strchr(ext, ','))
+                                       || (seperator = strchr(ext, ' '))
+                                       || (seperator = strchr(ext, '\0'))) {
+                                       seperator[0] = '\0';
+                               }
+                       }
                }
-       }
 
-       MMPLAYER_FLEAVE();
-}
+               if ((buffer = strstr(path, "size="))) {
+                       buffer += strlen("size=");
 
-int _mmplayer_manage_external_storage_state(MMHandleType hplayer, int id, int state)
-{
-       int ret = MM_ERROR_NONE;
-       mm_player_t* player = (mm_player_t*)hplayer;
-       MMMessageParamType msg_param = {0, };
+                       if (strlen(buffer) > 0) {
+                               strncpy(size, buffer, 99);
 
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+                               if ((seperator = strchr(size, ','))
+                                       || (seperator = strchr(size, ' '))
+                                       || (seperator = strchr(size, '\0'))) {
+                                       seperator[0] = '\0';
+                               }
 
-       LOGW("state changed storage %d:%d", id, state);
+                               mem_size = atoi(size);
+                       }
+               }
+       }
 
-       if (state != STORAGE_STATE_UNMOUNTABLE && state != STORAGE_STATE_REMOVED)
-               return MM_ERROR_NONE;
+       LOGD("ext: %s, mem_size: %d, mmap(param): %p", ext, mem_size, param);
 
-       /* FIXME: text path should be handled seperately. */
-       if (((player->storage_info[MMPLAYER_PATH_VOD].type == STORAGE_TYPE_EXTERNAL) && (player->storage_info[MMPLAYER_PATH_VOD].id == id)) ||
-               ((player->storage_info[MMPLAYER_PATH_TEXT].type == STORAGE_TYPE_EXTERNAL) && (player->storage_info[MMPLAYER_PATH_TEXT].id == id))) {
-               LOGW("external storage is removed");
+       if (mem_size && param) {
+               if (data->input_mem.buf)
+                       free(data->input_mem.buf);
+               data->input_mem.buf = malloc(mem_size);
 
-               if (player->msg_posted == FALSE) {
-                       memset(&msg_param, 0, sizeof(MMMessageParamType));
-                       msg_param.code = MM_ERROR_PLAYER_INVALID_URI;
-                       MMPLAYER_POST_MSG(player, MM_MESSAGE_ERROR, &msg_param);
-                       player->msg_posted = TRUE;
+               if (data->input_mem.buf) {
+                       memcpy(data->input_mem.buf, param, mem_size);
+                       data->input_mem.len = mem_size;
+                       ret = MM_ERROR_NONE;
+               } else {
+                       LOGE("failed to alloc mem %d", mem_size);
+                       ret = MM_ERROR_PLAYER_INTERNAL;
                }
 
-               /* unrealize the player */
-               ret = _mmplayer_unrealize(hplayer);
-               if (ret != MM_ERROR_NONE)
-                       LOGE("failed to unrealize");
+               data->input_mem.offset = 0;
+               data->uri_type = MM_PLAYER_URI_TYPE_MEM;
        }
 
-       MMPLAYER_FLEAVE();
        return ret;
 }
 
-int _mmplayer_get_adaptive_variant_info(MMHandleType hplayer, int *num, char **var_info)
+static int
+__mmplayer_set_file_uri(mmplayer_parse_profile_t *data, const char *uri)
 {
+       gchar *location = NULL;
+       GError *err = NULL;
+       char *path = NULL;
        int ret = MM_ERROR_NONE;
-       mm_player_t* player = (mm_player_t*) hplayer;
-       int idx = 0, total = 0;
-       gchar *result = NULL, *tmp = NULL;
 
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(num && var_info, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       if ((path = strstr(uri, "file://"))) {
+               location = g_filename_from_uri(uri, NULL, &err);
+               if (!location || (err != NULL)) {
+                       LOGE("Invalid URI '%s' for filesrc: %s", path,
+                               (err != NULL) ? err->message : "unknown error");
+                       if (err)
+                               g_error_free(err);
 
-       total = *num = g_list_length(player->adaptive_info.var_list);
-       if (total <= 0) {
-               LOGW("There is no stream variant info.");
-               return ret;
+                       MMPLAYER_FREEIF(location);
+
+                       data->uri_type = MM_PLAYER_URI_TYPE_NONE;
+                       return MM_ERROR_PLAYER_INVALID_URI;
+               }
+               LOGD("path from uri: %s", location);
        }
 
-       result = g_strdup("");
-       for (idx = 0 ; idx < total ; idx++) {
-               VariantData *v_data = NULL;
-               v_data = g_list_nth_data(player->adaptive_info.var_list, idx);
+       path = (location != NULL) ? (location) : ((char *)uri);
 
-               if (v_data) {
-                       gchar data[64] = {0};
-                       snprintf(data, sizeof(data), "%d,%d,%d,", v_data->bandwidth, v_data->width, v_data->height);
 
-                       tmp = g_strconcat(result, data, NULL);
-                       g_free(result);
-                       result = tmp;
+       ret = util_exist_file_path(path);
+
+       /* if no protocol prefix exist. check file existence and then give file:// as it's prefix */
+       if (ret == MM_ERROR_NONE) {
+               g_snprintf(data->uri,  MM_MAX_URL_LEN, "file://%s", path);
+               if (util_is_sdp_file(path)) {
+                       LOGD("uri is actually a file but it's sdp file. giving it to rtspsrc");
+                       data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
                } else {
-                       LOGW("There is no variant data in %d", idx);
-                       (*num)--;
+                       data->uri_type = MM_PLAYER_URI_TYPE_FILE;
                }
+       } else if (ret == MM_ERROR_PLAYER_PERMISSION_DENIED) {
+               data->uri_type = MM_PLAYER_URI_TYPE_NO_PERMISSION;
+       } else {
+               LOGE("invalid uri, could not play..");
+               data->uri_type = MM_PLAYER_URI_TYPE_NONE;
        }
 
-       *var_info = (char *)result;
+       MMPLAYER_FREEIF(location);
 
-       LOGD("variant info %d:%s", *num, *var_info);
-       MMPLAYER_FLEAVE();
        return ret;
 }
 
-int _mmplayer_set_max_adaptive_variant_limit(MMHandleType hplayer, int bandwidth, int width, int height)
+static mmplayer_video_decoded_data_info_t *
+__mmplayer_create_stream_from_pad(GstPad *pad)
 {
-       int ret = MM_ERROR_NONE;
-       mm_player_t* player = (mm_player_t*) hplayer;
+       GstCaps *caps = NULL;
+       GstStructure *structure = NULL;
+       unsigned int fourcc = 0;
+       const gchar *string_format = NULL;
+       mmplayer_video_decoded_data_info_t *stream = NULL;
+       gint width, height;
+       MMPixelFormatType format;
+       GstVideoInfo info;
 
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       caps = gst_pad_get_current_caps(pad);
+       if (!caps) {
+               LOGE("Caps is NULL.");
+               return NULL;
+       }
 
-       LOGD("set limit to [b]%d, [w]%d, [h]%d", bandwidth, width, height);
+       /* MMPLAYER_LOG_GST_CAPS_TYPE(caps); */
+       structure = gst_caps_get_structure(caps, 0);
+       gst_structure_get_int(structure, "width", &width);
+       gst_structure_get_int(structure, "height", &height);
+       string_format = gst_structure_get_string(structure, "format");
 
-       player->adaptive_info.limit.bandwidth = (bandwidth >= ADAPTIVE_VARIANT_DEFAULT_VALUE) ? (bandwidth) : (ADAPTIVE_VARIANT_DEFAULT_VALUE);
-       player->adaptive_info.limit.width = (width >= ADAPTIVE_VARIANT_DEFAULT_VALUE) ? (width) : (ADAPTIVE_VARIANT_DEFAULT_VALUE);
-       player->adaptive_info.limit.height = (height >= ADAPTIVE_VARIANT_DEFAULT_VALUE) ? (height) : (ADAPTIVE_VARIANT_DEFAULT_VALUE);
+       if (string_format)
+               fourcc = _mmplayer_convert_fourcc_string_to_value(string_format);
+       format = util_get_pixtype(fourcc);
+       gst_video_info_from_caps(&info, caps);
+       gst_caps_unref(caps);
 
-       if (player->pipeline && player->pipeline->mainbin && player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst) {
-               LOGD("update max limit of %s", GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst));
-               g_object_set(player->pipeline->mainbin[MMPLAYER_M_ADAPTIVE_DEMUX].gst,
-                                               "max-bandwidth", bandwidth, "max-video-width", width, "max-video-height", height, NULL);
+       /* moved here */
+       if (width == 0 || height == 0 || format == MM_PIXEL_FORMAT_INVALID) {
+               LOGE("Wrong condition!!");
+               return NULL;
+       }
 
-               /* FIXME: seek to current position for applying new variant limitation */
+       stream = (mmplayer_video_decoded_data_info_t *)g_try_malloc0(sizeof(mmplayer_video_decoded_data_info_t));
+       if (!stream) {
+               LOGE("failed to alloc mem for video data");
+               return NULL;
        }
 
-       MMPLAYER_FLEAVE();
-       return ret;
+       stream->width = width;
+       stream->height = height;
+       stream->format = format;
+       stream->plane_num = GST_VIDEO_INFO_N_PLANES(&info);
 
+       return stream;
 }
 
-int _mmplayer_get_max_adaptive_variant_limit(MMHandleType hplayer, int *bandwidth, int *width, int *height)
-{
-       int ret = MM_ERROR_NONE;
-       mm_player_t* player = (mm_player_t*) hplayer;
-
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(bandwidth && width && height, MM_ERROR_COMMON_INVALID_ARGUMENT);
-
-       *bandwidth = player->adaptive_info.limit.bandwidth;
-       *width = player->adaptive_info.limit.width;
-       *height = player->adaptive_info.limit.height;
-
-       LOGD("get limit to [b]%d, [w]%d, [h]%d", *bandwidth, *width, *height);
+static void
+__mmplayer_zerocopy_set_stride_elevation_bo(mmplayer_video_decoded_data_info_t *stream, GstMemory *mem)
+{
+       unsigned int pitch = 0;
+       unsigned int size = 0;
+       int index = 0;
+       tbm_surface_h surface = gst_tizen_memory_get_surface(mem);
+       tbm_bo bo = NULL;
+
+       for (index = 0; index < gst_tizen_memory_get_num_bos(mem); index++) {
+               bo = gst_tizen_memory_get_bos(mem, index);
+               if (bo)
+                       stream->bo[index] = tbm_bo_ref(bo);
+               else
+                       LOGE("failed to get bo for index %d", index);
+       }
 
-       MMPLAYER_FLEAVE();
-       return ret;
+       for (index = 0; index < stream->plane_num; index++) {
+               tbm_surface_internal_get_plane_data(surface, index, &size, NULL, &pitch);
+               stream->stride[index] = pitch;
+               if (pitch)
+                       stream->elevation[index] = size / pitch;
+               else
+                       stream->elevation[index] = stream->height;
+       }
 }
 
-int _mmplayer_set_streaming_buffering_time(MMHandleType hplayer, int buffer_ms, int rebuffer_ms)
+static gboolean
+__mmplayer_swcodec_set_stride_elevation(mmplayer_video_decoded_data_info_t *stream)
 {
-       int ret = MM_ERROR_NONE;
-       mm_player_t* player = (mm_player_t*) hplayer;
-
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       if (MMPLAYER_CURRENT_STATE(player) !=  MM_PLAYER_STATE_NULL)
-               LOGW("buffer_ms will not be applied.");
+       if (stream->format == MM_PIXEL_FORMAT_I420) {
+               int ret = TBM_SURFACE_ERROR_NONE;
+               tbm_surface_h surface;
+               tbm_surface_info_s info;
 
+               surface = tbm_surface_create(stream->width, stream->height, TBM_FORMAT_YUV420);
 
-       LOGD("set buffering time %d ms / %d ms", buffer_ms, rebuffer_ms);
+               ret = tbm_surface_get_info(surface, &info);
+               if (ret != TBM_SURFACE_ERROR_NONE) {
+                       tbm_surface_destroy(surface);
+                       return FALSE;
+               }
 
-       if (player->streamer == NULL) {
-               player->streamer = __mm_player_streaming_create();
-               __mm_player_streaming_initialize(player->streamer);
+               tbm_surface_destroy(surface);
+               stream->stride[0] = info.planes[0].stride;
+               stream->elevation[0] = info.planes[0].size / info.planes[0].stride;
+               stream->stride[1] = info.planes[1].stride;
+               stream->elevation[1] = info.planes[1].size / info.planes[1].stride;
+               stream->stride[2] = info.planes[2].stride;
+               stream->elevation[2] = info.planes[2].size / info.planes[2].stride;
+               stream->bo_size = info.planes[0].size + info.planes[1].size + info.planes[2].size;
+       } else if (stream->format == MM_PIXEL_FORMAT_RGBA) {
+               stream->stride[0] = stream->width * 4;
+               stream->elevation[0] = stream->height;
+               stream->bo_size = stream->stride[0] * stream->height;
+       } else {
+               LOGE("Not support format %d", stream->format);
+               return FALSE;
        }
 
-       if (buffer_ms >= 0)
-               player->streamer->buffering_req.prebuffer_time = buffer_ms;
-
-       if (rebuffer_ms >= 0)
-               player->streamer->buffering_req.rebuffer_time = rebuffer_ms;
-
-       MMPLAYER_FLEAVE();
-       return ret;
-
+       return TRUE;
 }
 
-int _mmplayer_get_streaming_buffering_time(MMHandleType hplayer, int *buffer_ms, int *rebuffer_ms)
+static gboolean
+__mmplayer_swcodec_set_bo(mmplayer_t *player, mmplayer_video_decoded_data_info_t *stream, GstMemory *mem)
 {
-       int ret = MM_ERROR_NONE;
-       mm_player_t* player = (mm_player_t*) hplayer;
+       tbm_bo_handle thandle;
+       gboolean is_mapped;
+       int src_stride[MM_PLAYER_IMGB_MPLANE_MAX] = { 0, };
+       int src_offset[MM_PLAYER_IMGB_MPLANE_MAX] = { 0, };
+       int dest_offset[MM_PLAYER_IMGB_MPLANE_MAX] = { 0, };
+       int i = 0;
+       int j = 0;
+       int k = 0;
+       unsigned char *src = NULL;
+       unsigned char *dest = NULL;
+       GstMapInfo mapinfo = GST_MAP_INFO_INIT;
 
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(buffer_ms && rebuffer_ms, MM_ERROR_COMMON_INVALID_ARGUMENT);
+       is_mapped = gst_memory_map(mem, &mapinfo, GST_MAP_READWRITE);
+       if (!is_mapped) {
+               LOGE("fail to gst_memory_map");
+               return FALSE;
+       }
 
-       if (player->streamer == NULL) {
-               player->streamer = __mm_player_streaming_create();
-               __mm_player_streaming_initialize(player->streamer);
+       if (!mapinfo.data) {
+               LOGE("data pointer is wrong");
+               goto ERROR;
        }
 
-       *buffer_ms = player->streamer->buffering_req.prebuffer_time;
-       *rebuffer_ms = player->streamer->buffering_req.rebuffer_time;
+       stream->bo[0] = __mmplayer_video_stream_get_bo(player, stream->bo_size);
+       if (!stream->bo[0]) {
+               LOGE("Fail to tbm_bo_alloc!!");
+               goto ERROR;
+       }
 
-       LOGD("buffering time %d ms / %d ms", *buffer_ms, *rebuffer_ms);
+       thandle = tbm_bo_map(stream->bo[0], TBM_DEVICE_CPU, TBM_OPTION_WRITE);
+       if (!thandle.ptr) {
+               LOGE("thandle pointer is wrong");
+               goto ERROR;
+       }
 
-       MMPLAYER_FLEAVE();
-       return ret;
-}
+       if (stream->format == MM_PIXEL_FORMAT_I420) {
+               src_stride[0] = GST_ROUND_UP_4(stream->width);
+               src_stride[1] = src_stride[2] = GST_ROUND_UP_4(stream->width >> 1);
+               src_offset[1] = src_stride[0] * GST_ROUND_UP_2(stream->height);
+               src_offset[2] = src_offset[1] + (src_stride[1] * (GST_ROUND_UP_2(stream->height) >> 1));
 
-int _mmplayer_set_codec_type(MMHandleType hplayer, MMPlayerStreamType stream_type, MMPlayerVideoCodecType codec_type)
-{
-#define IDX_FIRST_SW_CODEC 0
-       mm_player_t* player = (mm_player_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;
+               dest_offset[0] = 0;
+               dest_offset[1] = stream->stride[0] * stream->elevation[0];
+               dest_offset[2] = dest_offset[1] + stream->stride[1] * stream->elevation[1];
 
-       MMPLAYER_FENTER();
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+               for (i = 0; i < 3; i++) {
+                       src = mapinfo.data + src_offset[i];
+                       dest = thandle.ptr + dest_offset[i];
 
-       LOGD("ini setting : [a][h:%s][s:%s] / [v][h:%s][s:%s]",
-               player->ini.audiocodec_element_hw, player->ini.audiocodec_element_sw[IDX_FIRST_SW_CODEC],
-               player->ini.videocodec_element_hw, player->ini.videocodec_element_sw[IDX_FIRST_SW_CODEC]);
+                       if (i > 0)
+                               k = 1;
 
-       switch (stream_type) {
-       case MM_PLAYER_STREAM_TYPE_AUDIO:
-               if (((codec_type == MM_PLAYER_CODEC_TYPE_HW) &&
-                        (!strcmp(player->ini.audiocodec_element_hw, ""))) ||
-                       ((codec_type == MM_PLAYER_CODEC_TYPE_SW) &&
-                        (!strcmp(player->ini.audiocodec_element_sw[IDX_FIRST_SW_CODEC], "")))) {
-                       LOGE("There is no a codec for codec_type %d", codec_type);
-                       return MM_ERROR_PLAYER_NO_OP;
-               }
-       break;
-       case MM_PLAYER_STREAM_TYPE_VIDEO:
-               if (((codec_type == MM_PLAYER_CODEC_TYPE_HW) &&
-                        (!strcmp(player->ini.videocodec_element_hw, ""))) ||
-                       ((codec_type == MM_PLAYER_CODEC_TYPE_SW) &&
-                        (!strcmp(player->ini.videocodec_element_sw[IDX_FIRST_SW_CODEC], "")))) {
-                       LOGE("There is no v codec for codec_type %d", codec_type);
-                       return MM_ERROR_PLAYER_NO_OP;
+                       for (j = 0; j < stream->height >> k; j++) {
+                               memcpy(dest, src, stream->width>>k);
+                               src += src_stride[i];
+                               dest += stream->stride[i];
+                       }
                }
-
-       break;
-       default:
-               LOGE("Invalid stream type %d", stream_type);
-               return MM_ERROR_COMMON_INVALID_ARGUMENT;
-       break;
+       } else if (stream->format == MM_PIXEL_FORMAT_RGBA) {
+               memcpy(thandle.ptr, mapinfo.data, stream->bo_size);
+       } else {
+               LOGE("Not support format %d", stream->format);
+               goto ERROR;
        }
 
-       LOGD("update %s codec_type to %d", attr_name, codec_type);
+       tbm_bo_unmap(stream->bo[0]);
+       gst_memory_unmap(mem, &mapinfo);
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       mm_attrs_set_int_by_name(attrs, attr_name, codec_type);
+       return TRUE;
 
-       if (mmf_attrs_commit(player->attrs)) {
-               LOGE("failed to commit codec_type attributes");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
+ERROR:
+       if (stream->bo[0])
+               tbm_bo_unmap(stream->bo[0]);
 
-       MMPLAYER_FLEAVE();
-       return MM_ERROR_NONE;
+       if (is_mapped)
+               gst_memory_unmap(mem, &mapinfo);
+
+       return FALSE;
 }
 
-int
-_mmplayer_set_replaygain_enabled(MMHandleType hplayer, bool enabled)
+static void
+__mmplayer_set_pause_state(mmplayer_t *player)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
-       GstElement* rg_vol_element = NULL;
-
-       MMPLAYER_FENTER();
-
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       if (player->sent_bos)
+               return;
 
-       player->sound.rg_enable = enabled;
+       /* rtsp case, get content attrs by GstMessage */
+       if (MMPLAYER_IS_RTSP_STREAMING(player))
+               return;
 
-       /* just hold rgvolume enable value if pipeline is not ready */
-       if (!player->pipeline || !player->pipeline->audiobin) {
-               LOGD("pipeline is not ready. holding rgvolume enable value\n");
-               return MM_ERROR_NONE;
-       }
+       /* it's first time to update all content attrs. */
+       __mmplayer_update_content_attrs(player, ATTR_ALL);
+}
 
-       rg_vol_element = player->pipeline->audiobin[MMPLAYER_A_RGVOL].gst;
+static void
+__mmplayer_set_playing_state(mmplayer_t *player)
+{
+       gchar *audio_codec = NULL;
 
-       if (!rg_vol_element) {
-               LOGD("rgvolume element is not created");
-               return MM_ERROR_PLAYER_INTERNAL;
+       if (player->resumed_by_rewind && player->playback_rate < 0.0) {
+               /* initialize because auto resume is done well. */
+               player->resumed_by_rewind = FALSE;
+               player->playback_rate = 1.0;
        }
 
-       if (enabled)
-               g_object_set(rg_vol_element, "enable-rgvolume", TRUE, NULL);
-       else
-               g_object_set(rg_vol_element, "enable-rgvolume", FALSE, NULL);
+       if (player->sent_bos)
+               return;
 
-       MMPLAYER_FLEAVE();
+       /* try to get content metadata */
 
-       return MM_ERROR_NONE;
-}
+       /* NOTE : giving ATTR_MISSING_ONLY may have dependency with
+        * c-api since c-api doesn't use _start() anymore. It may not work propery with
+        * legacy mmfw-player api
+        */
+       __mmplayer_update_content_attrs(player, ATTR_MISSING_ONLY);
 
-int
-_mmplayer_is_replaygain_enabled(MMHandleType hplayer, bool *enabled)
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       GstElement* rg_vol_element = NULL;
-       gboolean enable = FALSE;
+       if ((player->cmd == MMPLAYER_COMMAND_START)
+               || (player->cmd == MMPLAYER_COMMAND_RESUME)) {
+               __mmplayer_handle_missed_plugin(player);
+       }
 
-       MMPLAYER_FENTER();
+       /* check audio codec field is set or not
+        * we can get it from typefinder or codec's caps.
+        */
+       mm_attrs_get_string_by_name(player->attrs, "content_audio_codec", &audio_codec);
 
-       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       MMPLAYER_RETURN_VAL_IF_FAIL(enabled, MM_ERROR_INVALID_ARGUMENT);
+       /* The codec format can't be sent for audio only case like amr, mid etc.
+        * Because, parser don't make related TAG.
+        * So, if it's not set yet, fill it with found data.
+        */
+       if (!audio_codec) {
+               if (g_strrstr(player->type, "audio/midi"))
+                       audio_codec = "MIDI";
+               else if (g_strrstr(player->type, "audio/x-amr"))
+                       audio_codec = "AMR";
+               else if (g_strrstr(player->type, "audio/mpeg")
+                               && !g_strrstr(player->type, "mpegversion=(int)1"))
+                       audio_codec = "AAC";
+               else
+                       audio_codec = "unknown";
 
-       /* just hold enable_rg value if pipeline is not ready */
-       if (!player->pipeline || !player->pipeline->audiobin) {
-               LOGD("pipeline is not ready. holding rgvolume value (%d)\n", player->sound.rg_enable);
-               *enabled = player->sound.rg_enable;
-               return MM_ERROR_NONE;
-       }
+               mm_attrs_set_string_by_name(player->attrs, "content_audio_codec", audio_codec);
 
-       rg_vol_element = player->pipeline->audiobin[MMPLAYER_A_RGVOL].gst;
+               if (mm_attrs_commit_all(player->attrs))
+                       LOGE("failed to update attributes");
 
-       if (!rg_vol_element) {
-               LOGD("rgvolume element is not created");
-               return MM_ERROR_PLAYER_INTERNAL;
+               LOGD("set audio codec type with caps");
        }
 
-       g_object_get(rg_vol_element, "enable-rgvolume", &enable, NULL);
-       *enabled = enable;
-
-       MMPLAYER_FLEAVE();
-
-       return MM_ERROR_NONE;
+       return;
 }