devide files to resolve build break 81/21681/2 submit/tizen/20140526.114814
authoreunhae1.choi <eunhae1.choi@samsung.com>
Mon, 26 May 2014 09:27:10 +0000 (18:27 +0900)
committereunhae1.choi <eunhae1.choi@samsung.com>
Mon, 26 May 2014 10:00:31 +0000 (19:00 +0900)
Change-Id: I35cc8556b93e91798dc13ce7ea17c8d44bad2a00

src/Makefile.am [changed mode: 0644->0755]
src/include/mm_player_priv_internal.h [new file with mode: 0755]
src/include/mm_player_priv_locl_func.h [new file with mode: 0755]
src/mm_player_priv.c
src/mm_player_priv_gst.c [new file with mode: 0755]
src/mm_player_priv_gst_wrapper.c [new file with mode: 0755]
src/mm_player_priv_internal.c [new file with mode: 0755]
src/mm_player_streaming.c [changed mode: 0644->0755]
src/mm_player_utils.c [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 8e1523e..4081fe4
@@ -8,6 +8,9 @@ includelibmmfplayer_HEADERS = include/mm_player.h \
 
 libmmfplayer_la_SOURCES = mm_player.c \
                          mm_player_priv.c \
+                         mm_player_priv_gst.c \
+                         mm_player_priv_internal.c \
+                         mm_player_priv_gst_wrapper.c \
                          mm_player_ini.c \
                          mm_player_utils.c \
                          mm_player_asm.c \
diff --git a/src/include/mm_player_priv_internal.h b/src/include/mm_player_priv_internal.h
new file mode 100755 (executable)
index 0000000..40b9dc4
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+ * libmm-player\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, Heechul Jeon <heechul.jeon@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+#ifndef __MM_PLAYER_PRIV_INTERNAL_H__\r
+#define        __MM_PLAYER_PRIV_INTERNAL_H__\r
+\r
+#define MM_PLAYER_FADEOUT_TIME_DEFAULT 700000 // 700 msec\r
+\r
+\r
+/*---------------------------------------------------------------------------\r
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                |\r
+---------------------------------------------------------------------------*/\r
+void           __mmplayer_release_signal_connection(mm_player_t* player);\r
+gboolean       __mmplayer_dump_pipeline_state(mm_player_t* player);\r
+int                    __mmplayer_gst_set_state (mm_player_t* player, GstElement * element,  GstState state, gboolean async, gint timeout);\r
+gboolean       __mmplayer_check_subtitle(mm_player_t* player);\r
+int                    __mmplayer_handle_missed_plugin(mm_player_t* player);\r
+gboolean       __mmplayer_link_decoder(mm_player_t* player, GstPad *srcpad);\r
+gboolean       __mmplayer_link_sink(mm_player_t* player , GstPad *srcpad);\r
+gint           __gst_handle_core_error(mm_player_t* player, int code);\r
+gint           __gst_handle_library_error(mm_player_t* player, int code);\r
+gint           __gst_handle_resource_error(mm_player_t* player, int code);\r
+gint           __gst_handle_stream_error(mm_player_t* player, GError* error, GstMessage * message);\r
+gint           __gst_transform_gsterror( mm_player_t* player, GstMessage * message, GError* error );\r
+gboolean       __mmplayer_handle_gst_error ( mm_player_t* player, GstMessage * message, GError* error );\r
+gboolean       __mmplayer_handle_streaming_error  ( mm_player_t* player, GstMessage * message );\r
+void           __mmplayer_add_sink( mm_player_t* player, GstElement* sink );\r
+void           __mmplayer_del_sink( mm_player_t* player, GstElement* sink );\r
+gboolean       __is_rtsp_streaming ( mm_player_t* player );\r
+gboolean       __is_http_streaming ( mm_player_t* player );\r
+gboolean       __is_streaming ( mm_player_t* player );\r
+gboolean       __is_live_streaming ( mm_player_t* player );\r
+gboolean       __is_http_live_streaming( mm_player_t* player );\r
+gboolean       __is_http_progressive_down(mm_player_t* player);\r
+\r
+#endif /* __MM_PLAYER_PRIV_INTERNAL_H__ */\r
+\r
diff --git a/src/include/mm_player_priv_locl_func.h b/src/include/mm_player_priv_locl_func.h
new file mode 100755 (executable)
index 0000000..c63c0ce
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, Heechul Jeon <heechul.jeon@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MM_PLAYER_LOCAL_FUNCTION_DEF_H_
+#define __MM_PLAYER_LOCAL_FUNCTION_DEF_H_
+
+
+/*---------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                |
+---------------------------------------------------------------------------*/
+/* mm_player_priv.c */
+gboolean       __mmplayer_eos_timer_cb(gpointer u_data);
+void           __mmplayer_typefind_have_type(  GstElement *tf, guint probability, GstCaps *caps, gpointer data);
+GstBusSyncReply        __mmplayer_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data);
+gboolean       __mmplayer_update_subtitle( GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data);
+void           __mmplayer_videoframe_render_error_cb(GstElement *element, void *error_id, gpointer data);
+void           __mmplayer_videostream_cb(GstElement *element, void *stream, int width, int height, gpointer data);
+
+/* mm_player_priv_wrapper.c */
+gboolean       __mmplayer_gst_callback(GstBus *bus, GstMessage *msg, gpointer data);
+gboolean       __mmplayer_gst_handle_duration(mm_player_t* player, GstMessage* msg);
+gboolean       __mmplayer_gst_extract_tag_from_msg(mm_player_t* player, GstMessage* msg);
+void           __mmplayer_gst_rtp_no_more_pads (GstElement *element,  gpointer data);
+gboolean       __mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink);
+void           __mmplayer_gst_rtp_dynamic_pad (GstElement *element, GstPad *pad, gpointer data);
+void           __mmplayer_gst_decode_callback(GstElement *decodebin, GstPad *pad, gboolean last, gpointer data);
+int                    __mmplayer_gst_element_link_bucket(GList* element_bucket);
+int                    __mmplayer_gst_element_add_bucket_to_bin(GstBin* bin, GList* element_bucket);
+int                    __mmplayer_gst_create_audio_pipeline(mm_player_t* player);
+int                    __mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDisplaySurfaceType surface_type);
+int                    __mmplayer_gst_create_text_pipeline(mm_player_t* player);
+int                    __mmplayer_gst_create_subtitle_src(mm_player_t* player);
+int                    __mmplayer_gst_create_pipeline(mm_player_t* player);
+int                    __mmplayer_gst_destroy_pipeline(mm_player_t* player);
+
+/* mm_player_priv_gst.c */
+int            __gst_realize(mm_player_t* player);
+int            __gst_unrealize(mm_player_t* player);
+int            __gst_pending_seek(mm_player_t* player);
+int            __gst_start(mm_player_t* player);
+int            __gst_stop(mm_player_t* player);
+int            __gst_pause(mm_player_t* player, gboolean async);
+int            __gst_resume(mm_player_t* player, gboolean async);
+int            __gst_set_position(mm_player_t* player, int format, unsigned long position, gboolean internal_called);
+int            __gst_get_position(mm_player_t* player, int format, unsigned long* position);
+int            __gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos);
+int            __gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param);
+gboolean       __gst_send_event_to_sink( mm_player_t* player, GstEvent* event );
+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);
+int            __gst_adjust_subtitle_position(mm_player_t* player, int format, int position);
+void   __gst_appsrc_feed_data_mem(GstElement *element, guint size, gpointer user_data);
+gboolean       __gst_appsrc_seek_data_mem(GstElement *element, guint64 size, gpointer user_data);
+void   __gst_appsrc_feed_data(GstElement *element, guint size, gpointer user_data);
+gboolean       __gst_appsrc_seek_data(GstElement *element, guint64 offset, gpointer user_data);
+gboolean       __gst_appsrc_enough_data(GstElement *element, gpointer user_data);
+
+#endif /*#ifndef __MM_PLAYER_LOCAL_FUNCTION_DEF_H_*/
+
index 0a6a1ea..ede7896 100755 (executable)
@@ -35,7 +35,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <sys/time.h>
-#include <sys/stat.h> 
+#include <sys/stat.h>
 #include <stdlib.h>
 
 #include <mm_error.h>
@@ -47,6 +47,8 @@
 #include "mm_player_ini.h"
 #include "mm_player_attrs.h"
 #include "mm_player_capture.h"
+#include "mm_player_priv_internal.h"
+#include "mm_player_priv_locl_func.h"
 
 /*===========================================================================================
 |                                                                                                                                                                                      |
@@ -76,8 +78,6 @@
 #define MM_VOLUME_FACTOR_MIN                           0
 #define MM_VOLUME_FACTOR_MAX                           1.0
 
-#define MM_PLAYER_FADEOUT_TIME_DEFAULT 700000 // 700 msec
-
 #define MM_PLAYER_MPEG_VNAME                           "mpegversion"
 #define MM_PLAYER_DIVX_VNAME                           "divxversion"
 #define MM_PLAYER_WMV_VNAME                            "wmvversion"
@@ -88,9 +88,6 @@
 #define GST_QUEUE_DEFAULT_TIME                 8
 #define GST_QUEUE_HLS_TIME                             8
 
-/* video capture callback*/
-gulong ahs_appsrc_cb_probe_id = 0;
-
 #define MMPLAYER_USE_FILE_FOR_BUFFERING(player) (((player)->profile.uri_type != MM_PLAYER_URI_TYPE_HLS) && (PLAYER_INI()->http_file_buffer_path) && (strlen(PLAYER_INI()->http_file_buffer_path) > 0) )
 
 #define        LAZY_PAUSE_TIMEOUT_MSEC 700
@@ -116,18 +113,6 @@ gulong ahs_appsrc_cb_probe_id = 0;
 ---------------------------------------------------------------------------*/
 static gboolean __mmplayer_set_state(mm_player_t* player, int state);
 static int             __mmplayer_get_state(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_subtitle_src(mm_player_t* player);
-static int             __mmplayer_gst_create_pipeline(mm_player_t* player);
-static int             __mmplayer_gst_destroy_pipeline(mm_player_t* player);
-static int             __mmplayer_gst_element_link_bucket(GList* element_bucket);
-
-static gboolean __mmplayer_gst_callback(GstBus *bus, GstMessage *msg, gpointer data);
-static void    __mmplayer_gst_decode_callback(GstElement *decodebin, GstPad *pad, gboolean last, gpointer data);
-
-static void    __mmplayer_typefind_have_type(  GstElement *tf, guint probability, GstCaps *caps, gpointer data);
 static gboolean __mmplayer_try_to_plug(mm_player_t* player, GstPad *pad, const GstCaps *caps);
 static void    __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data);
 static gboolean __mmplayer_is_midi_type(gchar* str_caps);
@@ -138,73 +123,26 @@ static gboolean   __mmplayer_close_link(mm_player_t* player, GstPad *srcpad, GstEl
 static gboolean __mmplayer_feature_filter(GstPluginFeature *feature, gpointer data);
 static void    __mmplayer_add_new_pad(GstElement *element, GstPad *pad, gpointer data);
 
-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 gboolean        __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_init_factories(mm_player_t* player);
 static void    __mmplayer_release_factories(mm_player_t* player);
 static void    __mmplayer_release_misc(mm_player_t* player);
 static gboolean        __mmplayer_gstreamer_init(void);
 
-static int             __mmplayer_gst_set_state (mm_player_t* player, GstElement * pipeline,  GstState state, gboolean async, gint timeout );
 gboolean __mmplayer_post_message(mm_player_t* player, enum MMMessageType msgtype, MMMessageParamType* param);
-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);
 
 int            __mmplayer_switch_audio_sink (mm_player_t* player);
-static gboolean __mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink);
 static int             __mmplayer_check_state(mm_player_t* player, enum PlayerCommandState command);
 static gboolean __mmplayer_audio_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data);
-
-static gboolean __mmplayer_dump_pipeline_state( mm_player_t* player );
-static gboolean __mmplayer_check_subtitle( mm_player_t* player );
-static gboolean __mmplayer_handle_gst_error ( mm_player_t* player, GstMessage * message, GError* error );
-static gboolean __mmplayer_handle_streaming_error  ( mm_player_t* player, GstMessage * message );
 static void            __mmplayer_post_delayed_eos( mm_player_t* player, int delay_in_ms );
 static void    __mmplayer_cancel_delayed_eos( mm_player_t* player );
-static gboolean        __mmplayer_eos_timer_cb(gpointer u_data);
-static gboolean __mmplayer_link_decoder( mm_player_t* player,GstPad *srcpad);
-static gboolean __mmplayer_link_sink( mm_player_t* player,GstPad *srcpad);
-static int     __mmplayer_handle_missed_plugin(mm_player_t* player);
 static int             __mmplayer_check_not_supported_codec(mm_player_t* player, 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);
 static void __mmplayer_set_antishock( mm_player_t* player, gboolean disable_by_force);
 static gpointer __mmplayer_repeat_thread(gpointer data);
 int _mmplayer_get_track_count(MMHandleType hplayer,  MMPlayerTrackType track_type, int *count);
 static gboolean _mmplayer_update_content_attrs(mm_player_t* player, enum content_attr_flag flag);
-
-
-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 void    __gst_set_async_state_change(mm_player_t* player, gboolean async);
-
-static gint    __gst_handle_core_error( mm_player_t* player, int code );
-static gint    __gst_handle_library_error( mm_player_t* player, int code );
-static gint    __gst_handle_resource_error( mm_player_t* player, int code );
-static gint    __gst_handle_stream_error( mm_player_t* player, GError* error, GstMessage * message );
-static gint            __gst_transform_gsterror( mm_player_t* player, GstMessage * message, GError* error);
-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 );
 
@@ -217,15 +155,8 @@ static void __mmplayer_set_unlinked_mime_type(mm_player_t* player, GstCaps *caps
 
 /* util */
 const gchar * __get_state_name ( int state );
-static gboolean __is_streaming( mm_player_t* player );
-static gboolean __is_rtsp_streaming( mm_player_t* player );
-static gboolean __is_live_streaming ( mm_player_t* player );
-static gboolean __is_http_streaming( mm_player_t* player );
-static gboolean __is_http_live_streaming( mm_player_t* player );
-static gboolean __is_http_progressive_down(mm_player_t* player);
 
 static gboolean __mmplayer_warm_up_video_codec( mm_player_t* player,  GstElementFactory *factory);
-static GstBusSyncReply __mmplayer_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data);
 
 static int  __mmplayer_realize_streaming_ext(mm_player_t* player);
 static int __mmplayer_unrealize_streaming_ext(mm_player_t *player);
@@ -444,70 +375,7 @@ ALREADY_GOING:
        return MM_ERROR_PLAYER_NO_OP;
 }
 
-int
-__mmplayer_gst_set_state (mm_player_t* player, GstElement * element,  GstState state, gboolean async, gint timeout) // @
-{
-       GstState element_state = GST_STATE_VOID_PENDING;
-       GstState element_pending_state = GST_STATE_VOID_PENDING;
-       GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
-
-       debug_fenter();
-
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( element, MM_ERROR_INVALID_ARGUMENT );
-
-       debug_log("setting [%s] element state to : %d\n", GST_ELEMENT_NAME(element),  state);
-
-       /* set state */
-       ret = gst_element_set_state(element, state);
-
-       if ( ret == GST_STATE_CHANGE_FAILURE )
-       {
-               debug_error("failed to set  [%s] state to [%d]\n", GST_ELEMENT_NAME(element), state);
-
-               /* dump state of all element */
-               __mmplayer_dump_pipeline_state( player );
-
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       /* return here so state transition to be done in async mode */
-       if ( async )
-       {
-               debug_log("async state transition. not waiting for state complete.\n");
-               return MM_ERROR_NONE;
-       }
-
-       /* wait for state transition */
-       ret = gst_element_get_state( element, &element_state, &element_pending_state, timeout * GST_SECOND );
-
-       if ( ret == GST_STATE_CHANGE_FAILURE || ( state != element_state ) )
-       {
-               debug_error("failed to change [%s] element state to [%s] within %d sec\n",
-                       GST_ELEMENT_NAME(element),
-                       gst_element_state_get_name(state), timeout );
-
-               debug_error(" [%s] state : %s   pending : %s \n",
-                       GST_ELEMENT_NAME(element),
-                       gst_element_state_get_name(element_state),
-                       gst_element_state_get_name(element_pending_state) );
-
-               /* dump state of all element */
-               __mmplayer_dump_pipeline_state( player );
-
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       debug_log("[%s] element state has changed to %s \n",
-               GST_ELEMENT_NAME(element),
-               gst_element_state_get_name(element_state));
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static void
+void
 __mmplayer_videostream_cb(GstElement *element, void *stream,
 int width, int height, gpointer data) // @
 {
@@ -527,7 +395,7 @@ int width, int height, gpointer data) // @
        debug_fleave();
 }
 
-static void
+void
 __mmplayer_videoframe_render_error_cb(GstElement *element, void *error_id, gpointer data)
 {
        mm_player_t* player = (mm_player_t*)data;
@@ -1414,5926 +1282,1518 @@ __mmplayer_handle_buffering_message ( mm_player_t* player )
        }
 }
 
+
 static gboolean
-__mmplayer_gst_callback(GstBus *bus, GstMessage *msg, gpointer data) // @
+__mmplayer_get_property_value_for_rotation(mm_player_t* player, int rotation_angle, int *value)
 {
-       mm_player_t* player = (mm_player_t*) data;
-       gboolean ret = TRUE;
-       static gboolean async_done = FALSE;
+       int pro_value = 0; // in the case of expection, default will be returned.
+       int dest_angle = rotation_angle;
+       int rotation_using_type = -1;
+       #define ROTATION_USING_X        0
+       #define ROTATION_USING_FIMC     1
+       #define ROTATION_USING_FLIP     2
 
-       return_val_if_fail ( player, FALSE );
-       return_val_if_fail ( msg && GST_IS_MESSAGE(msg), FALSE );
+       return_val_if_fail(player, FALSE);
+       return_val_if_fail(value, FALSE);
+       return_val_if_fail(rotation_angle >= 0, FALSE);
 
-#ifdef GST_API_VERSION_1
-       const GstStructure *structure;
-       structure = gst_message_get_structure (msg);
-#endif
+       if (rotation_angle >= 360)
+       {
+               dest_angle = rotation_angle - 360;
+       }
 
-       switch ( GST_MESSAGE_TYPE( msg ) )
+       /* chech if supported or not */
+       if ( dest_angle % 90 )
        {
-               case GST_MESSAGE_UNKNOWN:
-                       debug_warning("unknown message received\n");
-               break;
+               debug_log("not supported rotation angle = %d", rotation_angle);
+               return FALSE;
+       }
+
+       if (player->use_video_stream)
+       {
+               if (player->is_nv12_tiled)
+               {
+                       rotation_using_type = ROTATION_USING_FIMC;
+               }
+               else
+               {
+                       rotation_using_type = ROTATION_USING_FLIP;
+               }
+       }
+       else
+       {
+               int surface_type = 0;
+               mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
+               debug_log("check display surface type for rotation: %d", surface_type);
 
-               case GST_MESSAGE_EOS:
+               switch (surface_type)
                {
-                       MMHandleType attrs = 0;
-                       gint count = 0;
+                       case MM_DISPLAY_SURFACE_X:
+                               rotation_using_type = ROTATION_USING_X;
+                               break;
+                       case MM_DISPLAY_SURFACE_EVAS:
+                               if (player->is_nv12_tiled && !strcmp(PLAYER_INI()->videosink_element_evas,"evasimagesink"))
+                               {
+                                       rotation_using_type = ROTATION_USING_FIMC;
+                               }
+                               else if (!player->is_nv12_tiled)
+                               {
+                                       rotation_using_type = ROTATION_USING_FLIP;
+                               }
+                               else
+                               {
+                                       debug_error("it should not be here..");
+                                       return FALSE;
+                               }
+                               break;
+                       default:
+                               rotation_using_type = ROTATION_USING_FLIP;
+                               break;
+               }
+       }
 
-                       debug_log("GST_MESSAGE_EOS received\n");
+       debug_log("using %d type for rotation", rotation_using_type);
 
-                       /* 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) )
+       /* get property value for setting */
+       switch(rotation_using_type)
+       {
+               case ROTATION_USING_X: // xvimagesink
                        {
-                               debug_warning("EOS received on non-playing state. ignoring it\n");
-                               break;
+                               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;
+                               }
                        }
-
-                       if ( (player->audio_stream_cb) && (player->is_sound_extraction) )
+                       break;
+               case ROTATION_USING_FIMC: // fimcconvert
                        {
-                               GstPad *pad = NULL;
-
-                               pad = gst_element_get_static_pad (player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
-
-                               debug_error("release audio callback\n");
-
-                               /* release audio callback */
-#ifdef GST_API_VERSION_1
-                               gst_pad_remove_probe (pad, player->audio_cb_probe_id);
-#else
-                               gst_pad_remove_buffer_probe (pad, player->audio_cb_probe_id);
-#endif
-                               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;
-
+                                       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;
+                                       }
                        }
-
-                       /* rewind if repeat count is greater then zero */
-                       /* get play count */
-                       attrs = MMPLAYER_GET_ATTRS(player);
-
-                       if ( attrs )
+                       break;
+               case ROTATION_USING_FLIP: // videoflip
                        {
-                               gboolean smooth_repeat = FALSE;
-
-                               mm_attrs_get_int_by_name(attrs, "profile_play_count", &count);
-                               mm_attrs_get_int_by_name(attrs, "profile_smooth_repeat", &smooth_repeat);
-
-                               debug_log("remaining play count: %d, playback rate: %f\n", count, player->playback_rate);
-
-                               if ( count > 1 || count == -1 || player->playback_rate < 0.0 ) /* default value is 1 */
-                               {
-                                       if ( smooth_repeat )
+                                       switch (dest_angle)
                                        {
-                                               debug_log("smooth repeat enabled. seeking operation will be excuted in new thread\n");
 
-                                               g_cond_signal( player->repeat_thread_cond );
-
-                                               break;
+                                               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;
                                        }
-                                       else
-                                       {
-                                               gint ret_value = 0;
+                       }
+                       break;
+       }
 
-                                               if ( player->section_repeat )
-                                               {
-                                                       ret_value = _mmplayer_activate_section_repeat((MMHandleType)player, player->section_repeat_start, player->section_repeat_end);
-                                               }
-                                               else
-                                               {
+       debug_log("setting rotation property value : %d", pro_value);
 
-                                                       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 );
-                                                       }
+       *value = pro_value;
 
-                                                       ret_value = __gst_set_position( player, MM_PLAYER_POS_FORMAT_TIME, 0, TRUE);
+       return TRUE;
+}
 
-                                                       /* initialize */
-                                                       player->sent_bos = FALSE;
-                                               }
+int
+_mmplayer_update_video_param(mm_player_t* player) // @
+{
+       MMHandleType attrs = 0;
+       int surface_type = 0;
+       int org_angle = 0; // current supported angle values are 0, 90, 180, 270
+       int user_angle = 0;
+       int user_angle_type= 0;
+       int rotation_value = 0;
 
-                                               if ( MM_ERROR_NONE != ret_value )
-                                               {
-                                                       debug_error("failed to set position to zero for rewind\n");
-                                               }
-                                               else
-                                               {
-                                                       if ( count > 1 )
-                                                       {
-                                                               /* we successeded to rewind. update play count and then wait for next EOS */
-                                                               count--;
+       debug_fenter();
 
-                                                               mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
+       /* check video sinkbin is created */
+       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 );
 
-                                                               if ( mmf_attrs_commit ( attrs ) )
-                                                                       debug_error("failed to commit attrs\n");
-                                                       }
-                                               }
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-                                               break;
-                                       }
-                               }
-                       }
+       /* update user roation */
+       mm_attrs_get_int_by_name(attrs, "display_rotation", &user_angle_type);
 
-                       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-eos" );
+       /* get angle with user type */
+       switch(user_angle_type)
+       {
+               case MM_DISPLAY_ROTATION_NONE:
+                       user_angle = 0;
+                       break;
+               case MM_DISPLAY_ROTATION_90: // counter-clockwise 90
+                       user_angle = 270;
+                       break;
+               case MM_DISPLAY_ROTATION_180:
+                       user_angle = 180;
+                       break;
+               case MM_DISPLAY_ROTATION_270: // clockwise 90
+                       user_angle = 90;
+                       break;
+       }
 
-                       /* post eos message to application */
-                       __mmplayer_post_delayed_eos( player, PLAYER_INI()->eos_delay );
+       /* get original orientation */
+       if (player->v_stream_caps)
+       {
+               GstStructure *str = NULL;
 
-                       /* reset last position */
-                       player->last_position = 0;
+               str = gst_caps_get_structure (player->v_stream_caps, 0);
+               if ( !gst_structure_get_int (str, "orientation", &org_angle))
+               {
+                       debug_log ("missing 'orientation' field in video caps");
                }
-               break;
-
-               case GST_MESSAGE_ERROR:
+               else
                {
-                       GError *error = NULL;
-                       gchar* debug = NULL;
-                       gchar *msg_src_element = NULL;
+                       debug_log("origianl video orientation = %d", org_angle);
+               }
+       }
 
-                       /* generating debug info before returning error */
-                       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-error" );
+       debug_log("check user angle: %d, org angle: %d", user_angle, org_angle);
 
-                       /* get error code */
-                       gst_message_parse_error( msg, &error, &debug );
+       /* get rotation value to set */
+       __mmplayer_get_property_value_for_rotation(player, org_angle+user_angle, &rotation_value);
 
-                       msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( msg->src ) );
-#ifdef GST_API_VERSION_1
-                       if ( gst_structure_has_name ( structure, "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 );
+       /* check video stream callback is used */
+       if( player->use_video_stream )
+       {
+               if (player->is_nv12_tiled)
+               {
+                       gchar *ename = NULL;
+                       int width = 0;
+                       int height = 0;
 
-                               /* dump state of all element */
-                               __mmplayer_dump_pipeline_state( player );
+                       mm_attrs_get_int_by_name(attrs, "display_width", &width);
+                       mm_attrs_get_int_by_name(attrs, "display_height", &height);
 
-                       }
+                       /* resize video frame with requested values for fimcconvert */
+#ifdef GST_API_VERSION_1
+                       ename = GST_OBJECT (gst_element_get_factory(player->pipeline->videobin[MMPLAYER_V_CONV].gst));
 #else
-                       if ( gst_structure_has_name ( msg->structure, "streaming_error" ) )
-                       {
-                               /* Note : the streaming error from the streaming source is handled
-                                *   using __mmplayer_handle_streaming_error.
-                                */
-                               __mmplayer_handle_streaming_error ( player, msg );
+                       ename = GST_PLUGIN_FEATURE_NAME(gst_element_get_factory(player->pipeline->videobin[MMPLAYER_V_CONV].gst));
+#endif
 
-                               /* dump state of all element */
-                               __mmplayer_dump_pipeline_state( player );
-                       }
-                       else
+                       if (g_strrstr(ename, "fimcconvert"))
                        {
-                               /* traslate gst error code to msl error code. then post it
-                                * to application if needed
-                                */
-                               __mmplayer_handle_gst_error( player, msg, error );
+                               if (width)
+                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-width", width, NULL);
 
-                               /* dump state of all element */
-                               __mmplayer_dump_pipeline_state( player );
+                               if (height)
+                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-height", height, NULL);
 
+                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "rotate", rotation_value, NULL);
+                               debug_log("updating fimcconvert - r[%d], w[%d], h[%d]", rotation_value, width, height);
                        }
-
-#endif
-                       
-
-                       if (MMPLAYER_IS_HTTP_PD(player))
+                       else
                        {
-                               _mmplayer_unrealize_pd_downloader ((MMHandleType)player);
+                               debug_error("no available video converter");
+                               return MM_ERROR_PLAYER_INTERNAL;
                        }
-
-                       MMPLAYER_FREEIF( debug );
-                       g_error_free( error );
                }
-               break;
-
-               case GST_MESSAGE_WARNING:
+               else
                {
-                       char* debug = NULL;
-                       GError* error = NULL;
+                       debug_log("using video stream callback with memsink. player handle : [%p]", player);
 
-                       gst_message_parse_warning(msg, &error, &debug);
+                       g_object_set(player->pipeline->videobin[MMPLAYER_V_FLIP].gst, "method", rotation_value, NULL);
+               }
 
-                       debug_warning("warning : %s\n", error->message);
-                       debug_warning("debug : %s\n", debug);
+               return MM_ERROR_NONE;
+       }
 
-                       MMPLAYER_POST_MSG( player, MM_MESSAGE_WARNING, NULL );
+       /* update display surface */
+       mm_attrs_get_int_by_name(attrs, "display_surface_type", &surface_type);
+       debug_log("check display surface type attribute: %d", surface_type);
 
-                       MMPLAYER_FREEIF( debug );
-                       g_error_free( error );
-               }
-               break;
+       /* configuring display */
+       switch ( surface_type )
+       {
+               case MM_DISPLAY_SURFACE_X:
+               {
+                       /* ximagesink or xvimagesink */
+                       void *xid = NULL;
+                       int zoom = 0;
+                       int display_method = 0;
+                       int roi_x = 0;
+                       int roi_y = 0;
+                       int roi_w = 0;
+                       int roi_h = 0;
+                       int force_aspect_ratio = 0;
+                       gboolean visible = TRUE;
 
-               case GST_MESSAGE_INFO:                          debug_log("GST_MESSAGE_STATE_DIRTY\n"); break;
+                       /* common case if using x surface */
+                       mm_attrs_get_data_by_name(attrs, "display_overlay", &xid);
+                       if ( xid )
+                       {
+#define GST_VAAPI_DISPLAY_TYPE_X11 1
+                if (!strncmp(PLAYER_INI()->videosink_element_x,"vaapisink", strlen("vaapisink"))){
+                    debug_log("set video param: vaapisink display %d", GST_VAAPI_DISPLAY_TYPE_X11);
+                    g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                            "display", GST_VAAPI_DISPLAY_TYPE_X11,
+                            NULL);
+                }
 
-               case GST_MESSAGE_TAG:
-               {
-                       debug_log("GST_MESSAGE_TAG\n");
-                       if ( ! __mmplayer_gst_extract_tag_from_msg( player, msg ) )
+                               debug_log("set video param : xid %d", *(int*)xid);
+#ifdef GST_API_VERSION_1
+                               gst_video_overlay_set_window_handle( GST_VIDEO_OVERLAY( player->pipeline->videobin[MMPLAYER_V_SINK].gst ), *(int*)xid );
+#else
+                               gst_x_overlay_set_xwindow_id( GST_X_OVERLAY( player->pipeline->videobin[MMPLAYER_V_SINK].gst ), *(int*)xid );
+#endif
+                       }
+                       else
                        {
-                               debug_warning("failed to extract tags from gstmessage\n");
+                               /* FIXIT : is it error case? */
+                               debug_warning("still we don't have xid on player attribute. create it's own surface.");
                        }
-               }
-               break;
 
-               case GST_MESSAGE_BUFFERING:
-               {
-                       MMMessageParamType msg_param = {0, };
-                       gboolean update_buffering_percent = TRUE;
-
-                       if ( !MMPLAYER_IS_STREAMING(player) || (player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS) ) // pure hlsdemux case, don't consider buffering of msl currently
-                               break;
-
-                       __mm_player_streaming_buffering (player->streamer, msg);
+                       /* if xvimagesink */
+                       if (!strcmp(PLAYER_INI()->videosink_element_x,"xvimagesink"))
+                       {
+                               mm_attrs_get_int_by_name(attrs, "display_force_aspect_ration", &force_aspect_ratio);
+                               mm_attrs_get_int_by_name(attrs, "display_zoom", &zoom);
+                               mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_x", &roi_x);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_y", &roi_y);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_width", &roi_w);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_height", &roi_h);
+                               mm_attrs_get_int_by_name(attrs, "display_visible", &visible);
 
-                       __mmplayer_handle_buffering_message ( player );
+                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                       "force-aspect-ratio", force_aspect_ratio,
+                                       "zoom", zoom,
+                                       "rotate", rotation_value,
+                                       "handle-events", TRUE,
+                                       "display-geometry-method", display_method,
+                                       "draw-borders", FALSE,
+                                       "dst-roi-x", roi_x,
+                                       "dst-roi-y", roi_y,
+                                       "dst-roi-w", roi_w,
+                                       "dst-roi-h", roi_h,
+                                       "visible", visible,
+                                       NULL );
 
-                       update_buffering_percent = (player->pipeline_is_constructed || MMPLAYER_IS_RTSP_STREAMING(player) );
-                       if (update_buffering_percent)
-                       {
-                               msg_param.connection.buffering = player->streamer->buffering_percent;
-                               MMPLAYER_POST_MSG ( player, MM_MESSAGE_BUFFERING, &msg_param );
+                               debug_log("set video param : zoom %d", zoom);
+                               debug_log("set video param : rotate %d", rotation_value);
+                               debug_log("set video param : method %d", display_method);
+                               debug_log("set video param : dst-roi-x: %d, dst-roi-y: %d, dst-roi-w: %d, dst-roi-h: %d",
+                                                               roi_x, roi_y, roi_w, roi_h );
+                               debug_log("set video param : visible %d", visible);
+                               debug_log("set video param : force aspect ratio %d", force_aspect_ratio);
                        }
+
+            /* if vaapisink */
+            if (!strncmp(PLAYER_INI()->videosink_element_x, "vaapisink", strlen("vaapisink")))
+            {
+                g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                        "rotation", rotation_value,
+                        NULL);
+                debug_log("set video param: vaapisink rotation %d", rotation_value);
+            }
                }
                break;
-
-               case GST_MESSAGE_STATE_CHANGED:
+               case MM_DISPLAY_SURFACE_EVAS:
                {
-                       MMPlayerGstElement *mainbin;
-                       const GValue *voldstate, *vnewstate, *vpending;
-                       GstState oldstate, newstate, pending;
+                       void *object = NULL;
+                       int scaling = 0;
+                       gboolean visible = TRUE;
 
-                       if ( ! ( player->pipeline && player->pipeline->mainbin ) )
+                       /* common case if using evas surface */
+                       mm_attrs_get_data_by_name(attrs, "display_overlay", &object);
+                       mm_attrs_get_int_by_name(attrs, "display_visible", &visible);
+                       mm_attrs_get_int_by_name(attrs, "display_evas_do_scaling", &scaling);
+                       if (object)
                        {
-                               debug_error("player pipeline handle is null");
-                               break;
+                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                               "evas-object", object,
+                                               "visible", visible,
+                                               NULL);
+                               debug_log("set video param : evas-object %x", object);
+                               debug_log("set video param : visible %d", visible);
                        }
-
-                       mainbin = player->pipeline->mainbin;
-
-                       /* we only handle messages from pipeline */
-                       if( msg->src != (GstObject *)mainbin[MMPLAYER_M_PIPE].gst )
-                               break;
-
-                       /* get state info from msg */
-#ifdef GST_API_VERSION_1
-                       voldstate = gst_structure_get_value (structure, "old-state");
-                       vnewstate = gst_structure_get_value (structure, "new-state");
-                       vpending = gst_structure_get_value (structure, "pending-state");                        
-#else
-                       voldstate = gst_structure_get_value (msg->structure, "old-state");
-                       vnewstate = gst_structure_get_value (msg->structure, "new-state");
-                       vpending = gst_structure_get_value (msg->structure, "pending-state");
-#endif
-
-                       oldstate = (GstState)voldstate->data[0].v_int;
-                       newstate = (GstState)vnewstate->data[0].v_int;
-                       pending = (GstState)vpending->data[0].v_int;
-
-                       debug_log("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 ) );
-
-                       if (oldstate == newstate)
+                       else
                        {
-                               debug_warning("pipeline reports state transition to old state");
-                               break;
+                               debug_error("no evas object");
+                               return MM_ERROR_PLAYER_INTERNAL;
                        }
 
-                       switch(newstate)
+                       /* if evasimagesink */
+                       if (!strcmp(PLAYER_INI()->videosink_element_evas,"evasimagesink") && player->is_nv12_tiled)
                        {
-                               case GST_STATE_VOID_PENDING:
-                               break;
+                               int width = 0;
+                               int height = 0;
+                               int no_scaling = !scaling;
 
-                               case GST_STATE_NULL:
-                               break;
+                               mm_attrs_get_int_by_name(attrs, "display_width", &width);
+                               mm_attrs_get_int_by_name(attrs, "display_height", &height);
 
-                               case GST_STATE_READY:
-                               break;
+                               /* NOTE: fimcconvert does not manage index of src buffer from upstream src-plugin, decoder gives frame information in output buffer with no ordering */
+                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-buffer-num", 5, NULL);
 
-                               case GST_STATE_PAUSED:
+                               if (no_scaling)
                                {
-                                       gboolean prepare_async = FALSE;
-
-                                       if ( ! player->audio_cb_probe_id && player->is_sound_extraction )
-                                               __mmplayer_configure_audio_callback(player);
-
-                                       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);
-                                               debug_log("checking prepare mode for async transition - %d", prepare_async);
-                                       }
-
-                                       if ( MMPLAYER_IS_STREAMING(player) || prepare_async )
-                                       {
-                                               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PAUSED );
-
-                                               if (player->streamer)
-                                               {
-                                                       __mm_player_streaming_set_content_bitrate(player->streamer,
-                                                               player->total_maximum_bitrate, player->total_bitrate);
-                                               }
-                                       }
+                                       /* no-scaling order to fimcconvert, original width, height size of media src will be passed to sink plugin */
+                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst,
+                                                       "dst-width", 0, /* setting 0, output video width will be media src's width */
+                                                       "dst-height", 0, /* setting 0, output video height will be media src's height */
+                                                       NULL);
                                }
-                               break;
-
-                               case GST_STATE_PLAYING:
+                               else
                                {
-                                       if (player->doing_seek && async_done)
+                                       /* scaling order to fimcconvert */
+                                       if (width)
                                        {
-                                               player->doing_seek = FALSE;
-                                               async_done = FALSE;
-                                               MMPLAYER_POST_MSG ( player, MM_MESSAGE_SEEK_COMPLETED, NULL );
+                                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-width", width, NULL);
                                        }
-
-                                       if ( MMPLAYER_IS_STREAMING(player) ) // managed prepare async case when buffering is completed
+                                       if (height)
                                        {
-                                               // pending state should be reset oyherwise, it's still playing even though it's resumed after bufferging.
-                                               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PLAYING);
+                                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-height", height, NULL);
                                        }
+                                       debug_log("set video param : video frame scaling down to width(%d) height(%d)", width, height);
                                }
-                               break;
-
-                               default:
-                               break;
+                               debug_log("set video param : display_evas_do_scaling %d", scaling);
                        }
-               }
-               break;
 
-               case GST_MESSAGE_STATE_DIRTY:           debug_log("GST_MESSAGE_STATE_DIRTY\n"); break;
-               case GST_MESSAGE_STEP_DONE:                     debug_log("GST_MESSAGE_STEP_DONE\n"); break;
-               case GST_MESSAGE_CLOCK_PROVIDE:         debug_log("GST_MESSAGE_CLOCK_PROVIDE\n"); break;
-
-               case GST_MESSAGE_CLOCK_LOST:
+                       /* if evaspixmapsink */
+                       if (!strcmp(PLAYER_INI()->videosink_element_evas,"evaspixmapsink"))
                        {
-                               GstClock *clock = NULL;
-                               gst_message_parse_clock_lost (msg, &clock);
-                               debug_log("GST_MESSAGE_CLOCK_LOST : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
-                               g_print ("GST_MESSAGE_CLOCK_LOST : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
-
-                               if (PLAYER_INI()->provide_clock)
-                               {
-                                       debug_log ("Provide clock is TRUE, do pause->resume\n");
-                                       __gst_pause(player, FALSE);
-                                       __gst_resume(player, FALSE);
-                               }
-                       }
-                       break;
+                               int display_method = 0;
+                               int roi_x = 0;
+                               int roi_y = 0;
+                               int roi_w = 0;
+                               int roi_h = 0;
+                               int origin_size = !scaling;
 
-               case GST_MESSAGE_NEW_CLOCK:
-                       {
-                               GstClock *clock = NULL;
-                               gst_message_parse_new_clock (msg, &clock);
-                               debug_log("GST_MESSAGE_NEW_CLOCK : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
-                       }
-                       break;
+                               mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_x", &roi_x);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_y", &roi_y);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_width", &roi_w);
+                               mm_attrs_get_int_by_name(attrs, "display_roi_height", &roi_h);
 
-               case GST_MESSAGE_STRUCTURE_CHANGE:      debug_log("GST_MESSAGE_STRUCTURE_CHANGE\n"); break;
-               case GST_MESSAGE_STREAM_STATUS:         debug_log("GST_MESSAGE_STREAM_STATUS\n"); break;
-               case GST_MESSAGE_APPLICATION:           debug_log("GST_MESSAGE_APPLICATION\n"); break;
+                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                       "origin-size", origin_size,
+                                       "dst-roi-x", roi_x,
+                                       "dst-roi-y", roi_y,
+                                       "dst-roi-w", roi_w,
+                                       "dst-roi-h", roi_h,
+                                       "display-geometry-method", display_method,
+                                       NULL );
 
-               case GST_MESSAGE_ELEMENT:
-               {
-                       debug_log("GST_MESSAGE_ELEMENT\n");
+                               debug_log("set video param : method %d", display_method);
+                               debug_log("set video param : dst-roi-x: %d, dst-roi-y: %d, dst-roi-w: %d, dst-roi-h: %d",
+                                                               roi_x, roi_y, roi_w, roi_h );
+                               debug_log("set video param : display_evas_do_scaling %d (origin-size %d)", scaling, origin_size);
+                       }
+                       g_object_set(player->pipeline->videobin[MMPLAYER_V_FLIP].gst, "method", rotation_value, NULL);
                }
                break;
-
-               case GST_MESSAGE_SEGMENT_START:         debug_log("GST_MESSAGE_SEGMENT_START\n"); break;
-               case GST_MESSAGE_SEGMENT_DONE:          debug_log("GST_MESSAGE_SEGMENT_DONE\n"); break;
-
-               case GST_MESSAGE_DURATION:
+               case MM_DISPLAY_SURFACE_X_EXT:  /* NOTE : this surface type is used for the videoTexture(canvasTexture) overlay */
                {
-                       debug_log("GST_MESSAGE_DURATION\n");
-                       ret = __mmplayer_gst_handle_duration(player, msg);
-                       if (!ret)
+                       void *pixmap_id_cb = NULL;
+                       void *pixmap_id_cb_user_data = NULL;
+                       int display_method = 0;
+                       gboolean visible = TRUE;
+
+                       /* if xvimagesink */
+                       if (strcmp(PLAYER_INI()->videosink_element_x,"xvimagesink"))
                        {
-                               debug_warning("failed to update duration");
+                               debug_error("videosink is not xvimagesink");
+                               return MM_ERROR_PLAYER_INTERNAL;
                        }
-               }
-
-               break;
-
 
-               case GST_MESSAGE_LATENCY:                               debug_log("GST_MESSAGE_LATENCY\n"); break;
-               case GST_MESSAGE_ASYNC_START:           debug_log("GST_MESSAGE_ASYNC_DONE : %s\n", gst_element_get_name(GST_MESSAGE_SRC(msg))); break;
-
-               case GST_MESSAGE_ASYNC_DONE:
-               {
-                       debug_log("GST_MESSAGE_ASYNC_DONE : %s\n", gst_element_get_name(GST_MESSAGE_SRC(msg)));
+                       /* get information from attributes */
+                       mm_attrs_get_data_by_name(attrs, "display_overlay", &pixmap_id_cb);
+                       mm_attrs_get_data_by_name(attrs, "display_overlay_user_data", &pixmap_id_cb_user_data);
+                       mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
 
-                       if (player->doing_seek)
+                       if ( pixmap_id_cb )
                        {
-                               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)
+                               debug_log("set video param : display_overlay(0x%x)", pixmap_id_cb);
+                               if (pixmap_id_cb_user_data)
                                {
-                                       async_done = TRUE;
+                                       debug_log("set video param : display_overlay_user_data(0x%x)", pixmap_id_cb_user_data);
                                }
                        }
+                       else
+                       {
+                               debug_error("failed to set pixmap-id-callback");
+                               return MM_ERROR_PLAYER_INTERNAL;
+                       }
+                       debug_log("set video param : method %d", display_method);
+                       debug_log("set video param : visible %d", visible);
+
+                       /* set properties of videosink plugin */
+                       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                               "display-geometry-method", display_method,
+                               "draw-borders", FALSE,
+                               "visible", visible,
+                               "rotate", rotation_value,
+                               "pixmap-id-callback", pixmap_id_cb,
+                               "pixmap-id-callback-userdata", pixmap_id_cb_user_data,
+                               NULL );
                }
                break;
-
-               case GST_MESSAGE_REQUEST_STATE:         debug_log("GST_MESSAGE_REQUEST_STATE\n"); break;
-               case GST_MESSAGE_STEP_START:            debug_log("GST_MESSAGE_STEP_START\n"); break;
-               case GST_MESSAGE_QOS:                                   debug_log("GST_MESSAGE_QOS\n"); break;
-               case GST_MESSAGE_PROGRESS:                      debug_log("GST_MESSAGE_PROGRESS\n"); break;
-               case GST_MESSAGE_ANY:                           debug_log("GST_MESSAGE_ANY\n"); break;
-
-               default:
-                       debug_warning("unhandled message\n");
+               case MM_DISPLAY_SURFACE_NULL:
+               {
+                       /* do nothing */
+               }
                break;
        }
 
-       /* FIXIT : this cause so many warnings/errors from glib/gstreamer. we should not call it since
-        * gst_element_post_message api takes ownership of the message.
-        */
-       //gst_message_unref( msg );
+       debug_fleave();
 
-       return ret;
+       return MM_ERROR_NONE;
 }
 
 static gboolean
-__mmplayer_gst_handle_duration(mm_player_t* player, GstMessage* msg)
+__mmplayer_audio_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data)
 {
-       GstFormat format;
-       gint64 bytes = 0;
-
-       debug_fenter();
+       mm_player_t* player = (mm_player_t*) u_data;
+       gint size;
+       guint8 *data;
 
-       return_val_if_fail(player, FALSE);
-       return_val_if_fail(msg, FALSE);
+#ifdef GST_API_VERSION_1
+       GstMapInfo info;
+       gst_buffer_map (buffer, &info, GST_MAP_WRITE);
+       data = info.data;
+       size = gst_buffer_get_size(buffer);
 
-       gst_message_parse_duration (msg, &format, &bytes);
+       if (player->audio_stream_cb && size && data)
+               player->audio_stream_cb((void *)data, size, player->audio_stream_cb_user_param);
 
-       if (MMPLAYER_IS_HTTP_STREAMING(player) && format == GST_FORMAT_BYTES )
-       {
-               debug_log("data total size of http content: %lld", bytes);
-               player->http_content_size = bytes;
-       }
-       else if (format == GST_FORMAT_TIME)
-       {
-               /* handling audio clip which has vbr. means duration is keep changing */
-               _mmplayer_update_content_attrs (player, ATTR_DURATION );
-       }
-       else
-       {
-               debug_warning("duration is neither BYTES or TIME");
-               return FALSE;
-       }
+       gst_buffer_unmap (buffer, &info);
+#else
+       data = GST_BUFFER_DATA(buffer);
+       size = GST_BUFFER_SIZE(buffer);
 
-       debug_fleave();
+       if (player->audio_stream_cb && size && data)
+               player->audio_stream_cb((void *)data, size, player->audio_stream_cb_user_param);
+#endif
 
        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)\
-       {\
-               debug_log ( "update tag string : %s\n", string); \
-               mm_attrs_set_string_by_name(attribute, playertag, string); \
-               g_free(string);\
-               string = NULL;\
-       }\
-}
-
 #ifdef GST_API_VERSION_1
-#define MMPLAYER_UPDATE_TAG_IMAGE(gsttag, attribute, playertag) \
-value = gst_tag_list_get_value_index(tag_list, gsttag, index); \
-if (value) \
-{\
-       GstMapInfo info; \
-       gst_buffer_map (buffer, &info, GST_MAP_WRITE); \
-       buffer = gst_value_get_buffer (value); \
-       debug_log ( "update album cover data : %p, size : %d\n", info.data, gst_buffer_get_size(buffer)); \
-       player->album_art = (gchar *)g_malloc(gst_buffer_get_size(buffer)); \
-       if (player->album_art); \
-       { \
-               memcpy(player->album_art, info.data, gst_buffer_get_size(buffer)); \
-               mm_attrs_set_data_by_name(attribute, playertag, (void *)player->album_art, gst_buffer_get_size(buffer)); \
-       } \
-gst_buffer_unmap (buffer, &info); \
-}
-#else
-#define MMPLAYER_UPDATE_TAG_IMAGE(gsttag, attribute, playertag) \
-value = gst_tag_list_get_value_index(tag_list, gsttag, index); \
-if (value) \
-{\
-       buffer = gst_value_get_buffer (value); \
-       debug_log ( "update album cover data : %p, size : %d\n", GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); \
-       player->album_art = (gchar *)g_malloc(GST_BUFFER_SIZE(buffer)); \
-       if (player->album_art); \
-       { \
-               memcpy(player->album_art, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); \
-               mm_attrs_set_data_by_name(attribute, playertag, (void *)player->album_art, GST_BUFFER_SIZE(buffer)); \
-       } \
-}
-#endif
-
-#define MMPLAYER_UPDATE_TAG_UINT(gsttag, attribute, playertag) \
-if (gst_tag_list_get_uint(tag_list, gsttag, &v_uint))\
-{\
-       if(v_uint)\
-       {\
-               if(gsttag==GST_TAG_BITRATE)\
-               {\
-                       if (player->updated_bitrate_count == 0) \
-                               mm_attrs_set_int_by_name(attribute, "content_audio_bitrate", v_uint); \
-                       if (player->updated_bitrate_count<MM_PLAYER_STREAM_COUNT_MAX) \
-                       {\
-                               player->bitrate[player->updated_bitrate_count] = v_uint;\
-                               player->total_bitrate += player->bitrate[player->updated_maximum_bitrate_count]; \
-                               player->updated_bitrate_count++; \
-                               mm_attrs_set_int_by_name(attribute, playertag, player->total_bitrate);\
-                               debug_log ( "update bitrate %d[bps] of stream #%d.\n", v_uint, player->updated_bitrate_count);\
-                       }\
-               }\
-               else if (gsttag==GST_TAG_MAXIMUM_BITRATE)\
-               {\
-                       if (player->updated_maximum_bitrate_count<MM_PLAYER_STREAM_COUNT_MAX) \
-                       {\
-                               player->maximum_bitrate[player->updated_maximum_bitrate_count] = v_uint;\
-                               player->total_maximum_bitrate += player->maximum_bitrate[player->updated_maximum_bitrate_count]; \
-                               player->updated_maximum_bitrate_count++; \
-                               mm_attrs_set_int_by_name(attribute, playertag, player->total_maximum_bitrate); \
-                               debug_log ( "update maximum bitrate %d[bps] of stream #%d\n", v_uint, player->updated_maximum_bitrate_count);\
-                       }\
-               }\
-               else\
-               {\
-                       mm_attrs_set_int_by_name(attribute, playertag, v_uint); \
-               }\
-               v_uint = 0;\
-       }\
-}
+gboolean
+__mmplayer_update_subtitle( GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data)
+{
+       mm_player_t* player = (mm_player_t*) data;
+       MMMessageParamType msg = {0, };
+       GstClockTime duration = 0;
+       guint8 *text = NULL;
+       gboolean ret = TRUE;
+       GstMapInfo info;
 
-#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);\
-               debug_log ( "metainfo year : %s\n", string);\
-               MMPLAYER_FREEIF(string);\
-               g_date_free(date);\
-       }\
-}
+       debug_fenter();
 
-#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;\
-       }\
-}
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( buffer, FALSE );
 
-#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;\
-       }\
-}
+       gst_buffer_map (buffer, &info, GST_MAP_WRITE);
+       text = info.data;
+       gst_buffer_unmap (buffer, &info);
 
-       /* function start */
-       GstTagList* tag_list = NULL;
+       duration = GST_BUFFER_DURATION(buffer);
 
-       MMHandleType attrs = 0;
+       if ( player->is_subtitle_off )
+       {
+               debug_log("subtitle is OFF.\n" );
+               return TRUE;
+       }
 
-       char *string = NULL;
-       guint v_uint = 0;
-       GDate *date = NULL;
-       /* album cover */
-       GstBuffer *buffer = NULL;
-       gint index = 0;
-       const GValue *value;
+       if ( !text )
+       {
+               debug_log("There is no subtitle to be displayed.\n" );
+               return TRUE;
+       }
 
-       /* currently not used. but those are needed for above macro */
-       //guint64 v_uint64 = 0;
-       //gdouble v_double = 0;
+       msg.data = (void *) text;
+       msg.subtitle.duration = GST_TIME_AS_MSECONDS(duration);
 
-       return_val_if_fail( player && msg, FALSE );
+       debug_warning("update subtitle : [%ld msec] %s\n'", msg.subtitle.duration, (char*)msg.data );
 
-       attrs = MMPLAYER_GET_ATTRS(player);
+       MMPLAYER_POST_MSG( player, MM_MESSAGE_UPDATE_SUBTITLE, &msg );
 
-       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_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_IMAGE(GST_TAG_IMAGE, attrs, "tag_album_cover");
-       /* 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, ?, ?); */
-
-       if ( mmf_attrs_commit ( attrs ) )
-               debug_error("failed to commit.\n");
-
-       gst_tag_list_free(tag_list);
+       debug_fleave();
 
-       return TRUE;
+       return ret;
 }
-
-static void
-__mmplayer_gst_rtp_no_more_pads (GstElement *element,  gpointer data)  // @
+#else
+gboolean
+__mmplayer_update_subtitle( GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data)
 {
        mm_player_t* player = (mm_player_t*) data;
+       MMMessageParamType msg = {0, };
+       GstClockTime duration = 0;
+       guint8 *text = NULL;
+       gboolean ret = TRUE;
 
        debug_fenter();
 
-       /* 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 mo more pad will be added.
-         * So we can say this. if num_dynamic_pad is zero, it must be one of followings
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( buffer, FALSE );
 
-         * [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 )
+       text = GST_BUFFER_DATA(buffer);
+       duration = GST_BUFFER_DURATION(buffer);
+
+       if ( player->is_subtitle_off )
        {
-               debug_log("it seems pad caps is directely used for autoplugging. removing fakesink now\n");
+               debug_log("subtitle is OFF.\n" );
+               return TRUE;
+       }
 
-               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 ( !text )
+       {
+               debug_log("There is no subtitle to be displayed.\n" );
+               return TRUE;
        }
 
-       /* create dot before error-return. for debugging */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-no-more-pad" );
+       msg.data = (void *) text;
+       msg.subtitle.duration = GST_TIME_AS_MSECONDS(duration);
 
-       /* NOTE : if rtspsrc goes to PLAYING before adding it's src pads, a/v sink elements will
-        * not goes to PLAYING. they will just remain in PAUSED state. simply we are giving
-        * PLAYING state again.
-        */
-       __mmplayer_gst_set_state(player,
-               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, TRUE, 5000 );
+       debug_warning("update subtitle : [%ld msec] %s\n'", msg.subtitle.duration, (char*)msg.data );
 
-       player->no_more_pad = TRUE;
+       MMPLAYER_POST_MSG( player, MM_MESSAGE_UPDATE_SUBTITLE, &msg );
 
        debug_fleave();
+
+       return ret;
 }
+#endif
 
-static gboolean
-__mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink) // @
+#ifdef GST_API_VERSION_1
+int
+_mmplayer_push_buffer(MMHandleType hplayer, unsigned char *buf, int size) // @
 {
-       GstElement* parent = NULL;
-
-       return_val_if_fail(player && player->pipeline && fakesink, FALSE);
+       mm_player_t* player = (mm_player_t*)hplayer;
+       GstBuffer *buffer = NULL;
+       GstMapInfo info;
+       GstFlowReturn gst_ret = GST_FLOW_OK;
+       int ret = MM_ERROR_NONE;
 
-       /* lock */
-       g_mutex_lock( player->fsink_lock );
+       debug_fenter();
 
-       if ( ! fakesink->gst )
-       {
-               goto ERROR;
-       }
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       /* get parent of fakesink */
-       parent = (GstElement*)gst_object_get_parent( (GstObject*)fakesink->gst );
-       if ( ! parent )
-       {
-               debug_log("fakesink already removed\n");
-               goto ERROR;
-       }
+       /* check current state */
+//     MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_START );
 
-       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
+       /* NOTE : we should check and create pipeline again if not created as we destroy
+        * whole pipeline when stopping in streamming playback
         */
-       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state (fakesink->gst, GST_STATE_NULL) )
+       if ( ! player->pipeline )
        {
-               debug_error("fakesink state change failure!\n");
-
-               /* FIXIT : should I return here? or try to proceed to next? */
-               /* return FALSE; */
+               if ( MM_ERROR_NONE != __gst_realize( player ) )
+               {
+                       debug_error("failed to realize before starting. only in streamming\n");
+                       return MM_ERROR_PLAYER_INTERNAL;
+               }
        }
 
-       /* remove fakesink from it's parent */
-       if ( ! gst_bin_remove( GST_BIN( parent ), fakesink->gst ) )
-       {
-               debug_error("failed to remove fakesink\n");
-
-               gst_object_unref( parent );
+       debug_msg("app-src: pushing data\n");
 
-               goto ERROR;
+       if ( buf == NULL )
+       {
+               debug_error("buf is null\n");
+               return MM_ERROR_NONE;
        }
 
-       gst_object_unref( parent );
-
-       debug_log("state-holder removed\n");
+       buffer = gst_buffer_new ();
 
-       gst_element_set_locked_state( fakesink->gst, FALSE );
-
-       g_mutex_unlock( player->fsink_lock );
-       return TRUE;
-
-ERROR:
-       if ( fakesink->gst )
+       if (size <= 0)
        {
-               gst_element_set_locked_state( fakesink->gst, FALSE );
+               debug_log("call eos appsrc\n");
+               g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "end-of-stream", &gst_ret);
+               return MM_ERROR_NONE;
        }
 
-       g_mutex_unlock( player->fsink_lock );
-       return FALSE;
-}
+       info.data = (guint8*)(buf);
+       gst_buffer_set_size(buffer, size);
+       gst_buffer_map (buffer, &info, GST_MAP_WRITE);
 
+       debug_log("feed buffer %p, length %u\n", buf, size);
+       g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "push-buffer", buffer, &gst_ret);
 
-static void
-__mmplayer_gst_rtp_dynamic_pad (GstElement *element, GstPad *pad, gpointer data) // @
-{
-       GstPad *sinkpad = NULL;
-       GstCaps* caps = NULL;
-       GstElement* new_element = NULL;
+       debug_fleave();
 
-       mm_player_t* player = (mm_player_t*) data;
+       return ret;
+}
+#else
+int
+_mmplayer_push_buffer(MMHandleType hplayer, unsigned char *buf, int size) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       GstBuffer *buffer = NULL;
+       GstFlowReturn gst_ret = GST_FLOW_OK;
+       int ret = MM_ERROR_NONE;
 
        debug_fenter();
 
-       return_if_fail( element && pad );
-       return_if_fail( player &&
-                                       player->pipeline &&
-                                       player->pipeline->mainbin );
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check current state */
+//     MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_START );
 
 
-       /* payload type is recognizable. increase num_dynamic and wait for sinkbin creation.
-        * num_dynamic_pad will decreased after creating a sinkbin.
+       /* NOTE : we should check and create pipeline again if not created as we destroy
+        * whole pipeline when stopping in streamming playback
         */
-       player->num_dynamic_pad++;
-       debug_log("stream count inc : %d\n", player->num_dynamic_pad);
-
-       /* perform autoplugging if dump is disabled */
-       if ( PLAYER_INI()->rtsp_do_typefinding )
+       if ( ! player->pipeline )
        {
-               /* create typefind */
-               new_element = gst_element_factory_make( "typefind", NULL );
-               if ( ! new_element )
+               if ( MM_ERROR_NONE != __gst_realize( player ) )
                {
-                       debug_error("failed to create typefind\n");
-                       goto ERROR;
+                       debug_error("failed to realize before starting. only in streamming\n");
+                       return MM_ERROR_PLAYER_INTERNAL;
                }
-
-               MMPLAYER_SIGNAL_CONNECT(        player,
-                                                                       G_OBJECT(new_element),
-                                                                       "have-type",
-                                                                       G_CALLBACK(__mmplayer_typefind_have_type),
-                                                                       (gpointer)player);
-
-               /* FIXIT : try to remove it */
-               player->have_dynamic_pad = FALSE;
        }
-       else  /* NOTE : use pad's caps directely. if enabled. what I am assuming is there's no elemnt has dynamic pad */
-       {
-               debug_log("using pad caps to autopluging instead of doing typefind\n");
-#ifdef GST_API_VERSION_1
-               caps = gst_pad_get_current_caps( pad );
-#else
-               caps = gst_pad_get_caps( pad );
-#endif
 
-               MMPLAYER_CHECK_NULL( caps );
+       debug_msg("app-src: pushing data\n");
 
-               /* clear  previous result*/
-               player->have_dynamic_pad = FALSE;
-
-               if ( ! __mmplayer_try_to_plug( player, pad, caps ) )
-               {
-                       debug_error("failed to autoplug for caps : %s\n", gst_caps_to_string( caps ) );
-                       goto ERROR;
-               }
+       if ( buf == NULL )
+       {
+               debug_error("buf is null\n");
+               return MM_ERROR_NONE;
+       }
 
-               /* check if there's dynamic pad*/
-               if( player->have_dynamic_pad )
-               {
-                       debug_error("using pad caps assums there's no dynamic pad !\n");
-                       debug_error("try with enalbing rtsp_do_typefinding\n");
-                       goto ERROR;
-               }
+       buffer = gst_buffer_new ();
 
-               gst_caps_unref( caps );
-               caps = NULL;
+       if (size <= 0)
+       {
+               debug_log("call eos appsrc\n");
+               g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "end-of-stream", &gst_ret);
+               return MM_ERROR_NONE;
        }
 
-       /* excute new_element if created*/
-       if ( new_element )
-       {
-               debug_log("adding new element to pipeline\n");
+       GST_BUFFER_DATA(buffer) = (guint8*)(buf);
+       GST_BUFFER_SIZE(buffer) = size;
 
-               /* set state to READY before add to bin */
-               MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_READY );
+       debug_log("feed buffer %p, length %u\n", buf, size);
+       g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "push-buffer", buffer, &gst_ret);
 
-               /* add new element to the pipeline */
-               if ( FALSE == gst_bin_add( GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), new_element)  )
-               {
-                       debug_error("failed to add autoplug element to bin\n");
-                       goto ERROR;
-               }
+       debug_fleave();
 
-               /* get pad from element */
-               sinkpad = gst_element_get_static_pad ( GST_ELEMENT(new_element), "sink" );
-               if ( !sinkpad )
-               {
-                       debug_error("failed to get sinkpad from autoplug element\n");
-                       goto ERROR;
-               }
+       return ret;
+}
+#endif
 
-               /* link it */
-               if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
-               {
-                       debug_error("failed to link autoplug element\n");
-                       goto ERROR;
-               }
+GstBusSyncReply
+__mmplayer_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data)
+{
+       mm_player_t *player = (mm_player_t *)data;
 
-               gst_object_unref (sinkpad);
-               sinkpad = NULL;
+       switch (GST_MESSAGE_TYPE (message))
+       {
+               case GST_MESSAGE_TAG:
+                       __mmplayer_gst_extract_tag_from_msg(player, message);
+                       break;
+               case GST_MESSAGE_DURATION:
+                       __mmplayer_gst_handle_duration(player, message);
+                       break;
 
-               /* run. setting PLAYING here since streamming source is live source */
-               MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_PLAYING );
+               default:
+                       return GST_BUS_PASS;
        }
+       gst_message_unref (message);
 
-       debug_fleave();
+       return GST_BUS_DROP;
+}
 
-       return;
+static void __mmplayer_do_sound_fadedown(mm_player_t* player, unsigned int time)
+{
+       debug_fenter();
 
-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));
+       return_if_fail(player
+               && player->pipeline
+               && player->pipeline->audiobin
+               && player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
 
-       if ( sinkpad )
-               gst_object_unref(GST_OBJECT(sinkpad));
+       g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "mute", 2, NULL);
 
-       if ( caps )
-               gst_object_unref(GST_OBJECT(caps));
+       usleep(time);
 
-       /* 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
-        */
+       debug_fleave();
 }
 
-
-static void
-__mmplayer_gst_decode_callback(GstElement *decodebin, GstPad *pad, gboolean last, gpointer data) // @
+static void __mmplayer_undo_sound_fadedown(mm_player_t* player)
 {
-       mm_player_t* player = NULL;
-       MMHandleType attrs = 0;
-       GstElement* pipeline = NULL;
-       GstCaps* caps = NULL;
-       GstStructure* str = NULL;
-       const gchar* name = NULL;
-       GstPad* sinkpad = NULL;
-       GstElement* sinkbin = NULL;
-
-       /* check handles */
-       player = (mm_player_t*) data;
-
-       return_if_fail( decodebin && pad );
-       return_if_fail(player && player->pipeline && player->pipeline->mainbin);
-
-       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
-       {
-               debug_error("cannot get content attribute\n");
-               goto ERROR;
-       }
+       debug_fenter();
 
-       /* get mimetype from caps */
-#ifdef GST_API_VERSION_1
-       caps = gst_pad_get_current_caps( pad );
-#else
-       caps = gst_pad_get_caps( pad );
-#endif
-       if ( !caps )
-       {
-               debug_error("cannot get caps from pad.\n");
-               goto ERROR;
-       }
+       return_if_fail(player
+               && player->pipeline
+               && player->pipeline->audiobin
+               && player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
 
-       str = gst_caps_get_structure( caps, 0 );
-       if ( ! str )
-       {
-               debug_error("cannot get structure from capse.\n");
-               goto ERROR;
-       }
+       g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "mute", 0, NULL);
 
-       name = gst_structure_get_name(str);
-       if ( ! name )
-       {
-               debug_error("cannot get mimetype from structure.\n");
-               goto ERROR;
-       }
+       debug_fleave();
+}
 
-       debug_log("detected mimetype : %s\n", name);
+static gboolean __mmfplayer_parse_profile(const char *uri, void *param, MMPlayerParseProfile* data) // @
+{
+       gboolean ret = FALSE;
+       char *path = NULL;
 
-       if (strstr(name, "audio"))
-       {
-               if (player->pipeline->audiobin == NULL)
-               {
-                       __ta__("__mmplayer_gst_create_audio_pipeline",
-                               if (MM_ERROR_NONE !=  __mmplayer_gst_create_audio_pipeline(player))
-                               {
-                                       debug_error("failed to create audiobin. continuing without audio\n");
-                                       goto ERROR;
-                               }
-                       )
+       debug_fenter();
 
-                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
-                       debug_log("creating audiosink bin success\n");
-               }
-               else
-               {
-                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
-                       debug_log("re-using audiobin\n");
-               }
+       return_val_if_fail ( uri , FALSE);
+       return_val_if_fail ( data , FALSE);
+       return_val_if_fail ( ( strlen(uri) <= MM_MAX_URL_LEN ), FALSE );
 
-               /* FIXIT : track number shouldn't be hardcoded */
-               mm_attrs_set_int_by_name(attrs, "content_audio_track_num", 1);
-               player->audiosink_linked  = 1;
+       memset(data, 0, sizeof(MMPlayerParseProfile));
 
-               sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "sink" );
-               if ( !sinkpad )
-               {
-                       debug_error("failed to get pad from sinkbin\n");
-                       goto ERROR;
-               }
-       }
-       else if (strstr(name, "video"))
+       if ((path = strstr(uri, "file://")))
        {
-               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);
+               if (util_exist_file_path(path + 7)) {
+                       strncpy(data->uri, path, MM_MAX_URL_LEN-1);
 
-                       if (surface_type == MM_DISPLAY_SURFACE_NULL)
+                       if ( util_is_sdp_file ( path ) )
                        {
-                               debug_log("not make videobin because it dose not want\n");
-                               goto ERROR;
+                               debug_log("uri is actually a file but it's sdp file. giving it to rtspsrc\n");
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
                        }
-
-                       __ta__("__mmplayer_gst_create_video_pipeline",
-                       if (MM_ERROR_NONE !=  __mmplayer_gst_create_video_pipeline(player, caps, surface_type) )
+                       else
                        {
-                               debug_error("failed to create videobin. continuing without video\n");
-                               goto ERROR;
+                               data->uri_type = MM_PLAYER_URI_TYPE_FILE;
                        }
-                       )
-
-                       sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
-                       debug_log("creating videosink bin success\n");
+                       ret = TRUE;
                }
                else
                {
-                       sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
-                       debug_log("re-using videobin\n");
+                       debug_warning("could  access %s.\n", path);
                }
-
-               /* FIXIT : track number shouldn't be hardcoded */
-               mm_attrs_set_int_by_name(attrs, "content_video_track_num", 1);
-               player->videosink_linked  = 1;
-
-               sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "sink" );
-               if ( !sinkpad )
-               {
-                       debug_error("failed to get pad from sinkbin\n");
-                       goto ERROR;
+       }
+       else if ((path = strstr(uri, "buff://")))
+       {
+                       data->uri_type = MM_PLAYER_URI_TYPE_BUFF;
+                       ret = TRUE;
+       }
+       else if ((path = strstr(uri, "rtsp://")))
+       {
+               if (strlen(path)) {
+                       strcpy(data->uri, uri);
+                       data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
+                       ret = TRUE;
                }
        }
-       else if (strstr(name, "text"))
+       else if ((path = strstr(uri, "http://")))
        {
-               if (player->pipeline->textbin == NULL)
-               {
-                       __ta__("__mmplayer_gst_create_text_pipeline",
-                               if (MM_ERROR_NONE !=  __mmplayer_gst_create_text_pipeline(player))
-                               {
-                                       debug_error("failed to create textbin. continuing without text\n");
-                                       goto ERROR;
-                               }
-                       )
+               if (strlen(path)) {
+                       strcpy(data->uri, uri);
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_HTTP;
 
-                       sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
-                       debug_log("creating textink bin success\n");
-               }
-               else
-               {
-                       sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
-                       debug_log("re-using textbin\n");
+                       ret = TRUE;
                }
+       }
+       else if ((path = strstr(uri, "https://")))
+       {
+               if (strlen(path)) {
+                       strcpy(data->uri, uri);
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_HTTP;
 
-                       /* FIXIT : track number shouldn't be hardcoded */
-                       mm_attrs_set_int_by_name(attrs, "content_text_track_num", 1);
-
-                       player->textsink_linked  = 1;
-                       debug_msg("player->textsink_linked set to 1\n");
-
-               sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "text_sink" );
-               if ( !sinkpad )
-               {
-                       debug_error("failed to get pad from sinkbin\n");
-                       goto ERROR;
+                       ret = TRUE;
                }
        }
-       else
+       else if ((path = strstr(uri, "rtspu://")))
        {
-               debug_warning("unknown type of elementary stream! ignoring it...\n");
-               goto ERROR;
+               if (strlen(path)) {
+                       strcpy(data->uri, uri);
+                       data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
+                       ret = TRUE;
+               }
        }
-
-       if ( sinkbin )
+       else if ((path = strstr(uri, "rtspr://")))
        {
-               /* warm up */
-               if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state( sinkbin, GST_STATE_READY ) )
-               {
-                       debug_error("failed to set state(READY) to sinkbin\n");
-                       goto ERROR;
-               }
+               strcpy(data->uri, path);
+               char *separater =strstr(path, "*");
 
-               /* add */
-               if ( FALSE == gst_bin_add( GST_BIN(pipeline), sinkbin ) )
-               {
-                       debug_error("failed to add sinkbin to pipeline\n");
-                       goto ERROR;
-               }
+               if (separater) {
+                       int urgent_len = 0;
+                       char *urgent = separater + strlen("*");
 
-               /* link */
-               if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
-               {
-                       debug_error("failed to get pad from sinkbin\n");
-                       goto ERROR;
+                       if ((urgent_len = strlen(urgent))) {
+                               data->uri[strlen(path) - urgent_len - strlen("*")] = '\0';
+                               strcpy(data->urgent, urgent);
+                               data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
+                               ret = TRUE;
+                       }
                }
-
-               /* run */
-               if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state( sinkbin, GST_STATE_PAUSED ) )
-               {
-                       debug_error("failed to set state(PLAYING) to sinkbin\n");
-                       goto ERROR;
+       }
+       else if ((path = strstr(uri, "mms://")))
+       {
+               if (strlen(path)) {
+                       strcpy(data->uri, uri);
+                       data->uri_type = MM_PLAYER_URI_TYPE_URL_MMS;
+                       ret = TRUE;
                }
-
-               gst_object_unref( sinkpad );
-               sinkpad = NULL;
        }
+       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,};
 
-       debug_log("linking sink bin success\n");
+                       if (seperator) {
+                               if ((buffer = strstr(path, "ext="))) {
+                                       buffer += strlen("ext=");
 
-       /* 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 */
-       player->num_dynamic_pad--;
+                                       if (strlen(buffer)) {
+                                               strcpy(ext, buffer);
 
-       debug_log("stream count dec : %d (num of dynamic pad)\n", player->num_dynamic_pad);
+                                               if ((seperator = strchr(ext, ','))
+                                                       || (seperator = strchr(ext, ' '))
+                                                       || (seperator = strchr(ext, '\0'))) {
+                                                       seperator[0] = '\0';
+                                               }
+                                       }
+                               }
 
-       if ( ( player->no_more_pad ) && ( player->num_dynamic_pad == 0 ) )
-       {
-               __mmplayer_pipeline_complete( NULL, player );
-       }
+                               if ((buffer = strstr(path, "size="))) {
+                                       buffer += strlen("size=");
 
-ERROR:
-       if ( caps )
-               gst_caps_unref( caps );
+                                       if (strlen(buffer) > 0) {
+                                               strcpy(size, buffer);
 
-       if ( sinkpad )
-               gst_object_unref(GST_OBJECT(sinkpad));
+                                               if ((seperator = strchr(size, ','))
+                                                       || (seperator = strchr(size, ' '))
+                                                       || (seperator = strchr(size, '\0'))) {
+                                                       seperator[0] = '\0';
+                                               }
 
-       /* flusing out new attributes */
-       if (  mmf_attrs_commit ( attrs ) )
-       {
-               debug_error("failed to comit attributes\n");
-       }
+                                               mem_size = atoi(size);
+                                       }
+                               }
+                       }
 
-       return;
-}
+                       debug_log("ext: %s, mem_size: %d, mmap(param): %p\n", ext, mem_size, param);
+                       if ( mem_size && param) {
+                               data->mem = param;
+                               data->mem_size = mem_size;
+                               data->uri_type = MM_PLAYER_URI_TYPE_MEM;
+                               ret = TRUE;
+                       }
+               }
+       }
+       else
+       {
+               /* if no protocol prefix exist. check file existence and then give file:// as it's prefix */
+               if (util_exist_file_path(uri))
+               {
+                       debug_warning("uri has no protocol-prefix. giving 'file://' by default.\n");
+                       g_snprintf(data->uri,  MM_MAX_URL_LEN, "file://%s", uri);
 
-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_using_type = -1;
-       #define ROTATION_USING_X        0
-       #define ROTATION_USING_FIMC     1
-       #define ROTATION_USING_FLIP     2
-
-       return_val_if_fail(player, FALSE);
-       return_val_if_fail(value, FALSE);
-       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 )
-       {
-               debug_log("not supported rotation angle = %d", rotation_angle);
-               return FALSE;
-       }
-
-       if (player->use_video_stream)
-       {
-               if (player->is_nv12_tiled)
-               {
-                       rotation_using_type = ROTATION_USING_FIMC;
-               }
-               else
-               {
-                       rotation_using_type = ROTATION_USING_FLIP;
-               }
-       }
-       else
-       {
-               int surface_type = 0;
-               mm_attrs_get_int_by_name(player->attrs, "display_surface_type", &surface_type);
-               debug_log("check display surface type for rotation: %d", surface_type);
-
-               switch (surface_type)
-               {
-                       case MM_DISPLAY_SURFACE_X:
-                               rotation_using_type = ROTATION_USING_X;
-                               break;
-                       case MM_DISPLAY_SURFACE_EVAS:
-                               if (player->is_nv12_tiled && !strcmp(PLAYER_INI()->videosink_element_evas,"evasimagesink"))
-                               {
-                                       rotation_using_type = ROTATION_USING_FIMC;
-                               }
-                               else if (!player->is_nv12_tiled)
-                               {
-                                       rotation_using_type = ROTATION_USING_FLIP;
-                               }
-                               else
-                               {
-                                       debug_error("it should not be here..");
-                                       return FALSE;
-                               }
-                               break;
-                       default:
-                               rotation_using_type = ROTATION_USING_FLIP;
-                               break;
-               }
-       }
-
-       debug_log("using %d type for rotation", rotation_using_type);
-
-       /* get property value for setting */
-       switch(rotation_using_type)
-       {
-               case ROTATION_USING_X: // xvimagesink
-                       {
-                               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_FIMC: // 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;
-       }
-
-       debug_log("setting rotation property value : %d", pro_value);
-
-       *value = pro_value;
-
-       return TRUE;
-}
-
-int
-_mmplayer_update_video_param(mm_player_t* player) // @
-{
-       MMHandleType attrs = 0;
-       int surface_type = 0;
-       int org_angle = 0; // current supported angle values are 0, 90, 180, 270
-       int user_angle = 0;
-       int user_angle_type= 0;
-       int rotation_value = 0;
-
-       debug_fenter();
-
-       /* check video sinkbin is created */
-       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 );
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
-       {
-               debug_error("cannot get content attribute");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       /* update user roation */
-       mm_attrs_get_int_by_name(attrs, "display_rotation", &user_angle_type);
-
-       /* get angle with user type */
-       switch(user_angle_type)
-       {
-               case MM_DISPLAY_ROTATION_NONE:
-                       user_angle = 0;
-                       break;
-               case MM_DISPLAY_ROTATION_90: // counter-clockwise 90
-                       user_angle = 270;
-                       break;
-               case MM_DISPLAY_ROTATION_180:
-                       user_angle = 180;
-                       break;
-               case MM_DISPLAY_ROTATION_270: // clockwise 90
-                       user_angle = 90;
-                       break;
-       }
-
-       /* get original orientation */
-       if (player->v_stream_caps)
-       {
-               GstStructure *str = NULL;
-
-               str = gst_caps_get_structure (player->v_stream_caps, 0);
-               if ( !gst_structure_get_int (str, "orientation", &org_angle))
-               {
-                       debug_log ("missing 'orientation' field in video caps");
-               }
-               else
-               {
-                       debug_log("origianl video orientation = %d", org_angle);
-               }
-       }
-
-       debug_log("check user angle: %d, org angle: %d", user_angle, org_angle);
-
-       /* get rotation value to set */
-       __mmplayer_get_property_value_for_rotation(player, org_angle+user_angle, &rotation_value);
-
-       /* check video stream callback is used */
-       if( player->use_video_stream )
-       {
-               if (player->is_nv12_tiled)
-               {
-                       gchar *ename = NULL;
-                       int width = 0;
-                       int height = 0;
-
-                       mm_attrs_get_int_by_name(attrs, "display_width", &width);
-                       mm_attrs_get_int_by_name(attrs, "display_height", &height);
-
-                       /* resize video frame with requested values for fimcconvert */
-#ifdef GST_API_VERSION_1
-                       ename = GST_OBJECT (gst_element_get_factory(player->pipeline->videobin[MMPLAYER_V_CONV].gst));
-#else
-                       ename = GST_PLUGIN_FEATURE_NAME(gst_element_get_factory(player->pipeline->videobin[MMPLAYER_V_CONV].gst));
-#endif
-
-                       if (g_strrstr(ename, "fimcconvert"))
-                       {
-                               if (width)
-                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-width", width, NULL);
-
-                               if (height)
-                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-height", height, NULL);
-
-                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "rotate", rotation_value, NULL);
-                               debug_log("updating fimcconvert - r[%d], w[%d], h[%d]", rotation_value, width, height);
-                       }
-                       else
-                       {
-                               debug_error("no available video converter");
-                               return MM_ERROR_PLAYER_INTERNAL;
-                       }
-               }
-               else
-               {
-                       debug_log("using video stream callback with memsink. player handle : [%p]", player);
-
-                       g_object_set(player->pipeline->videobin[MMPLAYER_V_FLIP].gst, "method", rotation_value, NULL);
-               }
-
-               return MM_ERROR_NONE;
-       }
-
-       /* update display surface */
-       mm_attrs_get_int_by_name(attrs, "display_surface_type", &surface_type);
-       debug_log("check display surface type attribute: %d", surface_type);
-
-       /* configuring display */
-       switch ( surface_type )
-       {
-               case MM_DISPLAY_SURFACE_X:
-               {
-                       /* ximagesink or xvimagesink */
-                       void *xid = NULL;
-                       int zoom = 0;
-                       int display_method = 0;
-                       int roi_x = 0;
-                       int roi_y = 0;
-                       int roi_w = 0;
-                       int roi_h = 0;
-                       int force_aspect_ratio = 0;
-                       gboolean visible = TRUE;
-
-                       /* common case if using x surface */
-                       mm_attrs_get_data_by_name(attrs, "display_overlay", &xid);
-                       if ( xid )
-                       {
-#define GST_VAAPI_DISPLAY_TYPE_X11 1
-                if (!strncmp(PLAYER_INI()->videosink_element_x,"vaapisink", strlen("vaapisink"))){
-                    debug_log("set video param: vaapisink display %d", GST_VAAPI_DISPLAY_TYPE_X11);
-                    g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-                            "display", GST_VAAPI_DISPLAY_TYPE_X11,
-                            NULL);
-                }
-
-                               debug_log("set video param : xid %d", *(int*)xid);
-#ifdef GST_API_VERSION_1
-                               gst_video_overlay_set_window_handle( GST_VIDEO_OVERLAY( player->pipeline->videobin[MMPLAYER_V_SINK].gst ), *(int*)xid );
-#else
-                               gst_x_overlay_set_xwindow_id( GST_X_OVERLAY( player->pipeline->videobin[MMPLAYER_V_SINK].gst ), *(int*)xid );
-#endif
-                       }
-                       else
-                       {
-                               /* FIXIT : is it error case? */
-                               debug_warning("still we don't have xid on player attribute. create it's own surface.");
-                       }
-
-                       /* if xvimagesink */
-                       if (!strcmp(PLAYER_INI()->videosink_element_x,"xvimagesink"))
-                       {
-                               mm_attrs_get_int_by_name(attrs, "display_force_aspect_ration", &force_aspect_ratio);
-                               mm_attrs_get_int_by_name(attrs, "display_zoom", &zoom);
-                               mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
-                               mm_attrs_get_int_by_name(attrs, "display_roi_x", &roi_x);
-                               mm_attrs_get_int_by_name(attrs, "display_roi_y", &roi_y);
-                               mm_attrs_get_int_by_name(attrs, "display_roi_width", &roi_w);
-                               mm_attrs_get_int_by_name(attrs, "display_roi_height", &roi_h);
-                               mm_attrs_get_int_by_name(attrs, "display_visible", &visible);
-
-                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-                                       "force-aspect-ratio", force_aspect_ratio,
-                                       "zoom", zoom,
-                                       "rotate", rotation_value,
-                                       "handle-events", TRUE,
-                                       "display-geometry-method", display_method,
-                                       "draw-borders", FALSE,
-                                       "dst-roi-x", roi_x,
-                                       "dst-roi-y", roi_y,
-                                       "dst-roi-w", roi_w,
-                                       "dst-roi-h", roi_h,
-                                       "visible", visible,
-                                       NULL );
-
-                               debug_log("set video param : zoom %d", zoom);
-                               debug_log("set video param : rotate %d", rotation_value);
-                               debug_log("set video param : method %d", display_method);
-                               debug_log("set video param : dst-roi-x: %d, dst-roi-y: %d, dst-roi-w: %d, dst-roi-h: %d",
-                                                               roi_x, roi_y, roi_w, roi_h );
-                               debug_log("set video param : visible %d", visible);
-                               debug_log("set video param : force aspect ratio %d", force_aspect_ratio);
-                       }
-
-            /* if vaapisink */
-            if (!strncmp(PLAYER_INI()->videosink_element_x, "vaapisink", strlen("vaapisink")))
-            {
-                g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-                        "rotation", rotation_value,
-                        NULL);
-                debug_log("set video param: vaapisink rotation %d", rotation_value);
-            }
-               }
-               break;
-               case MM_DISPLAY_SURFACE_EVAS:
-               {
-                       void *object = NULL;
-                       int scaling = 0;
-                       gboolean visible = TRUE;
-
-                       /* common case if using evas surface */
-                       mm_attrs_get_data_by_name(attrs, "display_overlay", &object);
-                       mm_attrs_get_int_by_name(attrs, "display_visible", &visible);
-                       mm_attrs_get_int_by_name(attrs, "display_evas_do_scaling", &scaling);
-                       if (object)
-                       {
-                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-                                               "evas-object", object,
-                                               "visible", visible,
-                                               NULL);
-                               debug_log("set video param : evas-object %x", object);
-                               debug_log("set video param : visible %d", visible);
-                       }
-                       else
-                       {
-                               debug_error("no evas object");
-                               return MM_ERROR_PLAYER_INTERNAL;
-                       }
-
-                       /* if evasimagesink */
-                       if (!strcmp(PLAYER_INI()->videosink_element_evas,"evasimagesink") && player->is_nv12_tiled)
-                       {
-                               int width = 0;
-                               int height = 0;
-                               int no_scaling = !scaling;
-
-                               mm_attrs_get_int_by_name(attrs, "display_width", &width);
-                               mm_attrs_get_int_by_name(attrs, "display_height", &height);
-
-                               /* NOTE: fimcconvert does not manage index of src buffer from upstream src-plugin, decoder gives frame information in output buffer with no ordering */
-                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-buffer-num", 5, NULL);
-
-                               if (no_scaling)
-                               {
-                                       /* no-scaling order to fimcconvert, original width, height size of media src will be passed to sink plugin */
-                                       g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst,
-                                                       "dst-width", 0, /* setting 0, output video width will be media src's width */
-                                                       "dst-height", 0, /* setting 0, output video height will be media src's height */
-                                                       NULL);
-                               }
-                               else
-                               {
-                                       /* scaling order to fimcconvert */
-                                       if (width)
-                                       {
-                                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-width", width, NULL);
-                                       }
-                                       if (height)
-                                       {
-                                               g_object_set(player->pipeline->videobin[MMPLAYER_V_CONV].gst, "dst-height", height, NULL);
-                                       }
-                                       debug_log("set video param : video frame scaling down to width(%d) height(%d)", width, height);
-                               }
-                               debug_log("set video param : display_evas_do_scaling %d", scaling);
-                       }
-
-                       /* if evaspixmapsink */
-                       if (!strcmp(PLAYER_INI()->videosink_element_evas,"evaspixmapsink"))
-                       {
-                               int display_method = 0;
-                               int roi_x = 0;
-                               int roi_y = 0;
-                               int roi_w = 0;
-                               int roi_h = 0;
-                               int origin_size = !scaling;
-
-                               mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
-                               mm_attrs_get_int_by_name(attrs, "display_roi_x", &roi_x);
-                               mm_attrs_get_int_by_name(attrs, "display_roi_y", &roi_y);
-                               mm_attrs_get_int_by_name(attrs, "display_roi_width", &roi_w);
-                               mm_attrs_get_int_by_name(attrs, "display_roi_height", &roi_h);
-
-                               g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-                                       "origin-size", origin_size,
-                                       "dst-roi-x", roi_x,
-                                       "dst-roi-y", roi_y,
-                                       "dst-roi-w", roi_w,
-                                       "dst-roi-h", roi_h,
-                                       "display-geometry-method", display_method,
-                                       NULL );
-
-                               debug_log("set video param : method %d", display_method);
-                               debug_log("set video param : dst-roi-x: %d, dst-roi-y: %d, dst-roi-w: %d, dst-roi-h: %d",
-                                                               roi_x, roi_y, roi_w, roi_h );
-                               debug_log("set video param : display_evas_do_scaling %d (origin-size %d)", scaling, origin_size);
-                       }
-                       g_object_set(player->pipeline->videobin[MMPLAYER_V_FLIP].gst, "method", rotation_value, NULL);
-               }
-               break;
-               case MM_DISPLAY_SURFACE_X_EXT:  /* NOTE : this surface type is used for the videoTexture(canvasTexture) overlay */
-               {
-                       void *pixmap_id_cb = NULL;
-                       void *pixmap_id_cb_user_data = NULL;
-                       int display_method = 0;
-                       gboolean visible = TRUE;
-
-                       /* if xvimagesink */
-                       if (strcmp(PLAYER_INI()->videosink_element_x,"xvimagesink"))
-                       {
-                               debug_error("videosink is not xvimagesink");
-                               return MM_ERROR_PLAYER_INTERNAL;
-                       }
-
-                       /* get information from attributes */
-                       mm_attrs_get_data_by_name(attrs, "display_overlay", &pixmap_id_cb);
-                       mm_attrs_get_data_by_name(attrs, "display_overlay_user_data", &pixmap_id_cb_user_data);
-                       mm_attrs_get_int_by_name(attrs, "display_method", &display_method);
-
-                       if ( pixmap_id_cb )
-                       {
-                               debug_log("set video param : display_overlay(0x%x)", pixmap_id_cb);
-                               if (pixmap_id_cb_user_data)
-                               {
-                                       debug_log("set video param : display_overlay_user_data(0x%x)", pixmap_id_cb_user_data);
-                               }
-                       }
-                       else
-                       {
-                               debug_error("failed to set pixmap-id-callback");
-                               return MM_ERROR_PLAYER_INTERNAL;
-                       }
-                       debug_log("set video param : method %d", display_method);
-                       debug_log("set video param : visible %d", visible);
-
-                       /* set properties of videosink plugin */
-                       g_object_set(player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-                               "display-geometry-method", display_method,
-                               "draw-borders", FALSE,
-                               "visible", visible,
-                               "rotate", rotation_value,
-                               "pixmap-id-callback", pixmap_id_cb,
-                               "pixmap-id-callback-userdata", pixmap_id_cb_user_data,
-                               NULL );
-               }
-               break;
-               case MM_DISPLAY_SURFACE_NULL:
-               {
-                       /* do nothing */
-               }
-               break;
-       }
-
-       debug_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;
-
-       debug_fenter();
-
-       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 ( GST_ELEMENT_LINK(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst)) )
-                       {
-                               debug_log("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
-                       {
-                               debug_log("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;
-       }
-
-       debug_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;
-
-       debug_fenter();
-
-       return_val_if_fail(element_bucket, 0);
-       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)) )
-                       {
-                               debug_log("__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 ++;
-               }
-       }
-
-       debug_fleave();
-
-       return successful_add_count;
-}
-
-
-
-/**
- * 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
- */
-#define MMPLAYER_CREATEONLY_ELEMENT(x_bin, x_id, x_factory, x_name) \
-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 )\
-{\
-       debug_critical("failed to create %s \n", x_factory);\
-       goto ERROR;\
-}\
-
-#define MMPLAYER_CREATE_ELEMENT_ADD_BIN(x_bin, x_id, x_factory, x_name, y_bin) \
-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 )\
-{\
-       debug_critical("failed to create %s \n", x_factory);\
-       goto ERROR;\
-}\
-if( !gst_bin_add(GST_BIN(y_bin), GST_ELEMENT(x_bin[x_id].gst)))\
-{\
-       debug_log("__mmplayer_gst_element_link_bucket : Adding element [%s]  to bin [%s] failed\n",\
-               GST_ELEMENT_NAME(GST_ELEMENT(x_bin[x_id].gst)),\
-               GST_ELEMENT_NAME(GST_ELEMENT(y_bin) ) );\
-       goto ERROR;\
-}\
-
-/* macro for code readability. just for sinkbin-creation functions */
-#define MMPLAYER_CREATE_ELEMENT(x_bin, x_id, x_factory, x_name, x_add_bucket) \
-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 )\
-       {\
-               debug_critical("failed to create %s \n", x_factory);\
-               goto ERROR;\
-       }\
-       if ( x_add_bucket )\
-               element_bucket = g_list_append(element_bucket, &x_bin[x_id]);\
-} while(0);
-
-
-/**
-  * AUDIO PIPELINE
-  * - Local playback   : audioconvert !volume ! capsfilter ! audioeq ! audiosink
-  * - Streaming                : audioconvert !volume ! audiosink
-  * - PCM extraction   : audioconvert ! audioresample ! capsfilter ! fakesink
-  */
-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;
-       char *device_name = NULL;
-       gboolean link_audio_sink_now = TRUE;
-       int i =0;
-
-       debug_fenter();
-
-       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 )
-       {
-               debug_error("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 )
-       {
-               debug_critical("failed to create audiobin\n");
-               goto ERROR;
-       }
-
-       /* take it */
-       player->pipeline->audiobin = audiobin;
-
-       player->is_sound_extraction = __mmplayer_can_extract_pcm(player);
-
-       /* Adding audiotp plugin for reverse trickplay feature */
-       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TP, "audiotp", "audiotrickplay", TRUE);
-
-       /* converter */
-       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audioconverter", TRUE);
-
-       if ( ! player->is_sound_extraction )
-       {
-               GstCaps* caps = NULL;
-               gint channels = 0;
-
-               /* for logical volume control */
-               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_VOL, "volume", "volume", TRUE);
-               g_object_set(G_OBJECT (audiobin[MMPLAYER_A_VOL].gst), "volume", player->sound.volume, NULL);
-
-               if (player->sound.mute)
-               {
-                       debug_log("mute enabled\n");
-                       g_object_set(G_OBJECT (audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
-               }
-
-               /*capsfilter */
-               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audiocapsfilter", TRUE);
-
-               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 );
-
-               /* chech if multi-chennels */
-               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")))
-                       {
-#ifdef GST_API_VERSION_1
-                               if ((caps = gst_pad_get_current_caps(srcpad)))
-                               {
-                                       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);
-                               }
-#else
-                               if ((caps = gst_pad_get_caps(srcpad)))
-                               {
-                                       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);
-                               }
-#endif
-                               gst_object_unref(srcpad);
-                       }
-               }
-
-               /* audio effect element. if audio effect is enabled */
-               if ( channels <= 2 && (PLAYER_INI()->use_audio_effect_preset || PLAYER_INI()->use_audio_effect_custom) )
-               {
-                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER, PLAYER_INI()->name_of_audio_effect, "audiofilter", TRUE);
-               }
-
-               /* create audio sink */
-               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, PLAYER_INI()->name_of_audiosink,
-                       "audiosink", link_audio_sink_now);
-
-               /* sync on */
-               if (MMPLAYER_IS_RTSP_STREAMING(player))
-                       g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", FALSE, NULL);   /* sync off */
-               else
-                       g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", TRUE, NULL);    /* sync on */
-
-               /* qos on */
-               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL);     /* qos on */
-
-               /* FIXIT : using system clock. isn't there another way? */
-               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "provide-clock", PLAYER_INI()->provide_clock,  NULL);
-
-               __mmplayer_add_sink( player, audiobin[MMPLAYER_A_SINK].gst );
-
-               if(player->audio_buffer_cb)
-               {
-                   g_object_set(audiobin[MMPLAYER_A_SINK].gst, "audio-handle", player->audio_buffer_cb_user_param, NULL);
-                   g_object_set(audiobin[MMPLAYER_A_SINK].gst, "audio-callback", player->audio_buffer_cb, NULL);
-               }
-
-               if ( g_strrstr(PLAYER_INI()->name_of_audiosink, "avsysaudiosink") )
-               {
-                       gint volume_type = 0;
-                       gint audio_route = 0;
-                       gint sound_priority = FALSE;
-                       gint is_spk_out_only = 0;
-                       gint latency_mode = 0;
-
-                       /* set volume table
-                        * It should be set after player creation through attribute.
-                        * But, it can not be changed during playing.
-                        */
-                       mm_attrs_get_int_by_name(attrs, "sound_volume_type", &volume_type);
-                       mm_attrs_get_int_by_name(attrs, "sound_route", &audio_route);
-                       mm_attrs_get_int_by_name(attrs, "sound_priority", &sound_priority);
-                       mm_attrs_get_int_by_name(attrs, "sound_spk_out_only", &is_spk_out_only);
-                       mm_attrs_get_int_by_name(attrs, "audio_latency_mode", &latency_mode);
-
-                       /* hook sound_type if emergency case */
-                       if ( player->sm.event == ASM_EVENT_EMERGENCY)
-                       {
-                               debug_log ("This is emergency session, hook sound_type from [%d] to [%d]\n", volume_type, MM_SOUND_VOLUME_TYPE_EMERGENCY);
-                               volume_type = MM_SOUND_VOLUME_TYPE_EMERGENCY;
-                       }
-
-                       g_object_set(audiobin[MMPLAYER_A_SINK].gst,
-                                       "volumetype", volume_type,
-                                       "audio-route", audio_route,
-                                       "priority", sound_priority,
-                                       "user-route", is_spk_out_only,
-                                       "latency", latency_mode,
-                                       NULL);
-
-                       debug_log("audiosink property status...volume type:%d, route:%d, priority=%d, user-route=%d, latency=%d\n",
-                               volume_type, audio_route, sound_priority, is_spk_out_only, latency_mode);
-               }
-
-               /* Antishock can be enabled when player is resumed by soundCM.
-                * But, it's not used in MMS, setting and etc.
-                * Because, player start seems like late.
-                */
-               __mmplayer_set_antishock( player , FALSE );
-       }
-       else // pcm extraction only and no sound output
-       {
-               int dst_samplerate = 0;
-               int dst_channels = 0;
-               int dst_depth = 0;
-               char *caps_type = NULL;
-               GstCaps* caps = NULL;
-
-               /* resampler */
-               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RESAMPLER, "audioresample", "resampler", TRUE);
-
-               /* 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", "audiocapsfilter", TRUE);
-
-               caps = gst_caps_new_simple ("audio/x-raw-int",
-                                               "rate", G_TYPE_INT, dst_samplerate,
-                                               "channels", G_TYPE_INT, dst_channels,
-                                               "depth", G_TYPE_INT, dst_depth,
-                                               NULL);
-
-               caps_type = gst_caps_to_string(caps);
-               debug_log("resampler new caps : %s\n", caps_type);
-
-               g_object_set (GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL );
-
-               /* clean */
-               gst_caps_unref( caps );
-               MMPLAYER_FREEIF( caps_type );
-
-               /* fake sink */
-               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "fakesink", "fakesink", TRUE);
-
-               /* set sync */
-               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", FALSE, NULL);
-
-               __mmplayer_add_sink( player, audiobin[MMPLAYER_A_SINK].gst );
-       }
-
-       /* adding created elements to bin */
-       debug_log("adding created elements to bin\n");
-       if( !__mmplayer_gst_element_add_bucket_to_bin( GST_BIN(audiobin[MMPLAYER_A_BIN].gst), element_bucket ))
-       {
-               debug_error("failed to add elements\n");
-               goto ERROR;
-       }
-
-       /* linking elements in the bucket by added order. */
-       debug_log("Linking elements in the bucket by added order.\n");
-       if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
-       {
-               debug_error("failed to link elements\n");
-               goto ERROR;
-       }
-
-       /* get first element's sinkpad for creating ghostpad */
-       first_element = (MMPlayerGstElement *)element_bucket->data;
-
-       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
-       if ( ! pad )
-       {
-               debug_error("failed to get pad from first element of audiobin\n");
-               goto ERROR;
-       }
-
-       ghostpad = gst_ghost_pad_new("sink", pad);
-       if ( ! ghostpad )
-       {
-               debug_error("failed to create ghostpad\n");
-               goto ERROR;
-       }
-
-       if ( FALSE == gst_element_add_pad(audiobin[MMPLAYER_A_BIN].gst, ghostpad) )
-       {
-               debug_error("failed to add ghostpad to audiobin\n");
-               goto ERROR;
-       }
-
-       gst_object_unref(pad);
-
-       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_PRESET )
-               {
-                       if (!_mmplayer_audio_effect_preset_apply(player, player->audio_effect_info.preset))
-                       {
-                               debug_msg("apply audio effect(preset:%d) setting success\n",player->audio_effect_info.preset);
-                       }
-               }
-               else if ( player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM )
-               {
-                       if (!_mmplayer_audio_effect_custom_apply(player))
-                       {
-                               debug_msg("apply audio effect(custom) setting success\n");
-                       }
-               }
-       }
-
-       /* done. free allocated variables */
-       MMPLAYER_FREEIF( device_name );
-       g_list_free(element_bucket);
-
-       mm_attrs_set_int_by_name(attrs, "content_audio_found", TRUE);
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-
-ERROR:
-
-       debug_log("ERROR : releasing audiobin\n");
-
-       MMPLAYER_FREEIF( device_name );
-
-       if ( pad )
-               gst_object_unref(GST_OBJECT(pad));
-
-       if ( ghostpad )
-               gst_object_unref(GST_OBJECT(ghostpad));
-
-       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 gboolean
-__mmplayer_audio_stream_probe (GstPad *pad, GstBuffer *buffer, gpointer u_data)
-{
-       mm_player_t* player = (mm_player_t*) u_data;
-       gint size;
-       guint8 *data;
-
-#ifdef GST_API_VERSION_1
-       GstMapInfo info;
-       gst_buffer_map (buffer, &info, GST_MAP_WRITE);
-       data = info.data;
-       size = gst_buffer_get_size(buffer);
-
-       if (player->audio_stream_cb && size && data)
-               player->audio_stream_cb((void *)data, size, player->audio_stream_cb_user_param);
-       
-       gst_buffer_unmap (buffer, &info);
-#else
-       data = GST_BUFFER_DATA(buffer);
-       size = GST_BUFFER_SIZE(buffer);
-
-       if (player->audio_stream_cb && size && data)
-               player->audio_stream_cb((void *)data, size, player->audio_stream_cb_user_param);
-#endif
-
-       return TRUE;
-}
-
-/**
- * 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
-  * - x surface (arm/x86) : videoflip ! xvimagesink
-  * - evas surface  (arm) : fimcconvert ! evasimagesink
-  * - evas surface  (x86) : videoconvertor ! videoflip ! evasimagesink
-  */
-static int
-__mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDisplaySurfaceType surface_type)
-{
-       GstPad *pad = NULL;
-       MMHandleType attrs;
-       GList*element_bucket = NULL;
-       MMPlayerGstElement* first_element = NULL;
-       MMPlayerGstElement* videobin = NULL;
-       gchar* vconv_factory = NULL;
-       gchar *videosink_element = NULL;
-
-       debug_fenter();
-
-       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       /* alloc handles */
-       videobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_V_NUM);
-       if ( !videobin )
-       {
-               return MM_ERROR_PLAYER_NO_FREE_SPACE;
-       }
-
-       player->pipeline->videobin = videobin;
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
-       {
-               debug_error("cannot get content attribute");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       /* 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 )
-       {
-               debug_critical("failed to create videobin");
-               goto ERROR;
-       }
-
-       if( player->use_video_stream ) // video stream callback, so send raw video data to application
-       {
-               GstStructure *str = NULL;
-               gint ret = 0;
-
-               debug_log("using memsink\n");
-
-               /* first, create colorspace convert */
-               if (player->is_nv12_tiled)
-               {
-                       vconv_factory = "fimcconvert";
-               }
-               else // get video converter from player ini file
-               {
-                       if (strlen(PLAYER_INI()->name_of_video_converter) > 0)
-                       {
-                               vconv_factory = PLAYER_INI()->name_of_video_converter;
-                       }
-               }
-
-               if (vconv_factory)
-               {
-                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CONV, vconv_factory, "video converter", TRUE);
-               }
-
-               if ( !player->is_nv12_tiled)
-               {
-                       gint width = 0;         //width of video
-                       gint height = 0;                //height of video
-                       GstCaps* video_caps = NULL;
-
-                       /* rotator, scaler and capsfilter */
-            if (strncmp(PLAYER_INI()->videosink_element_x, "vaapisink", strlen("vaapisink"))){
-                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_FLIP, "videoflip", "video rotator", TRUE);
-                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SCALE, "videoscale", "video scaler", TRUE);
-                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CAPS, "capsfilter", "videocapsfilter", TRUE);
-            }
-
-                       /* get video stream caps parsed by demuxer */
-                       str = gst_caps_get_structure (player->v_stream_caps, 0);
-                       if ( !str )
-                       {
-                               debug_error("cannot get structure");
-                               goto ERROR;
-                       }
-
-                       mm_attrs_get_int_by_name(attrs, "display_width", &width);
-                       mm_attrs_get_int_by_name(attrs, "display_height", &height);
-                       if (!width || !height) {
-                               /* we set width/height of original media's size  to capsfilter for scaling video */
-                               ret = gst_structure_get_int (str, "width", &width);
-                               if ( !ret )
-                               {
-                                       debug_error("cannot get width");
-                                       goto ERROR;
-                               }
-
-                               ret = gst_structure_get_int(str, "height", &height);
-                               if ( !ret )
-                               {
-                                       debug_error("cannot get height");
-                                       goto ERROR;
-                               }
-                       }
-
-                       video_caps = gst_caps_new_simple( "video/x-raw-rgb",
-                                                                                       "width", G_TYPE_INT, width,
-                                                                                       "height", G_TYPE_INT, height,
-                                                                                       NULL);
-
-                       g_object_set (GST_ELEMENT(videobin[MMPLAYER_V_CAPS].gst), "caps", video_caps, NULL );
-
-                       gst_caps_unref( video_caps );
-               }
-
-               /* finally, create video sink. output will be BGRA8888. */
-               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, "avsysmemsink", "videosink", TRUE);
-
-               MMPLAYER_SIGNAL_CONNECT( player,
-                                                                        videobin[MMPLAYER_V_SINK].gst,
-                                                                        "video-stream",
-                                                                        G_CALLBACK(__mmplayer_videostream_cb),
-                                                                        player );
-       }
-       else // render video data using sink plugin like xvimagesink
-       {
-               debug_log("using videosink");
-
-               /* set video converter */
-               if (strlen(PLAYER_INI()->name_of_video_converter) > 0)
-               {
-                       vconv_factory = PLAYER_INI()->name_of_video_converter;
-
-                       if ( (player->is_nv12_tiled && (surface_type == MM_DISPLAY_SURFACE_EVAS) &&
-                               !strcmp(PLAYER_INI()->videosink_element_evas, "evasimagesink") ) )
-                       {
-                               vconv_factory = "fimcconvert";
-                       }
-                       else if (player->is_nv12_tiled)
-                       {
-                               vconv_factory = NULL;
-                       }
-
-                       if (vconv_factory)
-                       {
-                               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CONV, vconv_factory, "video converter", TRUE);
-                               debug_log("using video converter: %s", vconv_factory);
-                       }
-               }
-
-        if (strncmp(PLAYER_INI()->videosink_element_x,"vaapisink", strlen("vaapisink"))){
-               /* set video rotator */
-               if ( !player->is_nv12_tiled )
-                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_FLIP, "videoflip", "video rotator", TRUE);
-
-               /* videoscaler */
-               #if !defined(__arm__)
-               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SCALE, "videoscale", "videoscaler", TRUE);
-               #endif
-        }
-
-               /* set video sink */
-               switch (surface_type)
-               {
-               case MM_DISPLAY_SURFACE_X:
-                       if (strlen(PLAYER_INI()->videosink_element_x) > 0)
-                               videosink_element = PLAYER_INI()->videosink_element_x;
-                       else
-                               goto ERROR;
-                       break;
-               case MM_DISPLAY_SURFACE_EVAS:
-                       if (strlen(PLAYER_INI()->videosink_element_evas) > 0)
-                               videosink_element = PLAYER_INI()->videosink_element_evas;
-                       else
-                               goto ERROR;
-                       break;
-               case MM_DISPLAY_SURFACE_X_EXT:
-               {
-                       void *pixmap_id_cb = NULL;
-                       mm_attrs_get_data_by_name(attrs, "display_overlay", &pixmap_id_cb);
-                       if (pixmap_id_cb) /* this is used for the videoTextue(canvasTexture) overlay */
-                       {
-                               videosink_element = PLAYER_INI()->videosink_element_x;
-                       }
-                       else
-                       {
-                               debug_error("something wrong.. callback function for getting pixmap id is null");
-                               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;
-               default:
-                       debug_error("unidentified surface type");
-                       goto ERROR;
-               }
-
-               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_element, videosink_element, TRUE);
-               debug_log("selected videosink name: %s", videosink_element);
-
-               /* connect signal handlers for sink plug-in */
-               switch (surface_type) {
-               case MM_DISPLAY_SURFACE_X_EXT:
-                       MMPLAYER_SIGNAL_CONNECT( player,
-                                                                       player->pipeline->videobin[MMPLAYER_V_SINK].gst,
-                                                                       "frame-render-error",
-                                                                       G_CALLBACK(__mmplayer_videoframe_render_error_cb),
-                                                                       player );
-                       debug_log("videoTexture usage, connect a signal handler for pixmap rendering error");
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       if ( _mmplayer_update_video_param(player) != MM_ERROR_NONE)
-               goto ERROR;
-
-       /* qos on */
-       g_object_set (G_OBJECT (videobin[MMPLAYER_V_SINK].gst), "qos", TRUE, NULL);
-
-       /* store it as it's sink element */
-       __mmplayer_add_sink( player, videobin[MMPLAYER_V_SINK].gst );
-
-       /* adding created elements to bin */
-       if( ! __mmplayer_gst_element_add_bucket_to_bin(GST_BIN(videobin[MMPLAYER_V_BIN].gst), element_bucket) )
-       {
-               debug_error("failed to add elements\n");
-               goto ERROR;
-       }
-
-       /* Linking elements in the bucket by added order */
-       if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
-       {
-               debug_error("failed to link elements\n");
-               goto ERROR;
-       }
-
-       /* get first element's sinkpad for creating ghostpad */
-       first_element = (MMPlayerGstElement *)element_bucket->data;
-       if ( !first_element )
-       {
-               debug_error("failed to get first element from bucket\n");
-               goto ERROR;
-       }
-
-       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
-       if ( !pad )
-       {
-               debug_error("failed to get pad from first element\n");
-               goto ERROR;
-       }
-
-       /* create ghostpad */
-       if (FALSE == gst_element_add_pad(videobin[MMPLAYER_V_BIN].gst, gst_ghost_pad_new("sink", pad)))
-       {
-               debug_error("failed to add ghostpad to videobin\n");
-               goto ERROR;
-       }
-       gst_object_unref(pad);
-
-       /* done. free allocated variables */
-       g_list_free(element_bucket);
-
-       mm_attrs_set_int_by_name(attrs, "content_video_found", TRUE);
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-
-ERROR:
-       debug_error("ERROR : releasing videobin\n");
-
-       g_list_free( element_bucket );
-
-       if (pad)
-               gst_object_unref(GST_OBJECT(pad));
-
-       /* release videobin with it's childs */
-       if ( videobin[MMPLAYER_V_BIN].gst )
-       {
-               gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst));
-       }
-
-
-       MMPLAYER_FREEIF( videobin );
-
-       player->pipeline->videobin = NULL;
-
-       return MM_ERROR_PLAYER_INTERNAL;
-}
-
-static int __mmplayer_gst_create_text_pipeline(mm_player_t* player)
-{
-       MMPlayerGstElement* first_element = NULL;
-       MMPlayerGstElement* textbin = NULL;
-       GList* element_bucket = NULL;
-       GstPad *pad = NULL;
-       GstPad *ghostpad = NULL;
-       gint i = 0;
-
-       debug_fenter();
-
-       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 )
-       {
-               debug_error("failed to allocate memory for textbin\n");
-               return MM_ERROR_PLAYER_NO_FREE_SPACE;
-       }
-
-       /* 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 )
-       {
-               debug_critical("failed to create textbin\n");
-               goto ERROR;
-       }
-
-       /* take it */
-       player->pipeline->textbin = textbin;
-
-       /* fakesink */
-       if (player->use_textoverlay)
-       {
-               debug_log ("use textoverlay for displaying \n");
-
-               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_TEXT_QUEUE, "queue", "text_t_queue", textbin[MMPLAYER_T_BIN].gst);
-
-               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_VIDEO_QUEUE, "queue", "text_v_queue", textbin[MMPLAYER_T_BIN].gst);
-
-               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_VIDEO_CONVERTER, "fimcconvert", "text_v_converter", textbin[MMPLAYER_T_BIN].gst);
-
-               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_OVERLAY, "textoverlay", "text_overlay", textbin[MMPLAYER_T_BIN].gst);
-
-               if (!gst_element_link_pads (textbin[MMPLAYER_T_VIDEO_QUEUE].gst, "src", textbin[MMPLAYER_T_VIDEO_CONVERTER].gst, "sink"))
-               {
-                       debug_error("failed to link queue and converter\n");
-                       goto ERROR;
-               }
-
-               if (!gst_element_link_pads (textbin[MMPLAYER_T_VIDEO_CONVERTER].gst, "src", textbin[MMPLAYER_T_OVERLAY].gst, "video_sink"))
-               {
-                       debug_error("failed to link queue and textoverlay\n");
-                       goto ERROR;
-               }
-
-               if (!gst_element_link_pads (textbin[MMPLAYER_T_TEXT_QUEUE].gst, "src", textbin[MMPLAYER_T_OVERLAY].gst, "text_sink"))
-               {
-                       debug_error("failed to link queue and textoverlay\n");
-                       goto ERROR;
-               }
-
-       }
-       else
-       {
-               debug_log ("use subtitle message for displaying \n");
-
-               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_TEXT_QUEUE, "queue", "text_queue", TRUE);
-
-               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_SINK, "fakesink", "text_sink", TRUE);
-
-               g_object_set (G_OBJECT (textbin[MMPLAYER_T_SINK].gst), "sync", TRUE, NULL);
-               g_object_set (G_OBJECT (textbin[MMPLAYER_T_SINK].gst), "async", FALSE, NULL);
-               g_object_set (G_OBJECT (textbin[MMPLAYER_T_SINK].gst), "signal-handoffs", TRUE, NULL);
-
-               MMPLAYER_SIGNAL_CONNECT( player,
-                                                               G_OBJECT(textbin[MMPLAYER_T_SINK].gst),
-                                                               "handoff",
-                                                               G_CALLBACK(__mmplayer_update_subtitle),
-                                                               (gpointer)player );
-
-               if (!player->play_subtitle)
-               {
-                       debug_log ("add textbin sink as sink element of whole pipeline.\n");
-                       __mmplayer_add_sink (player, GST_ELEMENT(textbin[MMPLAYER_T_SINK].gst));
-               }
-
-               /* adding created elements to bin */
-               debug_log("adding created elements to bin\n");
-               if( !__mmplayer_gst_element_add_bucket_to_bin( GST_BIN(textbin[MMPLAYER_T_BIN].gst), element_bucket ))
-               {
-                       debug_error("failed to add elements\n");
-                       goto ERROR;
-               }
-
-               /* linking elements in the bucket by added order. */
-               debug_log("Linking elements in the bucket by added order.\n");
-               if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
-               {
-                       debug_error("failed to link elements\n");
-                       goto ERROR;
-               }
-
-               /* done. free allocated variables */
-               g_list_free(element_bucket);
-       }
-
-       if (textbin[MMPLAYER_T_TEXT_QUEUE].gst)
-       {
-               pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_TEXT_QUEUE].gst), "sink");
-               if (!pad)
-               {
-                       debug_error("failed to get text pad of textbin\n");
-                       goto ERROR;
-               }
-
-               ghostpad = gst_ghost_pad_new("text_sink", pad);
-               if (!ghostpad)
-               {
-                       debug_error("failed to create ghostpad of textbin\n");
-                       goto ERROR;
-               }
-
-               if ( FALSE == gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad) )
-               {
-                       debug_error("failed to add ghostpad to textbin\n");
-                       goto ERROR;
-               }
-       }
-
-       if (textbin[MMPLAYER_T_VIDEO_QUEUE].gst)
-       {
-               pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_VIDEO_QUEUE].gst), "sink");
-               if (!pad)
-               {
-                       debug_error("failed to get video pad of textbin\n");
-                       goto ERROR;
-               }
-
-               ghostpad = gst_ghost_pad_new("video_sink", pad);
-               if (!ghostpad)
-               {
-                       debug_error("failed to create ghostpad of textbin\n");
-                       goto ERROR;
-               }
-
-               if (!gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad))
-               {
-                       debug_error("failed to add ghostpad to textbin\n");
-                       goto ERROR;
-               }
-       }
-
-       if (textbin[MMPLAYER_T_OVERLAY].gst)
-       {
-               pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_OVERLAY].gst), "src");
-               if (!pad)
-               {
-                       debug_error("failed to get src pad of textbin\n");
-                       goto ERROR;
-               }
-
-               ghostpad = gst_ghost_pad_new("src", pad);
-               if (!ghostpad)
-               {
-                       debug_error("failed to create ghostpad of textbin\n");
-                       goto ERROR;
-               }
-
-               if (!gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad))
-               {
-                       debug_error("failed to add ghostpad to textbin\n");
-                       goto ERROR;
-               }
-       }
-
-       gst_object_unref(pad);
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-
-ERROR:
-
-       debug_log("ERROR : releasing textbin\n");
-
-       if ( pad )
-               gst_object_unref(GST_OBJECT(pad));
-
-       if ( ghostpad )
-               gst_object_unref(GST_OBJECT(ghostpad));
-
-       g_list_free( element_bucket );
-
-
-       /* 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 ( !parent )
-                       {
-                               gst_object_unref(GST_OBJECT(textbin[i].gst));
-                               textbin[i].gst = NULL;
-                       }
-                       else
-                       {
-                               gst_object_unref(GST_OBJECT(parent));
-                       }
-               }
-       }
-
-       /* release textbin with it's childs */
-       if ( textbin[MMPLAYER_T_BIN].gst )
-       {
-               gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
-       }
-
-       MMPLAYER_FREEIF( textbin );
-
-       player->pipeline->textbin = NULL;
-
-       return MM_ERROR_PLAYER_INTERNAL;
-}
-
-
-static int
-__mmplayer_gst_create_subtitle_src(mm_player_t* player)
-{
-       MMPlayerGstElement* mainbin = NULL;
-       MMHandleType attrs = 0;
-       GstElement * pipeline = NULL;
-       GstElement *subsrc = NULL;
-       GstElement *subparse = NULL;
-       GstPad *sinkpad = NULL;
-       gchar *subtitle_uri =NULL;
-       gchar *charset = NULL;
-
-       debug_fenter();
-
-       /* get mainbin */
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
-       mainbin = player->pipeline->mainbin;
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
-       {
-               debug_error("cannot get content attribute\n");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       mm_attrs_get_string_by_name ( attrs, "subtitle_uri", &subtitle_uri );
-       if ( !subtitle_uri || strlen(subtitle_uri) < 1)
-       {
-               debug_error("subtitle uri is not proper filepath.\n");
-               return MM_ERROR_PLAYER_INVALID_URI;
-       }
-       debug_log("subtitle file path is [%s].\n", subtitle_uri);
-
-
-       /* create the subtitle source */
-       subsrc = gst_element_factory_make("filesrc", "subtitle_source");
-       if ( !subsrc )
-       {
-               debug_error ( "failed to create filesrc element\n" );
-               goto ERROR;
-       }
-       g_object_set(G_OBJECT (subsrc), "location", subtitle_uri, NULL);
-
-       mainbin[MMPLAYER_M_SUBSRC].id = MMPLAYER_M_SUBSRC;
-       mainbin[MMPLAYER_M_SUBSRC].gst = subsrc;
-
-       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subsrc))
-       {
-               debug_warning("failed to add queue\n");
-               goto ERROR;
-       }
-
-       /* subparse */
-       subparse = gst_element_factory_make("subparse", "subtitle_parser");
-       if ( !subparse )
-       {
-               debug_error ( "failed to create subparse element\n" );
-               goto ERROR;
-       }
-
-       charset = util_get_charset(subtitle_uri);
-       if (charset)
-       {
-               debug_log ("detected charset is %s\n", charset );
-               g_object_set (G_OBJECT (subparse), "subtitle-encoding", charset, NULL);
-       }
-
-       mainbin[MMPLAYER_M_SUBPARSE].id = MMPLAYER_M_SUBPARSE;
-       mainbin[MMPLAYER_M_SUBPARSE].gst = subparse;
-
-       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subparse))
-       {
-               debug_warning("failed to add subparse\n");
-               goto ERROR;
-       }
-
-       if (!gst_element_link_pads (subsrc, "src", subparse, "sink"))
-       {
-               debug_warning("failed to link subsrc and subparse\n");
-               goto ERROR;
-       }
-
-       player->play_subtitle = TRUE;
-       debug_log ("play subtitle using subtitle file\n");
-
-       if (MM_ERROR_NONE !=  __mmplayer_gst_create_text_pipeline(player))
-       {
-               debug_error("failed to create textbin. continuing without text\n");
-               goto ERROR;
-       }
-
-       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), GST_ELEMENT(player->pipeline->textbin[MMPLAYER_T_BIN].gst)))
-       {
-               debug_warning("failed to add textbin\n");
-               goto ERROR;
-       }
-
-       if (!gst_element_link_pads (subparse, "src", player->pipeline->textbin[MMPLAYER_T_BIN].gst, "text_sink"))
-       {
-               debug_warning("failed to link subparse and textbin\n");
-               goto ERROR;
-       }
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-
-
-ERROR:
-       return MM_ERROR_PLAYER_INTERNAL;
-}
-
-#ifdef GST_API_VERSION_1
-gboolean
-__mmplayer_update_subtitle( GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data)
-{
-       mm_player_t* player = (mm_player_t*) data;
-       MMMessageParamType msg = {0, };
-       GstClockTime duration = 0;
-       guint8 *text = NULL;
-       gboolean ret = TRUE;
-       GstMapInfo info;
-
-       debug_fenter();
-
-       return_val_if_fail ( player, FALSE );
-       return_val_if_fail ( buffer, FALSE );
-
-       gst_buffer_map (buffer, &info, GST_MAP_WRITE);
-       text = info.data;
-       gst_buffer_unmap (buffer, &info);
-
-       duration = GST_BUFFER_DURATION(buffer);
-
-       if ( player->is_subtitle_off )
-       {
-               debug_log("subtitle is OFF.\n" );
-               return TRUE;
-       }
-
-       if ( !text )
-       {
-               debug_log("There is no subtitle to be displayed.\n" );
-               return TRUE;
-       }
-
-       msg.data = (void *) text;
-       msg.subtitle.duration = GST_TIME_AS_MSECONDS(duration);
-
-       debug_warning("update subtitle : [%ld msec] %s\n'", msg.subtitle.duration, (char*)msg.data );
-
-       MMPLAYER_POST_MSG( player, MM_MESSAGE_UPDATE_SUBTITLE, &msg );
-
-       debug_fleave();
-
-       return ret;
-}
-#else
-gboolean
-__mmplayer_update_subtitle( GstElement* object, GstBuffer *buffer, GstPad *pad, gpointer data)
-{
-       mm_player_t* player = (mm_player_t*) data;
-       MMMessageParamType msg = {0, };
-       GstClockTime duration = 0;
-       guint8 *text = NULL;
-       gboolean ret = TRUE;
-
-       debug_fenter();
-
-       return_val_if_fail ( player, FALSE );
-       return_val_if_fail ( buffer, FALSE );
-
-       text = GST_BUFFER_DATA(buffer);
-       duration = GST_BUFFER_DURATION(buffer);
-
-       if ( player->is_subtitle_off )
-       {
-               debug_log("subtitle is OFF.\n" );
-               return TRUE;
-       }
-
-       if ( !text )
-       {
-               debug_log("There is no subtitle to be displayed.\n" );
-               return TRUE;
-       }
-
-       msg.data = (void *) text;
-       msg.subtitle.duration = GST_TIME_AS_MSECONDS(duration);
-
-       debug_warning("update subtitle : [%ld msec] %s\n'", msg.subtitle.duration, (char*)msg.data );
-
-       MMPLAYER_POST_MSG( player, MM_MESSAGE_UPDATE_SUBTITLE, &msg );
-
-       debug_fleave();
-
-       return ret;
-}
-#endif
-
-static int     __gst_adjust_subtitle_position(mm_player_t* player, int format, int position)
-{
-       GstEvent* event = NULL;
-       gint64 current_pos = 0;
-       gint64 adusted_pos = 0;
-       gboolean ret = TRUE;
-
-       debug_fenter();
-
-       /* check player and subtitlebin are created */
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( player->play_subtitle, MM_ERROR_NOT_SUPPORT_API );
-
-       if (position == 0)
-       {
-               debug_log ("nothing to do\n");
-               return MM_ERROR_NONE;
-       }
-
-       switch (format)
-       {
-               case MM_PLAYER_POS_FORMAT_TIME:
-               {
-                       if (__gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, &current_pos ))
-                       {
-                               debug_error("failed to get position");
-                               return MM_ERROR_PLAYER_INTERNAL;
-                       }
-
-                       adusted_pos = (gint64)current_pos + ((gint64)position * G_GINT64_CONSTANT(1000000));
-                       if (adusted_pos < 0)
-                               adusted_pos = G_GUINT64_CONSTANT(0);
-                       debug_log("adjust subtitle postion : %lu -> %lu [msec]\n", GST_TIME_AS_MSECONDS(current_pos), GST_TIME_AS_MSECONDS(adusted_pos));
-
-                       event = gst_event_new_seek (1.0,        GST_FORMAT_TIME,
-                               ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
-                               GST_SEEK_TYPE_SET, adusted_pos,
-                               GST_SEEK_TYPE_SET, -1);
-               }
-               break;
-
-               default:
-               {
-                       debug_warning("invalid format.\n");
-                       return MM_ERROR_INVALID_ARGUMENT;
-               }
-       }
-
-       /* keep ref to the event */
-       gst_event_ref (event);
-
-       debug_log("sending event[%s] to subparse element [%s]\n",
-                       GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst) );
-
-       if (gst_element_send_event (player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst, event))
-       {
-               debug_log("sending event[%s] to subparse element [%s] success!\n",
-                       GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst) );
-       }
-
-       /* unref to the event */
-       gst_event_unref (event);
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-#ifdef GST_API_VERSION_1
-static void
-__gst_appsrc_feed_data_mem(GstElement *element, guint size, gpointer user_data) // @
-{
-       GstElement *appsrc = element;
-       tBuffer *buf = (tBuffer *)user_data;
-       GstBuffer *buffer = NULL;
-       GstFlowReturn ret = GST_FLOW_OK;
-       gint len = size;
-
-       return_if_fail ( element );
-       return_if_fail ( buf );
-
-       //buffer = gst_buffer_new ();
-
-       if (buf->offset >= buf->len)
-       {
-               debug_log("call eos appsrc\n");
-              g_signal_emit_by_name (appsrc, "end-of-stream", &ret);
-              return;
-       }
-
-       if ( buf->len - buf->offset < size)
-       {
-               len = buf->len - buf->offset + buf->offset;
-       }
-
-       buffer = gst_buffer_new();
-       GstMapInfo info;
-
-       info.data = (guint8*)(buf->buf + buf->offset);
-       gst_buffer_set_size(buffer, len);
-
-       //GST_BUFFER_DATA(buffer) = (guint8*)(buf->buf + buf->offset);
-       //GST_BUFFER_SIZE(buffer) = len;
-       GST_BUFFER_OFFSET(buffer) = buf->offset;
-       GST_BUFFER_OFFSET_END(buffer) = buf->offset + len;
-       gst_buffer_map (buffer, &info, GST_MAP_WRITE);
-
-       debug_log("feed buffer %p, offset %u-%u length %u\n", buffer, buf->offset, buf->len,len);
-       g_signal_emit_by_name (appsrc, "push-buffer", buffer, &ret);
-
-       buf->offset += len;
-}
-#else
-static void
-__gst_appsrc_feed_data_mem(GstElement *element, guint size, gpointer user_data) // @
-{
-       GstElement *appsrc = element;
-       tBuffer *buf = (tBuffer *)user_data;
-       GstBuffer *buffer = NULL;
-       GstFlowReturn ret = GST_FLOW_OK;
-       gint len = size;
-
-       return_if_fail ( element );
-       return_if_fail ( buf );
-
-       buffer = gst_buffer_new ();
-
-       if (buf->offset >= buf->len)
-       {
-               debug_log("call eos appsrc\n");
-              g_signal_emit_by_name (appsrc, "end-of-stream", &ret);
-              return;
-       }
-
-       if ( buf->len - buf->offset < size)
-       {
-               len = buf->len - buf->offset + buf->offset;
-       }
-
-       GST_BUFFER_DATA(buffer) = (guint8*)(buf->buf + buf->offset);
-       GST_BUFFER_SIZE(buffer) = len;
-       GST_BUFFER_OFFSET(buffer) = buf->offset;
-       GST_BUFFER_OFFSET_END(buffer) = buf->offset + len;
-
-       debug_log("feed buffer %p, offset %u-%u length %u\n", buffer, buf->offset, buf->len,len);
-       g_signal_emit_by_name (appsrc, "push-buffer", buffer, &ret);
-
-       buf->offset += len;
-}
-#endif
-
-static gboolean
-__gst_appsrc_seek_data_mem(GstElement *element, guint64 size, gpointer user_data) // @
-{
-       tBuffer *buf = (tBuffer *)user_data;
-
-       return_val_if_fail ( buf, FALSE );
-
-       buf->offset  = (int)size;
-
-       return TRUE;
-}
-
-static void
-__gst_appsrc_feed_data(GstElement *element, guint size, gpointer user_data) // @
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-
-       return_if_fail ( player );
-
-       debug_msg("app-src: feed data\n");
-
-       if(player->need_data_cb)
-               player->need_data_cb(size, player->buffer_cb_user_param);
-}
-
-static gboolean
-__gst_appsrc_seek_data(GstElement *element, guint64 offset, gpointer user_data) // @
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-
-       return_val_if_fail ( player, FALSE );
-
-       debug_msg("app-src: seek data\n");
-
-       if(player->seek_data_cb)
-               player->seek_data_cb(offset, player->buffer_cb_user_param);
-
-       return TRUE;
-}
-
-
-static gboolean
-__gst_appsrc_enough_data(GstElement *element, gpointer user_data) // @
-{
-       mm_player_t *player  = (mm_player_t*)user_data;
-
-       return_val_if_fail ( player, FALSE );
-
-       debug_msg("app-src: enough data:%p\n", player->enough_data_cb);
-
-       if(player->enough_data_cb)
-               player->enough_data_cb(player->buffer_cb_user_param);
-
-       return TRUE;
-}
-
-#ifdef GST_API_VERSION_1
-int
-_mmplayer_push_buffer(MMHandleType hplayer, unsigned char *buf, int size) // @
-{
-       mm_player_t* player = (mm_player_t*)hplayer;
-       GstBuffer *buffer = NULL;
-       GstMapInfo info;
-       GstFlowReturn gst_ret = GST_FLOW_OK;
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       /* check current state */
-//     MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( 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 )
-       {
-               if ( MM_ERROR_NONE != __gst_realize( player ) )
-               {
-                       debug_error("failed to realize before starting. only in streamming\n");
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-       }
-
-       debug_msg("app-src: pushing data\n");
-
-       if ( buf == NULL )
-       {
-               debug_error("buf is null\n");
-               return MM_ERROR_NONE;
-       }
-
-       buffer = gst_buffer_new ();
-
-       if (size <= 0)
-       {
-               debug_log("call eos appsrc\n");
-               g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "end-of-stream", &gst_ret);
-               return MM_ERROR_NONE;
-       }
-
-       info.data = (guint8*)(buf);
-       gst_buffer_set_size(buffer, size);
-       gst_buffer_map (buffer, &info, GST_MAP_WRITE);
-
-       debug_log("feed buffer %p, length %u\n", buf, size);
-       g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "push-buffer", buffer, &gst_ret);
-
-       debug_fleave();
-
-       return ret;
-}
-#else
-int
-_mmplayer_push_buffer(MMHandleType hplayer, unsigned char *buf, int size) // @
-{
-       mm_player_t* player = (mm_player_t*)hplayer;
-       GstBuffer *buffer = NULL;
-       GstFlowReturn gst_ret = GST_FLOW_OK;
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       /* check current state */
-//     MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( 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 )
-       {
-               if ( MM_ERROR_NONE != __gst_realize( player ) )
-               {
-                       debug_error("failed to realize before starting. only in streamming\n");
-                       return MM_ERROR_PLAYER_INTERNAL;
-               }
-       }
-
-       debug_msg("app-src: pushing data\n");
-
-       if ( buf == NULL )
-       {
-               debug_error("buf is null\n");
-               return MM_ERROR_NONE;
-       }
-
-       buffer = gst_buffer_new ();
-
-       if (size <= 0)
-       {
-               debug_log("call eos appsrc\n");
-               g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "end-of-stream", &gst_ret);
-               return MM_ERROR_NONE;
-       }
-
-       GST_BUFFER_DATA(buffer) = (guint8*)(buf);
-       GST_BUFFER_SIZE(buffer) = size;
-
-       debug_log("feed buffer %p, length %u\n", buf, size);
-       g_signal_emit_by_name (player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "push-buffer", buffer, &gst_ret);
-
-       debug_fleave();
-
-       return ret;
-}
-#endif
-
-static GstBusSyncReply
-__mmplayer_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data)
-{
-       mm_player_t *player = (mm_player_t *)data;
-
-       switch (GST_MESSAGE_TYPE (message))
-       {
-               case GST_MESSAGE_TAG:
-                       __mmplayer_gst_extract_tag_from_msg(player, message);
-                       break;
-               case GST_MESSAGE_DURATION:
-                       __mmplayer_gst_handle_duration(player, message);
-                       break;
-
-               default:
-                       return GST_BUS_PASS;
-       }
-       gst_message_unref (message);
-
-       return GST_BUS_DROP;
-}
-
-/**
- * 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) // @
-{
-       GstBus  *bus = NULL;
-       MMPlayerGstElement *mainbin = NULL;
-       MMHandleType attrs = 0;
-       GstElement* element = NULL;
-       GList* element_bucket = NULL;
-       gboolean need_state_holder = TRUE;
-       gint i = 0;
-
-       debug_fenter();
-
-       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       /* get profile attribute */
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
-       {
-               debug_error("cannot get content attribute\n");
-               goto INIT_ERROR;
-       }
-
-       /* create pipeline handles */
-       if ( player->pipeline )
-       {
-               debug_warning("pipeline should be released before create new one\n");
-               goto INIT_ERROR;
-       }
-
-       player->pipeline = (MMPlayerGstPipelineInfo*) g_malloc0( sizeof(MMPlayerGstPipelineInfo) );
-       if (player->pipeline == NULL)
-               goto INIT_ERROR;
-
-       memset( player->pipeline, 0, sizeof(MMPlayerGstPipelineInfo) );
-
-
-       /* create mainbin */
-       mainbin = (MMPlayerGstElement*) g_malloc0( sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM );
-       if (mainbin == NULL)
-               goto INIT_ERROR;
-
-       memset( mainbin, 0, sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM);
-
-
-       /* 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 )
-       {
-               debug_error("failed to create pipeline\n");
-               goto INIT_ERROR;
-       }
-
-
-       /* create source element */
-       switch ( player->profile.uri_type )
-       {
-               /* rtsp streamming */
-               case MM_PLAYER_URI_TYPE_URL_RTSP:
-               {
-                       gint network_bandwidth;
-                       gchar *user_agent, *wap_profile;
-
-                       element = gst_element_factory_make(PLAYER_INI()->name_of_rtspsrc, "streaming_source");
-
-                       if ( !element )
-                       {
-                               debug_critical("failed to create streaming source element\n");
-                               break;
-                       }
-
-                       debug_log("using streamming source [%s].\n", PLAYER_INI()->name_of_rtspsrc);
-
-                       /* make it zero */
-                       network_bandwidth = 0;
-                       user_agent = wap_profile = NULL;
-
-                       /* get attribute */
-                       mm_attrs_get_string_by_name ( attrs, "streaming_user_agent", &user_agent );
-                       mm_attrs_get_string_by_name ( attrs,"streaming_wap_profile", &wap_profile );
-                       mm_attrs_get_int_by_name ( attrs, "streaming_network_bandwidth", &network_bandwidth );
-
-                       debug_log("setting streaming source ----------------\n");
-                       debug_log("user_agent : %s\n", user_agent);
-                       debug_log("wap_profile : %s\n", wap_profile);
-                       debug_log("network_bandwidth : %d\n", network_bandwidth);
-                       debug_log("buffering time : %d\n", PLAYER_INI()->rtsp_buffering_time);
-                       debug_log("rebuffering time : %d\n", PLAYER_INI()->rtsp_rebuffering_time);
-                       debug_log("-----------------------------------------\n");
-
-                       /* setting property to streaming source */
-                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-                       g_object_set(G_OBJECT(element), "bandwidth", network_bandwidth, NULL);
-                       g_object_set(G_OBJECT(element), "buffering_time", PLAYER_INI()->rtsp_buffering_time, NULL);
-                       g_object_set(G_OBJECT(element), "rebuffering_time", PLAYER_INI()->rtsp_rebuffering_time, NULL);
-                       if ( user_agent )
-                               g_object_set(G_OBJECT(element), "user_agent", user_agent, NULL);
-                       if ( wap_profile )
-                               g_object_set(G_OBJECT(element), "wap_profile", wap_profile, NULL);
-
-                       MMPLAYER_SIGNAL_CONNECT ( player, G_OBJECT(element), "pad-added",
-                               G_CALLBACK (__mmplayer_gst_rtp_dynamic_pad), player );
-                       MMPLAYER_SIGNAL_CONNECT ( player, G_OBJECT(element), "no-more-pads",
-                               G_CALLBACK (__mmplayer_gst_rtp_no_more_pads), player );
-
-                       player->no_more_pad = FALSE;
-                       player->num_dynamic_pad = 0;
-
-                       /* NOTE : we cannot determine it yet. this filed will be filled by
-                        * _mmplayer_update_content_attrs() after START.
-                        */
-                       player->streaming_type = STREAMING_SERVICE_NONE;
-               }
-               break;
-
-               /* http streaming*/
-               case MM_PLAYER_URI_TYPE_URL_HTTP:
-               {
-                       gchar *user_agent, *proxy, *cookies, **cookie_list;
-                       user_agent = proxy = cookies = NULL;
-                       cookie_list = NULL;
-                       gint mode = MM_PLAYER_PD_MODE_NONE;
-
-                       mm_attrs_get_int_by_name ( attrs, "pd_mode", &mode );
-
-                       player->pd_mode = mode;
-
-                       debug_log("http playback, PD mode : %d\n", player->pd_mode);
-
-                       if ( ! MMPLAYER_IS_HTTP_PD(player) )
-                       {
-                               element = gst_element_factory_make(PLAYER_INI()->name_of_httpsrc, "http_streaming_source");
-                               if ( !element )
-                               {
-                                       debug_critical("failed to create http streaming source element[%s].\n", PLAYER_INI()->name_of_httpsrc);
-                                       break;
-                               }
-                               debug_log("using http streamming source [%s].\n", PLAYER_INI()->name_of_httpsrc);
-
-                               /* get attribute */
-                               mm_attrs_get_string_by_name ( attrs, "streaming_cookie", &cookies );
-                               mm_attrs_get_string_by_name ( attrs, "streaming_user_agent", &user_agent );
-                               mm_attrs_get_string_by_name ( attrs, "streaming_proxy", &proxy );
-
-                               /* get attribute */
-                               debug_log("setting http streaming source ----------------\n");
-                               debug_log("location : %s\n", player->profile.uri);
-                               debug_log("cookies : %s\n", cookies);
-                               debug_log("proxy : %s\n", proxy);
-                               debug_log("user_agent :  %s\n",  user_agent);
-                               debug_log("timeout : %d\n",  PLAYER_INI()->http_timeout);
-                               debug_log("-----------------------------------------\n");
-
-                               /* setting property to streaming source */
-                               g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
-                               g_object_set(G_OBJECT(element), "timeout", PLAYER_INI()->http_timeout, NULL);
-                               /* check if prosy is vailid or not */
-                               if ( util_check_valid_url ( proxy ) )
-                                       g_object_set(G_OBJECT(element), "proxy", proxy, 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);
-                       }
-                       else // progressive download
-                       {
-                               if (player->pd_mode == MM_PLAYER_PD_MODE_URI)
-                               {
-                                       gchar *path = NULL;
-
-                                       mm_attrs_get_string_by_name ( attrs, "pd_location", &path );
-
-                                       MMPLAYER_FREEIF(player->pd_file_save_path);
-
-                                       debug_log("PD Location : %s\n", path);
-
-                                       if ( path )
-                                       {
-                                               player->pd_file_save_path = g_strdup(path);
-                                       }
-                                       else
-                                       {
-                                               debug_error("can't find pd location so, it should be set \n");
-                                               return MM_ERROR_PLAYER_FILE_NOT_FOUND;
-                                       }
-                               }
-
-                               element = gst_element_factory_make("pdpushsrc", "PD pushsrc");
-                               if ( !element )
-                               {
-                                       debug_critical("failed to create PD push source element[%s].\n", "pdpushsrc");
-                                       break;
-                               }
-
-                               g_object_set(G_OBJECT(element), "location", player->pd_file_save_path, NULL);
-                       }
-
-                       player->streaming_type = STREAMING_SERVICE_NONE;
-               }
-               break;
-
-               /* file source */
-               case MM_PLAYER_URI_TYPE_FILE:
-               {
-                       char* drmsrc = PLAYER_INI()->name_of_drmsrc;
-
-                       debug_log("using [%s] for 'file://' handler.\n", drmsrc);
-
-                       element = gst_element_factory_make(drmsrc, "source");
-                       if ( !element )
-                       {
-                               debug_critical("failed to create %s\n", drmsrc);
-                               break;
-                       }
-
-                       g_object_set(G_OBJECT(element), "location", (player->profile.uri)+7, NULL);     /* uri+7 -> remove "file:// */
-                       //g_object_set(G_OBJECT(element), "use-mmap", TRUE, NULL);
-               }
-               break;
-
-               /* appsrc */
-               case MM_PLAYER_URI_TYPE_BUFF:
-               {
-                       guint64 stream_type = GST_APP_STREAM_TYPE_STREAM;
-
-                       debug_log("mem src is selected\n");
-
-                       element = gst_element_factory_make("appsrc", "buff-source");
-                       if ( !element )
-                       {
-                               debug_critical("failed to create appsrc element\n");
-                               break;
-                       }
-
-                       g_object_set( element, "stream-type", stream_type, NULL );
-                       //g_object_set( element, "size", player->mem_buf.len, NULL );
-                       //g_object_set( element, "blocksize", (guint64)20480, NULL );
-
-                       MMPLAYER_SIGNAL_CONNECT( player, element, "seek-data",
-                               G_CALLBACK(__gst_appsrc_seek_data), player);
-                       MMPLAYER_SIGNAL_CONNECT( player, element, "need-data",
-                               G_CALLBACK(__gst_appsrc_feed_data), player);
-                       MMPLAYER_SIGNAL_CONNECT( player, element, "enough-data",
-                               G_CALLBACK(__gst_appsrc_enough_data), player);
-               }
-               break;
-
-               /* appsrc */
-               case MM_PLAYER_URI_TYPE_MEM:
-               {
-                       guint64 stream_type = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
-
-                       debug_log("mem src is selected\n");
-
-                       element = gst_element_factory_make("appsrc", "mem-source");
-                       if ( !element )
-                       {
-                               debug_critical("failed to create appsrc element\n");
-                               break;
-                       }
-
-                       g_object_set( element, "stream-type", stream_type, NULL );
-                       g_object_set( element, "size", player->mem_buf.len, NULL );
-                       g_object_set( element, "blocksize", (guint64)20480, NULL );
-
-                       MMPLAYER_SIGNAL_CONNECT( player, element, "seek-data",
-                               G_CALLBACK(__gst_appsrc_seek_data_mem), &player->mem_buf );
-                       MMPLAYER_SIGNAL_CONNECT( player, element, "need-data",
-                               G_CALLBACK(__gst_appsrc_feed_data_mem), &player->mem_buf );
-               }
-               break;
-               case MM_PLAYER_URI_TYPE_URL:
-               break;
-
-               case MM_PLAYER_URI_TYPE_TEMP:
-               break;
-
-               case MM_PLAYER_URI_TYPE_NONE:
-               default:
-               break;
-       }
-
-       /* check source element is OK */
-       if ( ! element )
-       {
-               debug_critical("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 = __mm_player_streaming_create();
-               __mm_player_streaming_initialize(player->streamer);
-       }
-
-       if ( MMPLAYER_IS_HTTP_PD(player) )
-       {
-              debug_log ("Picked queue2 element....\n");
-               element = gst_element_factory_make("queue2", "hls_stream_buffer");
-               if ( !element )
-               {
-                       debug_critical ( "failed to create http streaming buffer element\n" );
-                       goto INIT_ERROR;
-               }
-
-               /* take it */
-               mainbin[MMPLAYER_M_S_BUFFER].id = MMPLAYER_M_S_BUFFER;
-               mainbin[MMPLAYER_M_S_BUFFER].gst = element;
-               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_S_BUFFER]);
-
-               __mm_player_streaming_set_buffer(player->streamer,
-                               element,
-                               TRUE,
-                               PLAYER_INI()->http_max_size_bytes,
-                               1.0,
-                               PLAYER_INI()->http_buffering_limit,
-                               PLAYER_INI()->http_buffering_time,
-                               FALSE,
-                               NULL,
-                               0);
-       }
-
-       /* create autoplugging element if src element is not a streamming src */
-       if ( player->profile.uri_type != MM_PLAYER_URI_TYPE_URL_RTSP )
-       {
-               element = NULL;
-
-               if( PLAYER_INI()->use_decodebin )
-               {
-                       /* create decodebin */
-                       element = gst_element_factory_make("decodebin", "decodebin");
-
-                       g_object_set(G_OBJECT(element), "async-handling", TRUE, NULL);
-
-                       /* set signal handler */
-                       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(element), "new-decoded-pad",
-                                       G_CALLBACK(__mmplayer_gst_decode_callback), player);
-
-                       /* we don't need state holder, bcz decodebin is doing well by itself */
-                       need_state_holder = FALSE;
-               }
-               else
-               {
-                       element = gst_element_factory_make("typefind", "typefinder");
-                       MMPLAYER_SIGNAL_CONNECT( player, element, "have-type",
-                               G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player );
-               }
-
-               /* check autoplug element is OK */
-               if ( ! element )
-               {
-                       debug_critical("can not create autoplug element\n");
-                       goto INIT_ERROR;
-               }
-
-               mainbin[MMPLAYER_M_AUTOPLUG].id = MMPLAYER_M_AUTOPLUG;
-               mainbin[MMPLAYER_M_AUTOPLUG].gst = element;
-
-               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_AUTOPLUG]);
-       }
-
-
-       /* add elements to pipeline */
-       if( !__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element_bucket))
-       {
-               debug_error("Failed to add elements to pipeline\n");
-               goto INIT_ERROR;
-       }
-
-
-       /* linking elements in the bucket by added order. */
-       if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
-       {
-               debug_error("Failed to link some elements\n");
-               goto INIT_ERROR;
-       }
-
-
-       /* 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)
-               {
-                       debug_error ("fakesink element could not be created\n");
-                       goto INIT_ERROR;
-               }
-#ifdef GST_API_VERSION_1
-               GST_OBJECT_FLAG_UNSET (mainbin[MMPLAYER_M_SRC_FAKESINK].gst, GST_ELEMENT_FLAG_SINK);
-#else
-               GST_OBJECT_FLAG_UNSET (mainbin[MMPLAYER_M_SRC_FAKESINK].gst, GST_ELEMENT_IS_SINK);
-#endif
-
-               /* take ownership of fakesink. we are reusing it */
-               gst_object_ref( mainbin[MMPLAYER_M_SRC_FAKESINK].gst );
-
-               /* add */
-               if ( FALSE == gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst),
-                       mainbin[MMPLAYER_M_SRC_FAKESINK].gst) )
-               {
-                       debug_error("failed to add fakesink to bin\n");
-                       goto INIT_ERROR;
-               }
-       }
-
-       /* now we have completed mainbin. take it */
-       player->pipeline->mainbin = mainbin;
-
-       /* connect bus callback */
-       bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[MMPLAYER_M_PIPE].gst));
-       if ( !bus )
-       {
-               debug_error ("cannot get bus from pipeline.\n");
-               goto INIT_ERROR;
-       }
-       player->bus_watcher = gst_bus_add_watch(bus, (GstBusFunc)__mmplayer_gst_callback, player);
-
-       /* Note : check whether subtitle atrribute uri is set. If uri is set, then tyr to play subtitle file */
-       if ( __mmplayer_check_subtitle ( player ) )
-       {
-               if ( MM_ERROR_NONE != __mmplayer_gst_create_subtitle_src(player) )
-                       debug_error("fail to create subtitle src\n")
-       }
-
-       /* set sync handler to get tag synchronously */
-#ifdef GST_API_VERSION_1
-       gst_bus_set_sync_handler(bus, __mmplayer_bus_sync_callback, player, NULL);
-#else
-       gst_bus_set_sync_handler(bus, __mmplayer_bus_sync_callback, player);
-#endif
-       /* finished */
-       gst_object_unref(GST_OBJECT(bus));
-       g_list_free(element_bucket);
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-
-INIT_ERROR:
-
-       __mmplayer_gst_destroy_pipeline(player);
-       g_list_free(element_bucket);
-
-       /* 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));
-                       }
-               }
-       }
-
-       /* release pipeline with it's childs */
-       if ( mainbin[MMPLAYER_M_PIPE].gst )
-       {
-               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
-       }
-
-       MMPLAYER_FREEIF( player->pipeline );
-       MMPLAYER_FREEIF( mainbin );
-
-       return MM_ERROR_PLAYER_INTERNAL;
-}
-
-
-static int
-__mmplayer_gst_destroy_pipeline(mm_player_t* player) // @
-{
-       gint timeout = 0;
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       return_val_if_fail ( player, MM_ERROR_INVALID_HANDLE );
-
-       /* cleanup stuffs */
-       MMPLAYER_FREEIF(player->type);
-       player->have_dynamic_pad = FALSE;
-       player->no_more_pad = FALSE;
-       player->num_dynamic_pad = 0;
-
-       if (player->v_stream_caps)
-       {
-               gst_caps_unref(player->v_stream_caps);
-               player->v_stream_caps = NULL;
-       }
-
-       if (ahs_appsrc_cb_probe_id )
-       {
-               GstPad *pad = NULL;
-               pad = gst_element_get_static_pad(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "src" );
-
-#ifdef GST_API_VERSION_1
-               gst_pad_remove_probe (pad, ahs_appsrc_cb_probe_id);
-#else          
-               gst_pad_remove_buffer_probe (pad, ahs_appsrc_cb_probe_id);
-#endif
-               gst_object_unref(pad);
-               pad = NULL;
-               ahs_appsrc_cb_probe_id = 0;
-       }
-
-       if ( player->sink_elements )
-               g_list_free ( player->sink_elements );
-       player->sink_elements = NULL;
-
-       /* 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_delayed_eos( 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 );
-
-               /* disconnecting bus watch */
-               if ( player->bus_watcher )
-                       g_source_remove( 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));
-
-#ifdef GST_API_VERSION_1
-                       gst_bus_set_sync_handler (bus, NULL, NULL, NULL);
-#else
-                       gst_bus_set_sync_handler (bus, NULL, NULL);
-#endif
-                       gst_object_unref(bus);
-
-                       debug_log("pipeline status before set state to NULL\n");
-                       __mmplayer_dump_pipeline_state( player );
-
-                       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 )
-                       {
-                               debug_error("fail to change state to NULL\n");
-                               return MM_ERROR_PLAYER_INTERNAL;
-                       }
-
-                       debug_log("pipeline status before unrefering pipeline\n");
-                       __mmplayer_dump_pipeline_state( player );
-
-                       gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
-
-                       /* free fakesink */
-                       if ( mainbin[MMPLAYER_M_SRC_FAKESINK].gst )
-                               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC_FAKESINK].gst));
-
-                       /* free avsysaudiosink
-                          avsysaudiosink should be unref when destory pipeline just after start play with BT.
-                          Because audiosink is created but never added to bin, and therefore it will not be unref when pipeline is destroyed.
-                       */
-                       MMPLAYER_FREEIF( audiobin );
-                       MMPLAYER_FREEIF( videobin );
-                       MMPLAYER_FREEIF( textbin );
-                       MMPLAYER_FREEIF( mainbin );
-               }
-
-               if ( tag_list )
-                       gst_tag_list_free(tag_list);
-
-               MMPLAYER_FREEIF( player->pipeline );
-       }
-
-       player->pipeline_is_constructed = FALSE;
-
-       debug_fleave();
-
-       return ret;
-}
-
-static int __gst_realize(mm_player_t* player) // @
-{
-       gint timeout = 0;
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
-
-       __ta__("__mmplayer_gst_create_pipeline",
-               ret = __mmplayer_gst_create_pipeline(player);
-               if ( ret )
-               {
-                       debug_critical("failed to create pipeline\n");
-                       return ret;
-               }
-       )
-
-       /* 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 */
-               debug_error("failed to set READY state");
-               return ret;
-       }
-       else
-       {
-               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_READY );
-       }
-
-       /* create dot before error-return. for debugging */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-realize" );
-
-       debug_fleave();
-
-       return ret;
-}
-
-static int __gst_unrealize(mm_player_t* player) // @
-{
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       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 );
-
-       /* destroy pipeline */
-       ret = __mmplayer_gst_destroy_pipeline( player );
-       if ( ret != MM_ERROR_NONE )
-       {
-               debug_error("failed to destory pipeline\n");
-               return ret;
-       }
-
-       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_NULL );
-
-       debug_fleave();
-
-       return ret;
-}
-
-static int __gst_pending_seek ( mm_player_t* player )
-{
-       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
-       MMPlayerStateType pending_state = MM_PLAYER_STATE_NONE;
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       if ( !player->pending_seek.is_pending )
-       {
-               debug_log("pending seek is not reserved. nothing to do.\n" );
-               return ret;
-       }
-
-       /* check player state if player could pending seek or not. */
-       current_state = MMPLAYER_CURRENT_STATE(player);
-       pending_state = MMPLAYER_PENDING_STATE(player);
-
-       if ( current_state != MM_PLAYER_STATE_PAUSED && current_state != MM_PLAYER_STATE_PLAYING  )
-       {
-               debug_warning("try to pending seek in %s state, try next time. \n",
-                       MMPLAYER_STATE_GET_NAME(current_state));
-               return ret;
-       }
-
-       debug_log("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 )
-               debug_error("failed to seek pending postion. just keep staying current position.\n");
-
-       player->pending_seek.is_pending = FALSE;
-
-       debug_fleave();
-
-       return ret;
-}
-
-static int __gst_start(mm_player_t* player) // @
-{
-       gboolean sound_extraction = 0;
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       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);
-
-       /* 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 )
-               {
-                       debug_error("failed to set state to PAUSED for pending seek\n");
-                       return ret;
-               }
-
-               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PLAYING;
-
-               if ( sound_extraction )
-               {
-                       debug_log("setting pcm extraction\n");
-
-                       ret = __mmplayer_set_pcm_extraction(player);
-                       if ( MM_ERROR_NONE != ret )
-                       {
-                               debug_warning("failed to set pcm extraction\n");
-                               return ret;
-                       }
-               }
-               else
-               {
-                       if ( MM_ERROR_NONE != __gst_pending_seek(player) )
-                       {
-                               debug_warning("failed to seek pending postion. starting from the begin of content.\n");
-                       }
-               }
-       }
-
-       debug_log("current state before doing transition");
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
-       MMPLAYER_PRINT_STATE(player);
-
-       /* set pipeline state to PLAYING  */
-       ret = __mmplayer_gst_set_state(player,
-               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, FALSE, MMPLAYER_STATE_CHANGE_TIMEOUT(player) );
-       if (ret == MM_ERROR_NONE)
-       {
-               MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PLAYING);
-       }
-       else
-       {
-               debug_error("failed to set state to PLAYING");
-               return ret;
-       }
-
-       /* generating debug info before returning error */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-start" );
-
-       debug_fleave();
-
-       return ret;
-}
-
-static void __mmplayer_do_sound_fadedown(mm_player_t* player, unsigned int time)
-{
-       debug_fenter();
-
-       return_if_fail(player
-               && player->pipeline
-               && player->pipeline->audiobin
-               && player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
-
-       g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "mute", 2, NULL);
-
-       usleep(time);
-
-       debug_fleave();
-}
-
-static void __mmplayer_undo_sound_fadedown(mm_player_t* player)
-{
-       debug_fenter();
-
-       return_if_fail(player
-               && player->pipeline
-               && player->pipeline->audiobin
-               && player->pipeline->audiobin[MMPLAYER_A_SINK].gst);
-
-       g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "mute", 0, NULL);
-
-       debug_fleave();
-}
-
-static int __gst_stop(mm_player_t* player) // @
-{
-       GstStateChangeReturn change_ret = GST_STATE_CHANGE_SUCCESS;
-       MMHandleType attrs = 0;
-       gboolean fadewown = FALSE;
-       gboolean rewind = FALSE;
-       gint timeout = 0;
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       debug_log("current state before doing transition");
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
-       MMPLAYER_PRINT_STATE(player);
-
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
-       {
-               debug_error("cannot get content attribute\n");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       mm_attrs_get_int_by_name(attrs,"sound_fadedown", &fadewown);
-
-       /* enable fadedown */
-       if (fadewown)
-               __mmplayer_do_sound_fadedown(player, MM_PLAYER_FADEOUT_TIME_DEFAULT);
-
-       /* Just set state to PAUESED and the rewind. it's usual player behavior. */
-       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT ( player );
-       if  ( player->profile.uri_type == MM_PLAYER_URI_TYPE_BUFF || player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS)
-       {
-               ret = __mmplayer_gst_set_state(player,
-                       player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_READY, FALSE, timeout );
-       }
-       else
-       {
-               ret = __mmplayer_gst_set_state( player,
-                       player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED, FALSE, timeout );
-
-               if ( !MMPLAYER_IS_STREAMING(player))
-                       rewind = TRUE;
-       }
-
-       /* disable fadeout */
-       if (fadewown)
-               __mmplayer_undo_sound_fadedown(player);
-
-
-       /* return if set_state has failed */
-       if ( ret != MM_ERROR_NONE )
-       {
-               debug_error("failed to set state.\n");
-               return ret;
-       }
-
-       /* 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) )
-               {
-                       debug_warning("failed to rewind\n");
-                       ret = MM_ERROR_PLAYER_SEEK;
-               }
-       }
-
-       /* initialize */
-       player->sent_bos = FALSE;
-
-       /* 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 );
-       }
-       else
-       {
-               debug_error("fail to stop player.\n");
-               ret = MM_ERROR_PLAYER_INTERNAL;
-               __mmplayer_dump_pipeline_state(player);
-       }
-
-       /* generate dot file if enabled */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-stop" );
-
-       debug_fleave();
-
-       return ret;
-}
-
-int __gst_pause(mm_player_t* player, gboolean async) // @
-{
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       debug_log("current state before doing transition");
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PAUSED;
-       MMPLAYER_PRINT_STATE(player);
-
-       /* 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));
-
-       if ( FALSE == async && ret != MM_ERROR_NONE )
-       {
-               GstMessage *msg = NULL;
-               GTimer *timer = NULL;
-               gdouble MAX_TIMEOUT_SEC = 3;
-
-               debug_error("failed to set state to PAUSED");
-
-               timer = g_timer_new();
-               g_timer_start(timer);
-
-               GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
-               /* check if gst error posted or not */
-               do
-               {
-                       msg = gst_bus_timed_pop(bus, GST_SECOND /2);
-                       if (msg)
-                       {
-                               if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR)
-                               {
-                                       GError *error = NULL;
-
-                                       debug_error("paring error posted from bus");
-                                       /* parse error code */
-                                       gst_message_parse_error(msg, &error, NULL);
-
-                                       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 );
-                                       }
-                                       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 );
-                                       }
-                                       player->msg_posted = TRUE;
-                               }
-                               gst_message_unref(msg);
-                       }
-               } while (g_timer_elapsed(timer, NULL) < MAX_TIMEOUT_SEC);
-
-               /* clean */
-               gst_object_unref(bus);
-               g_timer_stop (timer);
-               g_timer_destroy (timer);
-
-               return ret;
-       }
-       else
-       {
-               if ( async == FALSE )
-               {
-                       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PAUSED );
-               }
-       }
-
-       /* FIXIT : analyze so called "async problem" */
-       /* set async off */
-       __gst_set_async_state_change( player, TRUE);
-
-       /* generate dot file before returning error */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-pause" );
-
-       debug_fleave();
-
-       return ret;
-}
-
-int __gst_resume(mm_player_t* player, gboolean async) // @
-{
-       int ret = MM_ERROR_NONE;
-       gint timeout = 0;
-       GstBus *bus = NULL;
-
-       debug_fenter();
-
-       return_val_if_fail(player && player->pipeline,
-               MM_ERROR_PLAYER_NOT_INITIALIZED);
-
-       debug_log("current state before doing transition");
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
-       MMPLAYER_PRINT_STATE(player);
-
-       /* generate dot file before returning error */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-resume" );
-
-       __mmplayer_set_antishock( player , FALSE );
-
-       if ( async )
-               debug_log("do async state transition to PLAYING.\n");
-
-       /* clean bus sync handler because it's not needed any more */
-       bus = gst_pipeline_get_bus (GST_PIPELINE(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
-#ifdef GST_API_VERSION_1
-                       gst_bus_set_sync_handler (bus, NULL, NULL, NULL);
-#else
-                       gst_bus_set_sync_handler (bus, NULL, NULL);
-#endif
-       gst_object_unref(bus);
-
-       /* set pipeline state to PLAYING */
-       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
-
-       ret = __mmplayer_gst_set_state(player,
-               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, async, timeout );
-       if (ret != MM_ERROR_NONE)
-       {
-               debug_error("failed to set state to PLAYING\n");
-
-               return ret;
-       }
-       else
-       {
-               if (async == FALSE)
-               {
-                       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PLAYING );
-               }
-       }
-
-       /* FIXIT : analyze so called "async problem" */
-       /* set async off */
-       __gst_set_async_state_change( player, FALSE );
-
-       /* generate dot file before returning error */
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-resume" );
-
-       debug_fleave();
-
-       return ret;
-}
-
-static int
-__gst_set_position(mm_player_t* player, int format, unsigned long position, gboolean internal_called) // @
-{
-#ifndef GST_API_VERSION_1
-       GstFormat fmt  = GST_FORMAT_TIME;
-#endif
-       unsigned long dur_msec = 0;
-       gint64 dur_nsec = 0;
-       gint64 pos_nsec = 0;
-       gboolean ret = TRUE;
-
-       debug_fenter();
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       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;
-
-       /* 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 )
-       {
-#ifdef GST_API_VERSION_1
-               if ( !gst_element_query_duration( player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &dur_nsec ))
-               {
-                       goto SEEK_ERROR;
-               }
-#else
-               if ( !gst_element_query_duration( player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &dur_nsec ))
-               {
-                       goto SEEK_ERROR;
-               }
-#endif
-               player->duration = dur_nsec;
-       }
-
-       if ( player->duration )
-       {
-               dur_msec = GST_TIME_AS_MSECONDS(player->duration);
-       }
-       else
-       {
-               debug_error("could not get the duration. fail to seek.\n");
-               goto SEEK_ERROR;
-       }
-
-       debug_log("playback rate: %f\n", player->playback_rate);
-
-       /* do seek */
-       switch ( format )
-       {
-               case MM_PLAYER_POS_FORMAT_TIME:
-               {
-                       /* check position is valid or not */
-                       if ( position > dur_msec )
-                               goto INVALID_ARGS;
-
-                       debug_log("seeking to (%lu) msec, duration is %d msec\n", position, dur_msec);
-
-                       if (player->doing_seek)
-                       {
-                               debug_log("not completed seek");
-                               return MM_ERROR_PLAYER_DOING_SEEK;
-                       }
-
-                       if ( !internal_called)
-                               player->doing_seek = TRUE;
-
-                       pos_nsec = position * G_GINT64_CONSTANT(1000000);
-                       ret = __gst_seek ( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, player->playback_rate,
-                                                       GST_FORMAT_TIME, ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
-                                                       GST_SEEK_TYPE_SET, pos_nsec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
-                       if ( !ret  )
-                       {
-                               debug_error("failed to set position. dur[%lu]  pos[%lu]  pos_msec[%llu]\n", dur_msec, position, pos_nsec);
-                               goto SEEK_ERROR;
-                       }
-               }
-               break;
-
-               case MM_PLAYER_POS_FORMAT_PERCENT:
-               {
-                       debug_log("seeking to (%lu)%% \n", position);
-
-                       if (player->doing_seek)
-                       {
-                               debug_log("not completed seek");
-                               return MM_ERROR_PLAYER_DOING_SEEK;
-                       }
-
-                       if ( !internal_called)
-                               player->doing_seek = TRUE;
-
-                       /* 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, ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
-                                                       GST_SEEK_TYPE_SET, pos_nsec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
-                       if ( !ret  )
-                       {
-                               debug_error("failed to set position. dur[%lud]  pos[%lud]  pos_msec[%llud]\n", dur_msec, position, pos_nsec);
-                               goto SEEK_ERROR;
-                       }
-               }
-               break;
-
-               default:
-                       goto INVALID_ARGS;
-
-       }
-
-       /* 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 );
-
-       debug_fleave();
-       return MM_ERROR_NONE;
-
-PENDING:
-       player->pending_seek.is_pending = TRUE;
-       player->pending_seek.format = format;
-       player->pending_seek.pos = position;
-
-       debug_warning("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);
-
-       return MM_ERROR_NONE;
-
-INVALID_ARGS:
-       debug_error("invalid arguments, position : %ld  dur : %ld format : %d \n", position, dur_msec, format);
-       return MM_ERROR_INVALID_ARGUMENT;
-
-SEEK_ERROR:
-       player->doing_seek = FALSE;
-       return MM_ERROR_PLAYER_SEEK;
-}
-
-#define TRICKPLAY_OFFSET GST_MSECOND
-
-static int
-__gst_get_position(mm_player_t* player, int format, unsigned long* position) // @
-{
-       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
-#ifndef GST_API_VERSION_1
-       GstFormat fmt = GST_FORMAT_TIME;
-#endif
-       signed long long pos_msec = 0;
-       gboolean ret = TRUE;
-
-       return_val_if_fail( player && position && player->pipeline && player->pipeline->mainbin,
-               MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       current_state = MMPLAYER_CURRENT_STATE(player);
-
-       /* 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 )
-       {
-#ifdef GST_API_VERSION_1
-               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_msec);
-#else
-               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &pos_msec);
-#endif
-       }
-
-       /* 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 ))
-               //|| ( player->last_position != 0 && pos_msec == 0 ) )
-       {
-               debug_warning ("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS (pos_msec), ret, current_state);
-
-               if(player->playback_rate < 0.0)
-                       pos_msec = player->last_position - TRICKPLAY_OFFSET;
-               else
-                       pos_msec = player->last_position;
-
-               if (!ret)
-                       pos_msec = player->last_position;
-               else
-                       player->last_position = pos_msec;
-
-               debug_warning("returning last point : %"GST_TIME_FORMAT, GST_TIME_ARGS(pos_msec));
-
-       }
-       else
-       {
-               player->last_position = pos_msec;
-       }
-
-       switch (format) {
-               case MM_PLAYER_POS_FORMAT_TIME:
-                       *position = GST_TIME_AS_MSECONDS(pos_msec);
-                       break;
-
-               case MM_PLAYER_POS_FORMAT_PERCENT:
-               {
-                       int dur = 0;
-                       int pos = 0;
-
-                       dur = player->duration / GST_SECOND;
-                       if (dur <= 0)
-                       {
-                               debug_log ("duration is [%d], so returning position 0\n",dur);
-                               *position = 0;
-                       }
-                       else
-                       {
-                               pos = pos_msec / GST_SECOND;
-                               *position = pos * 100 / dur;
-                       }
-                       break;
-               }
-               default:
-                       return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       debug_log("current position : %lu\n", *position);
-
-
-       return MM_ERROR_NONE;
-}
-
-
-static int     __gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos)
-{
-       GstElement *element = NULL;
-       GstQuery *query = NULL;
-
-       return_val_if_fail( player &&
-               player->pipeline &&
-               player->pipeline->mainbin,
-               MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       return_val_if_fail( start_pos && stop_pos, MM_ERROR_INVALID_ARGUMENT );
-
-       if ( MMPLAYER_IS_HTTP_STREAMING ( player ))
-       {
-               /* Note : In case of http streaming or HLS, the buffering queue [ queue2 ] could handle buffering query. */
-               element = GST_ELEMENT ( player->pipeline->mainbin[MMPLAYER_M_S_BUFFER].gst );
-       }
-       else if ( MMPLAYER_IS_RTSP_STREAMING ( player ) )
-       {
-               debug_warning ( "it's not supported yet.\n" );
-               return MM_ERROR_NONE;
-       }
-       else
-       {
-               debug_warning ( "it's only used for streaming case.\n" );
-               return MM_ERROR_NONE;
-       }
-
-       *start_pos = 0;
-       *stop_pos = 0;
-
-       switch ( format )
-       {
-               case MM_PLAYER_POS_FORMAT_PERCENT :
-               {
-                               query = gst_query_new_buffering ( GST_FORMAT_PERCENT );
-                               if ( gst_element_query ( element, query ) )
-                               {
-                                       gint64 start, stop;
-                                       GstFormat format;
-                                       gboolean busy;
-                                       gint percent;
-
-                                       gst_query_parse_buffering_percent ( query, &busy, &percent);
-                                       gst_query_parse_buffering_range ( query, &format, &start, &stop, NULL );
-
-                                       debug_log ( "buffering start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT "\n",  start, stop);
-
-                                       if ( start != -1)
-                                               *start_pos = 100 * start / GST_FORMAT_PERCENT_MAX;
-                                       else
-                                               *start_pos = 0;
-
-                                       if ( stop != -1)
-                                               *stop_pos = 100 * stop / GST_FORMAT_PERCENT_MAX;
-                                       else
-                                               *stop_pos = 0;
-                               }
-                               gst_query_unref (query);
-               }
-               break;
-
-               case MM_PLAYER_POS_FORMAT_TIME :
-                       debug_warning ( "Time format is not supported yet.\n" );
-                       break;
-
-               default :
-                       break;
-       }
-
-       debug_log("current buffer position : %lu~%lu \n", *start_pos, *stop_pos );
-
-       return MM_ERROR_NONE;
-}
-
-static int
-__gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param) // @
-{
-       debug_fenter();
-
-       if ( !player )
-       {
-               debug_warning("set_message_callback is called with invalid player handle\n");
-               return MM_ERROR_PLAYER_NOT_INITIALIZED;
-       }
-
-       player->msg_cb = callback;
-       player->msg_cb_param = user_param;
-
-       debug_log("msg_cb : 0x%x     msg_cb_param : 0x%x\n", (guint)callback, (guint)user_param);
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static gboolean __mmfplayer_parse_profile(const char *uri, void *param, MMPlayerParseProfile* data) // @
-{
-       gboolean ret = FALSE;
-       char *path = NULL;
-
-       debug_fenter();
-
-       return_val_if_fail ( uri , FALSE);
-       return_val_if_fail ( data , FALSE);
-       return_val_if_fail ( ( strlen(uri) <= MM_MAX_URL_LEN ), FALSE );
-
-       memset(data, 0, sizeof(MMPlayerParseProfile));
-
-       if ((path = strstr(uri, "file://")))
-       {
-               if (util_exist_file_path(path + 7)) {
-                       strncpy(data->uri, path, MM_MAX_URL_LEN-1);
-
-                       if ( util_is_sdp_file ( path ) )
-                       {
-                               debug_log("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 = TRUE;
-               }
-               else
-               {
-                       debug_warning("could  access %s.\n", path);
-               }
-       }
-       else if ((path = strstr(uri, "buff://")))
-       {
-                       data->uri_type = MM_PLAYER_URI_TYPE_BUFF;
-                       ret = TRUE;
-       }
-       else if ((path = strstr(uri, "rtsp://")))
-       {
-               if (strlen(path)) {
-                       strcpy(data->uri, uri);
-                       data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
-                       ret = TRUE;
-               }
-       }
-       else if ((path = strstr(uri, "http://")))
-       {
-               if (strlen(path)) {
-                       strcpy(data->uri, uri);
-                               data->uri_type = MM_PLAYER_URI_TYPE_URL_HTTP;
-
-                       ret = TRUE;
-               }
-       }
-       else if ((path = strstr(uri, "https://")))
-       {
-               if (strlen(path)) {
-                       strcpy(data->uri, uri);
-                               data->uri_type = MM_PLAYER_URI_TYPE_URL_HTTP;
-
-                       ret = TRUE;
-               }
-       }
-       else if ((path = strstr(uri, "rtspu://")))
-       {
-               if (strlen(path)) {
-                       strcpy(data->uri, uri);
-                       data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
-                       ret = TRUE;
-               }
-       }
-       else if ((path = strstr(uri, "rtspr://")))
-       {
-               strcpy(data->uri, path);
-               char *separater =strstr(path, "*");
-
-               if (separater) {
-                       int urgent_len = 0;
-                       char *urgent = separater + strlen("*");
-
-                       if ((urgent_len = strlen(urgent))) {
-                               data->uri[strlen(path) - urgent_len - strlen("*")] = '\0';
-                               strcpy(data->urgent, urgent);
-                               data->uri_type = MM_PLAYER_URI_TYPE_URL_RTSP;
-                               ret = TRUE;
-                       }
-               }
-       }
-       else if ((path = strstr(uri, "mms://")))
-       {
-               if (strlen(path)) {
-                       strcpy(data->uri, uri);
-                       data->uri_type = MM_PLAYER_URI_TYPE_URL_MMS;
-                       ret = TRUE;
-               }
-       }
-       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)) {
-                                               strcpy(ext, buffer);
-
-                                               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) {
-                                               strcpy(size, buffer);
-
-                                               if ((seperator = strchr(size, ','))
-                                                       || (seperator = strchr(size, ' '))
-                                                       || (seperator = strchr(size, '\0'))) {
-                                                       seperator[0] = '\0';
-                                               }
-
-                                               mem_size = atoi(size);
-                                       }
-                               }
-                       }
-
-                       debug_log("ext: %s, mem_size: %d, mmap(param): %p\n", ext, mem_size, param);
-                       if ( mem_size && param) {
-                                       data->mem = param;
-                                       data->mem_size = mem_size;
-                               data->uri_type = MM_PLAYER_URI_TYPE_MEM;
-                               ret = TRUE;
-                       }
-               }
-       }
-       else
-       {
-               /* if no protocol prefix exist. check file existence and then give file:// as it's prefix */
-               if (util_exist_file_path(uri))
-               {
-                       debug_warning("uri has no protocol-prefix. giving 'file://' by default.\n");
-                       g_snprintf(data->uri,  MM_MAX_URL_LEN, "file://%s", uri);
-
-                       if ( util_is_sdp_file( (char*)uri ) )
-                       {
-                               debug_log("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 = TRUE;
-               }
-               else
-               {
-                       debug_error ("invalid uri, could not play..\n");
-                       data->uri_type = MM_PLAYER_URI_TYPE_NONE;
-               }
-       }
-
-       if (data->uri_type == MM_PLAYER_URI_TYPE_NONE) {
-               ret = FALSE;
-       }
-
-       /* dump parse result */
-       debug_log("profile parsing result ---\n");
-       debug_warning("incomming uri : %s\n", uri);
-       debug_log("uri : %s\n", data->uri);
-       debug_log("uri_type : %d\n", data->uri_type);
-       debug_log("play_mode : %d\n", data->play_mode);
-       debug_log("mem : 0x%x\n", (guint)data->mem);
-       debug_log("mem_size : %d\n", data->mem_size);
-       debug_log("urgent : %s\n", data->urgent);
-       debug_log("--------------------------\n");
-
-       debug_fleave();
-
-       return ret;
-}
-
-gboolean _asm_postmsg(gpointer *data)
-{
-       mm_player_t* player = (mm_player_t*)data;
-       MMMessageParamType msg = {0, };
-
-       debug_fenter();
-
-       return_val_if_fail ( player, FALSE );
-
-       msg.union_type = MM_MSG_UNION_CODE;
-       msg.code = player->sm.event_src;
-
-       MMPLAYER_POST_MSG( player, MM_MESSAGE_READY_TO_RESUME, &msg);
-
-       return FALSE;
-}
-
-gboolean _asm_lazy_pause(gpointer *data)
-{
-       mm_player_t* player = (mm_player_t*)data;
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       return_val_if_fail ( player, FALSE );
-
-       if (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PLAYING)
-       {
-               debug_log ("Ready to proceed lazy pause\n");
-               ret = _mmplayer_pause((MMHandleType)player);
-               if(MM_ERROR_NONE != ret)
-               {
-                       debug_error("MMPlayer pause failed in ASM callback lazy pause\n");
-               }
-       }
-       else
-       {
-               debug_log ("Invalid state to proceed lazy pause\n");
-       }
-
-       /* unset mute */
-       if (player->pipeline && player->pipeline->audiobin)
-               g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "mute", 0, NULL);
-
-       player->sm.by_asm_cb = 0; //should be reset here
-
-       debug_fleave();
-
-       return FALSE;
-}
-
-ASM_cb_result_t
-__mmplayer_asm_callback(int handle, ASM_event_sources_t event_src, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data)
-{
-       mm_player_t* player = (mm_player_t*) cb_data;
-       ASM_cb_result_t cb_res = ASM_CB_RES_IGNORE;
-       int result = MM_ERROR_NONE;
-       gboolean lazy_pause = FALSE;
-
-       debug_fenter();
-
-       return_val_if_fail ( player && player->pipeline, ASM_CB_RES_IGNORE );
-       return_val_if_fail ( player->attrs, MM_ERROR_PLAYER_INTERNAL );
-
-       if (player->is_sound_extraction)
-       {
-               debug_log("sound extraction is working...so, asm command is ignored.\n");
-               return result;
-       }
-
-       player->sm.by_asm_cb = 1; // it should be enabled for player state transition with called application command
-       player->sm.event_src = event_src;
-
-       if(event_src == ASM_EVENT_SOURCE_EARJACK_UNPLUG )
-       {
-               int stop_by_asm = 0;
-
-               mm_attrs_get_int_by_name(player->attrs, "sound_stop_when_unplugged", &stop_by_asm);
-               if (!stop_by_asm)
-                       return cb_res;
-       }
-       else if (event_src == ASM_EVENT_SOURCE_RESOURCE_CONFLICT)
-       {
-               /* can use video overlay simultaneously */
-               /* video resource conflict */
-               if(player->pipeline->videobin)
-               {
-                       if (PLAYER_INI()->multiple_codec_supported)
-                       {
-                               debug_log("video conflict but, can support to use video overlay simultaneously");
-                               result = _mmplayer_pause((MMHandleType)player);
-                               cb_res = ASM_CB_RES_PAUSE;
-                       }
-                       else
-                       {
-                               debug_log("video conflict, can't support for multiple codec instance");
-                               result = _mmplayer_unrealize((MMHandleType)player);
-                               cb_res = ASM_CB_RES_STOP;
-                       }
-               }
-               return cb_res;
-       }
-
-       switch(command)
-       {
-               case ASM_COMMAND_PLAY:
-                       debug_warning ("Got unexpected asm command (%d)", command);
-               break;
-
-               case ASM_COMMAND_STOP: // notification case
-               {
-                       debug_warning("Got msg from asm to stop");
-
-                       result = _mmplayer_stop((MMHandleType)player);
-                       if (result != MM_ERROR_NONE)
-                       {
-                               debug_warning("fail to set stop state by asm");
-                               cb_res = ASM_CB_RES_IGNORE;
-                       }
-                       else
-                       {
-                               cb_res = ASM_CB_RES_STOP;
-                       }
-                       player->sm.by_asm_cb = 0; // reset because no message any more from asm
-               }
-               break;
-
-               case ASM_COMMAND_PAUSE:
-               {
-                       debug_warning("Got msg from asm to Pause");
-
-                       if(event_src == ASM_EVENT_SOURCE_CALL_START
-                               || event_src == ASM_EVENT_SOURCE_ALARM_START
-                               || event_src == ASM_EVENT_SOURCE_MEDIA)
-                       {
-                               //hold 0.7 second to excute "fadedown mute" effect
-                               debug_warning ("do fade down->pause->undo fade down");
-
-                               __mmplayer_do_sound_fadedown(player, MM_PLAYER_FADEOUT_TIME_DEFAULT);
-
-                               result = _mmplayer_pause((MMHandleType)player);
-                               if (result != MM_ERROR_NONE)
-                               {
-                                       debug_warning("fail to set Pause state by asm");
-                                       cb_res = ASM_CB_RES_IGNORE;
-                                       break;
-                               }
-                               __mmplayer_undo_sound_fadedown(player);
-                       }
-                       else if(event_src == ASM_EVENT_SOURCE_OTHER_PLAYER_APP)
-                       {
-                               lazy_pause = TRUE; // return as soon as possible, for fast start of other app
-
-                               if ( player->pipeline->audiobin && player->pipeline->audiobin[MMPLAYER_A_SINK].gst )
-                                       g_object_set( player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "mute", 2, NULL);
-
-                               player->lazy_pause_event_id = g_timeout_add(LAZY_PAUSE_TIMEOUT_MSEC, (GSourceFunc)_asm_lazy_pause, (gpointer)player);
-                               debug_warning ("set lazy pause timer (id=[%d], timeout=[%d ms])", player->lazy_pause_event_id, LAZY_PAUSE_TIMEOUT_MSEC);
-                       }
-                       else
-                       {
-                               //immediate pause
-                               debug_log ("immediate pause");
-                               result = _mmplayer_pause((MMHandleType)player);
-                       }
-                       cb_res = ASM_CB_RES_PAUSE;
-               }
-               break;
-
-               case ASM_COMMAND_RESUME:
-               {
-                       debug_warning("Got msg from asm to Resume. So, application can resume. code (%d) \n", event_src);
-                       player->sm.by_asm_cb = 0;
-                       //ASM server is single thread daemon. So use g_idle_add() to post resume msg
-                       g_idle_add((GSourceFunc)_asm_postmsg, (gpointer)player);
-                       cb_res = ASM_CB_RES_IGNORE;
-               }
-               break;
-
-               default:
-               break;
-       }
-
-       if (!lazy_pause)
-               player->sm.by_asm_cb = 0;
-
-       debug_fleave();
-
-       return cb_res;
-}
-
-int
-_mmplayer_create_player(MMHandleType handle) // @
-{
-       mm_player_t* player = MM_PLAYER_CAST(handle);
-
-       debug_fenter();
-
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       MMTA_ACUM_ITEM_BEGIN("[KPI] media player service create->playing", FALSE);
-
-       /* initialize player state */
-       MMPLAYER_CURRENT_STATE(player) = MM_PLAYER_STATE_NONE;
-       MMPLAYER_PREV_STATE(player) = MM_PLAYER_STATE_NONE;
-       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NONE;
-       MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_NONE;
-
-       /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL ( player, MMPLAYER_COMMAND_CREATE );
-
-       /* construct attributes */
-       player->attrs = _mmplayer_construct_attribute(handle);
-
-       if ( !player->attrs )
-       {
-               debug_critical("Failed to construct attributes\n");
-               goto ERROR;
-       }
-
-       /* initialize gstreamer with configured parameter */
-       if ( ! __mmplayer_gstreamer_init() )
-       {
-               debug_critical("Initializing gstreamer failed\n");
-               goto ERROR;
-       }
-
-       /* initialize factories if not using decodebin */
-       if ( FALSE == PLAYER_INI()->use_decodebin )
-       {
-               if( player->factories == NULL )
-                   __mmplayer_init_factories(player);
-       }
-
-       /* create lock. note that g_tread_init() has already called in gst_init() */
-       player->fsink_lock = g_mutex_new();
-       if ( ! player->fsink_lock )
-       {
-               debug_critical("Cannot create mutex for command lock\n");
-               goto ERROR;
-       }
-
-       /* create repeat mutex */
-       player->repeat_thread_mutex = g_mutex_new();
-       if ( ! player->repeat_thread_mutex )
-       {
-               debug_critical("Cannot create repeat mutex\n");
-               goto ERROR;
-       }
-
-       /* create repeat cond */
-       player->repeat_thread_cond = g_cond_new();
-       if ( ! player->repeat_thread_cond )
-       {
-               debug_critical("Cannot create repeat cond\n");
-               goto ERROR;
-       }
-
-       /* create repeat thread */
-       player->repeat_thread =
-               g_thread_create (__mmplayer_repeat_thread, (gpointer)player, TRUE, NULL);
-       if ( ! player->repeat_thread )
-       {
-               goto ERROR;
-       }
-
-       if ( MM_ERROR_NONE != _mmplayer_initialize_video_capture(player))
-       {
-               debug_error("failed to initialize video capture\n");
-               goto ERROR;
-       }
-
-       /* register to asm */
-       if ( MM_ERROR_NONE != _mmplayer_asm_register(&player->sm, (ASM_sound_cb_t)__mmplayer_asm_callback, (void*)player) )
-       {
-               /* NOTE : we are dealing it as an error since we cannot expect it's behavior */
-               debug_error("failed to register asm server\n");
-               return MM_ERROR_POLICY_INTERNAL;
-       }
-
-       if (MMPLAYER_IS_HTTP_PD(player))
-       {
-               player->pd_downloader = NULL;
-               player->pd_file_save_path = NULL;
-       }
-
-       /* give default value of audio effect setting */
-       player->bypass_audio_effect = TRUE;
-       player->sound.volume = MM_VOLUME_FACTOR_DEFAULT;
-       player->playback_rate = DEFAULT_PLAYBACK_RATE;
-
-       player->play_subtitle = FALSE;
-       player->use_textoverlay = FALSE;
-
-       /* set player state to null */
-       MMPLAYER_STATE_CHANGE_TIMEOUT(player) = PLAYER_INI()->localplayback_state_change_timeout;
-       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_NULL );
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-
-ERROR:
-       /* free lock */
-       if ( player->fsink_lock )
-               g_mutex_free( player->fsink_lock );
-       player->fsink_lock = NULL;
-
-       /* free thread */
-       if ( player->repeat_thread_cond &&
-                player->repeat_thread_mutex &&
-                player->repeat_thread )
-       {
-               player->repeat_thread_exit = TRUE;
-               g_cond_signal( player->repeat_thread_cond );
-
-               g_thread_join( player->repeat_thread );
-               player->repeat_thread = NULL;
-
-               g_mutex_free ( player->repeat_thread_mutex );
-               player->repeat_thread_mutex = NULL;
-
-               g_cond_free ( player->repeat_thread_cond );
-               player->repeat_thread_cond = NULL;
-       }
-       /* clear repeat thread mutex/cond if still alive
-        * this can happen if only thread creating has failed
-        */
-       if ( player->repeat_thread_mutex )
-               g_mutex_free ( player->repeat_thread_mutex );
-
-       if ( player->repeat_thread_cond )
-               g_cond_free ( player->repeat_thread_cond );
-
-       /* release attributes */
-       _mmplayer_deconstruct_attribute(handle);
-
-       return MM_ERROR_PLAYER_INTERNAL;
-}
-
-static gboolean
-__mmplayer_gstreamer_init(void) // @
-{
-       static gboolean initialized = FALSE;
-       static const int max_argc = 50;
-       gint* argc = NULL;
-       gchar** argv = NULL;
-       GError *err = NULL;
-       int i = 0;
-
-       debug_fenter();
-
-       if ( initialized )
-       {
-               debug_log("gstreamer already initialized.\n");
-               return TRUE;
-       }
-
-       /* alloc */
-       argc = malloc( sizeof(int) );
-       argv = malloc( sizeof(gchar*) * max_argc );
-
-       if ( !argc || !argv )
-               goto ERROR;
-
-       memset( argv, 0, sizeof(gchar*) * max_argc );
-
-       /* add initial */
-       *argc = 1;
-       argv[0] = g_strdup( "mmplayer" );
-
-       /* add gst_param */
-       for ( i = 0; i < 5; i++ ) /* FIXIT : num of param is now fixed to 5. make it dynamic */
-       {
-               if ( strlen( PLAYER_INI()->gst_param[i] ) > 0 )
-               {
-                       argv[*argc] = g_strdup( PLAYER_INI()->gst_param[i] );
-                       (*argc)++;
-               }
-       }
-
-       /* we would not do fork for scanning plugins */
-       argv[*argc] = g_strdup("--gst-disable-registry-fork");
-       (*argc)++;
-
-       /* check disable registry scan */
-       if ( PLAYER_INI()->skip_rescan )
-       {
-               argv[*argc] = g_strdup("--gst-disable-registry-update");
-               (*argc)++;
-       }
-
-       /* check disable segtrap */
-       if ( PLAYER_INI()->disable_segtrap )
-       {
-               argv[*argc] = g_strdup("--gst-disable-segtrap");
-               (*argc)++;
-       }
-
-       debug_log("initializing gstreamer with following parameter\n");
-       debug_log("argc : %d\n", *argc);
-
-       for ( i = 0; i < *argc; i++ )
-       {
-               debug_log("argv[%d] : %s\n", i, argv[i]);
-       }
-
-
-       /* initializing gstreamer */
-       __ta__("gst_init time",
-
-               if ( ! gst_init_check (argc, &argv, &err))
-               {
-                       debug_error("Could not initialize GStreamer: %s\n", err ? err->message : "unknown error occurred");
-                       if (err)
+                       if ( util_is_sdp_file( (char*)uri ) )
                        {
-                               g_error_free (err);
+                               debug_log("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 = TRUE;
+               }
+               else
+               {
+                       debug_error ("invalid uri, could not play..\n");
+                       data->uri_type = MM_PLAYER_URI_TYPE_NONE;
+               }
+       }
 
-                       goto ERROR;
-               }
-       );
-
-       /* release */
-       for ( i = 0; i < *argc; i++ )
-       {
-               MMPLAYER_FREEIF( argv[i] );
-       }
-
-       MMPLAYER_FREEIF( argv );
-       MMPLAYER_FREEIF( argc );
-
-       /* done */
-       initialized = TRUE;
-
-       debug_fleave();
-
-       return TRUE;
-
-ERROR:
-
-       MMPLAYER_FREEIF( argv );
-       MMPLAYER_FREEIF( argc );
-
-       return FALSE;
-}
-
-int
-__mmplayer_destroy_streaming_ext(mm_player_t* player)
-{
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       if (player->pd_downloader)
-               _mmplayer_unrealize_pd_downloader((MMHandleType)player);
-
-       if (MMPLAYER_IS_HTTP_PD(player))
-               _mmplayer_destroy_pd_downloader((MMHandleType)player);
-
-       if (MMPLAYER_IS_STREAMING(player))
-       {
-               if (player->streamer)
-               {
-                       __mm_player_streaming_deinitialize (player->streamer);
-                       __mm_player_streaming_destroy(player->streamer);
-                       player->streamer = NULL;
-               }
-       }
-       return MM_ERROR_NONE;
-}
-
-int
-_mmplayer_destroy(MMHandleType handle) // @
-{
-       mm_player_t* player = MM_PLAYER_CAST(handle);
-
-       debug_fenter();
-
-       /* check player handle */
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       /* destroy can called at anytime */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL ( player, MMPLAYER_COMMAND_DESTROY );
-
-       __mmplayer_destroy_streaming_ext(player);
-
-       /* release repeat thread */
-       if ( player->repeat_thread_cond &&
-                player->repeat_thread_mutex &&
-                player->repeat_thread )
-       {
-               player->repeat_thread_exit = TRUE;
-               g_cond_signal( player->repeat_thread_cond );
-
-               debug_log("waitting for repeat thread exit\n");
-               g_thread_join ( player->repeat_thread );
-               g_mutex_free ( player->repeat_thread_mutex );
-               g_cond_free ( player->repeat_thread_cond );
-               debug_log("repeat thread released\n");
-       }
-
-       if (MM_ERROR_NONE != _mmplayer_release_video_capture(player))
-       {
-               debug_error("failed to release video capture\n");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       /* withdraw asm */
-       if ( MM_ERROR_NONE != _mmplayer_asm_unregister(&player->sm) )
-       {
-               debug_error("failed to deregister asm server\n");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       /* release pipeline */
-       if ( MM_ERROR_NONE != __mmplayer_gst_destroy_pipeline( player ) )
-       {
-               debug_error("failed to destory pipeline\n");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       /* release attributes */
-       _mmplayer_deconstruct_attribute( handle );
-
-       /* release factories */
-       __mmplayer_release_factories( player );
-
-       /* release lock */
-       if ( player->fsink_lock )
-               g_mutex_free( player->fsink_lock );
-
-       if ( player->msg_cb_lock )
-               g_mutex_free( player->msg_cb_lock );
-
-       if (player->lazy_pause_event_id)
-       {
-               g_source_remove (player->lazy_pause_event_id);
-               player->lazy_pause_event_id = 0;
+       if (data->uri_type == MM_PLAYER_URI_TYPE_NONE) {
+               ret = FALSE;
        }
 
+       /* dump parse result */
+       debug_log("profile parsing result ---\n");
+       debug_warning("incomming uri : %s\n", uri);
+       debug_log("uri : %s\n", data->uri);
+       debug_log("uri_type : %d\n", data->uri_type);
+       debug_log("play_mode : %d\n", data->play_mode);
+       debug_log("mem : 0x%x\n", (guint)data->mem);
+       debug_log("mem_size : %d\n", data->mem_size);
+       debug_log("urgent : %s\n", data->urgent);
+       debug_log("--------------------------\n");
+
        debug_fleave();
 
-       return MM_ERROR_NONE;
+       return ret;
 }
 
-int
-__mmplayer_realize_streaming_ext(mm_player_t* player)
+gboolean _asm_postmsg(gpointer *data)
 {
-       int ret = MM_ERROR_NONE;
+       mm_player_t* player = (mm_player_t*)data;
+       MMMessageParamType msg = {0, };
 
        debug_fenter();
-       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 )
-               {
-                       debug_error ("Unable to create PD Downloader...");
-                       ret = MM_ERROR_PLAYER_NO_FREE_SPACE;
-               }
+       return_val_if_fail ( player, FALSE );
 
-               bret = _mmplayer_realize_pd_downloader((MMHandleType)player, player->profile.uri, player->pd_file_save_path, player->pipeline->mainbin[MMPLAYER_M_SRC].gst);
+       msg.union_type = MM_MSG_UNION_CODE;
+       msg.code = player->sm.event_src;
 
-               if (FALSE == bret)
-               {
-                       debug_error ("Unable to create PD Downloader...");
-                       ret = MM_ERROR_PLAYER_NOT_INITIALIZED;
-               }
-       }
+       MMPLAYER_POST_MSG( player, MM_MESSAGE_READY_TO_RESUME, &msg);
 
-       debug_fleave();
-       return ret;
+       return FALSE;
 }
 
-int
-_mmplayer_realize(MMHandleType hplayer) // @
+gboolean _asm_lazy_pause(gpointer *data)
 {
-       mm_player_t* player =  (mm_player_t*)hplayer;
-       char *uri =NULL;
-       void *param = NULL;
-       int application_pid = -1;
-       gboolean update_registry = FALSE;
-       MMHandleType attrs = 0;
+       mm_player_t* player = (mm_player_t*)data;
        int ret = MM_ERROR_NONE;
 
        debug_fenter();
 
-       /* check player handle */
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED )
-
-       /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_REALIZE );
+       return_val_if_fail ( player, FALSE );
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
+       if (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PLAYING)
        {
-               debug_error("fail to get attributes.\n");
-               return MM_ERROR_PLAYER_INTERNAL;
+               debug_log ("Ready to proceed lazy pause\n");
+               ret = _mmplayer_pause((MMHandleType)player);
+               if(MM_ERROR_NONE != ret)
+               {
+                       debug_error("MMPlayer pause failed in ASM callback lazy pause\n");
+               }
        }
-
-       mm_attrs_get_int_by_name(attrs, "sound_application_pid", &application_pid );
-       player->sm.pid = application_pid;
-
-       mm_attrs_get_string_by_name(attrs, "profile_uri", &uri);
-       mm_attrs_get_data_by_name(attrs, "profile_user_param", &param);
-
-       if (! __mmfplayer_parse_profile((const char*)uri, param, &player->profile) )
+       else
        {
-               debug_error("failed to parse profile\n");
-               return MM_ERROR_PLAYER_INVALID_URI;
+               debug_log ("Invalid state to proceed lazy pause\n");
        }
 
-       /* FIXIT : we can use thouse in player->profile directly */
-       if (player->profile.uri_type == MM_PLAYER_URI_TYPE_MEM)
-       {
-               player->mem_buf.buf = (char *)player->profile.mem;
-               player->mem_buf.len = player->profile.mem_size;
-               player->mem_buf.offset = 0;
-       }
+       /* unset mute */
+       if (player->pipeline && player->pipeline->audiobin)
+               g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst), "mute", 0, NULL);
 
-       if (player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_MMS)
-       {
-               debug_warning("mms protocol is not supported format.\n");
-               return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
-       }
+       player->sm.by_asm_cb = 0; //should be reset here
 
-       if (MMPLAYER_IS_STREAMING(player))
-               MMPLAYER_STATE_CHANGE_TIMEOUT(player) = PLAYER_INI()->live_state_change_timeout;
-       else
-               MMPLAYER_STATE_CHANGE_TIMEOUT(player) = PLAYER_INI()->localplayback_state_change_timeout;
+       debug_fleave();
 
-       player->videodec_linked  = 0;
-       player->videosink_linked = 0;
-       player->audiodec_linked  = 0;
-       player->audiosink_linked = 0;
-       player->textsink_linked = 0;
+       return FALSE;
+}
 
-       /* set the subtitle ON default */
-       player->is_subtitle_off = FALSE;
+ASM_cb_result_t
+__mmplayer_asm_callback(int handle, ASM_event_sources_t event_src, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data)
+{
+       mm_player_t* player = (mm_player_t*) cb_data;
+       ASM_cb_result_t cb_res = ASM_CB_RES_IGNORE;
+       int result = MM_ERROR_NONE;
+       gboolean lazy_pause = FALSE;
 
-       /* registry should be updated for downloadable codec */
-       mm_attrs_get_int_by_name(attrs, "profile_update_registry", &update_registry);
+       debug_fenter();
 
-       if ( update_registry )
-       {
-               debug_log("updating registry...\n");
-               gst_update_registry();
+       return_val_if_fail ( player && player->pipeline, ASM_CB_RES_IGNORE );
+       return_val_if_fail ( player->attrs, MM_ERROR_PLAYER_INTERNAL );
 
-               /* then we have to rebuild factories */
-               __mmplayer_release_factories( player );
-               __mmplayer_init_factories(player);
+       if (player->is_sound_extraction)
+       {
+               debug_log("sound extraction is working...so, asm command is ignored.\n");
+               return result;
        }
 
-       /* realize pipeline */
-       ret = __gst_realize( player );
-       if ( ret != MM_ERROR_NONE )
+       player->sm.by_asm_cb = 1; // it should be enabled for player state transition with called application command
+       player->sm.event_src = event_src;
+
+       if(event_src == ASM_EVENT_SOURCE_EARJACK_UNPLUG )
        {
-               debug_error("fail to realize the player.\n");
+               int stop_by_asm = 0;
+
+               mm_attrs_get_int_by_name(player->attrs, "sound_stop_when_unplugged", &stop_by_asm);
+               if (!stop_by_asm)
+                       return cb_res;
        }
-       else
+       else if (event_src == ASM_EVENT_SOURCE_RESOURCE_CONFLICT)
        {
-               ret = __mmplayer_realize_streaming_ext(player);
+               /* can use video overlay simultaneously */
+               /* video resource conflict */
+               if(player->pipeline->videobin)
+               {
+                       if (PLAYER_INI()->multiple_codec_supported)
+                       {
+                               debug_log("video conflict but, can support to use video overlay simultaneously");
+                               result = _mmplayer_pause((MMHandleType)player);
+                               cb_res = ASM_CB_RES_PAUSE;
+                       }
+                       else
+                       {
+                               debug_log("video conflict, can't support for multiple codec instance");
+                               result = _mmplayer_unrealize((MMHandleType)player);
+                               cb_res = ASM_CB_RES_STOP;
+                       }
+               }
+               return cb_res;
        }
 
-       debug_fleave();
-
-       return ret;
-}
-
-int
-__mmplayer_unrealize_streaming_ext(mm_player_t *player)
-{
-       debug_fenter();
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       /* destroy can called at anytime */
-       if (player->pd_downloader && MMPLAYER_IS_HTTP_PD(player))
+       switch(command)
        {
-               _mmplayer_unrealize_pd_downloader ((MMHandleType)player);
-               player->pd_downloader = NULL;
-       }
+               case ASM_COMMAND_PLAY:
+                       debug_warning ("Got unexpected asm command (%d)", command);
+               break;
 
-       debug_fleave();
-       return MM_ERROR_NONE;
-}
+               case ASM_COMMAND_STOP: // notification case
+               {
+                       debug_warning("Got msg from asm to stop");
 
-int
-_mmplayer_unrealize(MMHandleType hplayer) // @
-{
-       mm_player_t* player = (mm_player_t*)hplayer;
-       int ret = MM_ERROR_NONE;
+                       result = _mmplayer_stop((MMHandleType)player);
+                       if (result != MM_ERROR_NONE)
+                       {
+                               debug_warning("fail to set stop state by asm");
+                               cb_res = ASM_CB_RES_IGNORE;
+                       }
+                       else
+                       {
+                               cb_res = ASM_CB_RES_STOP;
+                       }
+                       player->sm.by_asm_cb = 0; // reset because no message any more from asm
+               }
+               break;
 
-       debug_fenter();
+               case ASM_COMMAND_PAUSE:
+               {
+                       debug_warning("Got msg from asm to Pause");
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED )
+                       if(event_src == ASM_EVENT_SOURCE_CALL_START
+                               || event_src == ASM_EVENT_SOURCE_ALARM_START
+                               || event_src == ASM_EVENT_SOURCE_MEDIA)
+                       {
+                               //hold 0.7 second to excute "fadedown mute" effect
+                               debug_warning ("do fade down->pause->undo fade down");
 
-       /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_UNREALIZE );
+                               __mmplayer_do_sound_fadedown(player, MM_PLAYER_FADEOUT_TIME_DEFAULT);
 
-       __mmplayer_unrealize_streaming_ext(player);
+                               result = _mmplayer_pause((MMHandleType)player);
+                               if (result != MM_ERROR_NONE)
+                               {
+                                       debug_warning("fail to set Pause state by asm");
+                                       cb_res = ASM_CB_RES_IGNORE;
+                                       break;
+                               }
+                               __mmplayer_undo_sound_fadedown(player);
+                       }
+                       else if(event_src == ASM_EVENT_SOURCE_OTHER_PLAYER_APP)
+                       {
+                               lazy_pause = TRUE; // return as soon as possible, for fast start of other app
 
-       /* unrealize pipeline */
-       ret = __gst_unrealize( player );
+                               if ( player->pipeline->audiobin && player->pipeline->audiobin[MMPLAYER_A_SINK].gst )
+                                       g_object_set( player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "mute", 2, NULL);
 
-       /* set player state if success */
-       if ( MM_ERROR_NONE == ret )
-       {
-               if (player->sm.state != ASM_STATE_STOP) {
-                       ret = _mmplayer_asm_set_state(hplayer, ASM_STATE_STOP);
-                       if ( ret )
+                               player->lazy_pause_event_id = g_timeout_add(LAZY_PAUSE_TIMEOUT_MSEC, (GSourceFunc)_asm_lazy_pause, (gpointer)player);
+                               debug_warning ("set lazy pause timer (id=[%d], timeout=[%d ms])", player->lazy_pause_event_id, LAZY_PAUSE_TIMEOUT_MSEC);
+                       }
+                       else
                        {
-                               debug_error("failed to set asm state to STOP\n");
-                               return ret;
+                               //immediate pause
+                               debug_log ("immediate pause");
+                               result = _mmplayer_pause((MMHandleType)player);
                        }
+                       cb_res = ASM_CB_RES_PAUSE;
                }
-       }
+               break;
 
-       debug_fleave();
+               case ASM_COMMAND_RESUME:
+               {
+                       debug_warning("Got msg from asm to Resume. So, application can resume. code (%d) \n", event_src);
+                       player->sm.by_asm_cb = 0;
+                       //ASM server is single thread daemon. So use g_idle_add() to post resume msg
+                       g_idle_add((GSourceFunc)_asm_postmsg, (gpointer)player);
+                       cb_res = ASM_CB_RES_IGNORE;
+               }
+               break;
 
-       return ret;
-}
+               default:
+               break;
+       }
 
-int
-_mmplayer_set_message_callback(MMHandleType hplayer, MMMessageCallback callback, gpointer user_param) // @
-{
-       mm_player_t* player = (mm_player_t*)hplayer;
+       if (!lazy_pause)
+               player->sm.by_asm_cb = 0;
 
-       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       debug_fleave();
 
-       return __gst_set_message_callback(player, callback, user_param);
+       return cb_res;
 }
 
 int
-_mmplayer_get_state(MMHandleType hplayer, int* state) // @
+_mmplayer_create_player(MMHandleType handle) // @
 {
-       mm_player_t *player = (mm_player_t*)hplayer;
-
-       return_val_if_fail(state, MM_ERROR_INVALID_ARGUMENT);
-
-       *state = MMPLAYER_CURRENT_STATE(player);
+       mm_player_t* player = MM_PLAYER_CAST(handle);
 
-       return MM_ERROR_NONE;
-}
+       debug_fenter();
 
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-int
-_mmplayer_set_volume(MMHandleType hplayer, MMPlayerVolumeType volume) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       GstElement* vol_element = NULL;
-       int i = 0;
+       MMTA_ACUM_ITEM_BEGIN("[KPI] media player service create->playing", FALSE);
 
-       debug_fenter();
+       /* initialize player state */
+       MMPLAYER_CURRENT_STATE(player) = MM_PLAYER_STATE_NONE;
+       MMPLAYER_PREV_STATE(player) = MM_PLAYER_STATE_NONE;
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_NONE;
+       MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_NONE;
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL ( player, MMPLAYER_COMMAND_CREATE );
 
-       debug_log("volume [L]=%f:[R]=%f\n",
-               volume.level[MM_VOLUME_CHANNEL_LEFT], volume.level[MM_VOLUME_CHANNEL_RIGHT]);
+       /* construct attributes */
+       player->attrs = _mmplayer_construct_attribute(handle);
 
-       /* invalid factor range or not */
-       for ( i = 0; i < MM_VOLUME_CHANNEL_NUM; i++ )
+       if ( !player->attrs )
        {
-               if (volume.level[i] < MM_VOLUME_FACTOR_MIN || volume.level[i] > MM_VOLUME_FACTOR_MAX) {
-                       debug_error("Invalid factor! (valid factor:0~1.0)\n");
-                       return MM_ERROR_INVALID_ARGUMENT;
-               }
+               debug_critical("Failed to construct attributes\n");
+               goto ERROR;
        }
 
-       /* Save volume to handle. Currently the first array element will be saved. */
-       player->sound.volume = volume.level[0];
+       /* initialize gstreamer with configured parameter */
+       if ( ! __mmplayer_gstreamer_init() )
+       {
+               debug_critical("Initializing gstreamer failed\n");
+               goto ERROR;
+       }
 
-       /* check pipeline handle */
-       if ( ! player->pipeline || ! player->pipeline->audiobin )
+       /* initialize factories if not using decodebin */
+       if ( FALSE == PLAYER_INI()->use_decodebin )
        {
-               debug_log("audiobin is not created yet\n");
-               debug_log("but, current stored volume will be set when it's created.\n");
+               if( player->factories == NULL )
+                   __mmplayer_init_factories(player);
+       }
 
-               /* NOTE : stored volume will be used in create_audiobin
-                * returning MM_ERROR_NONE here makes application to able to
-                * set volume at anytime.
-                */
-               return MM_ERROR_NONE;
+       /* create lock. note that g_tread_init() has already called in gst_init() */
+       player->fsink_lock = g_mutex_new();
+       if ( ! player->fsink_lock )
+       {
+               debug_critical("Cannot create mutex for command lock\n");
+               goto ERROR;
        }
 
-       /* setting volume to volume element */
-       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+       /* create repeat mutex */
+       player->repeat_thread_mutex = g_mutex_new();
+       if ( ! player->repeat_thread_mutex )
+       {
+               debug_critical("Cannot create repeat mutex\n");
+               goto ERROR;
+       }
 
-       if ( vol_element )
+       /* create repeat cond */
+       player->repeat_thread_cond = g_cond_new();
+       if ( ! player->repeat_thread_cond )
        {
-               debug_log("volume is set [%f]\n", player->sound.volume);
-               g_object_set(vol_element, "volume", player->sound.volume, NULL);
+               debug_critical("Cannot create repeat cond\n");
+               goto ERROR;
        }
 
-       debug_fleave();
+       /* create repeat thread */
+       player->repeat_thread =
+               g_thread_create (__mmplayer_repeat_thread, (gpointer)player, TRUE, NULL);
+       if ( ! player->repeat_thread )
+       {
+               goto ERROR;
+       }
 
-       return MM_ERROR_NONE;
-}
+       if ( MM_ERROR_NONE != _mmplayer_initialize_video_capture(player))
+       {
+               debug_error("failed to initialize video capture\n");
+               goto ERROR;
+       }
 
+       /* register to asm */
+       if ( MM_ERROR_NONE != _mmplayer_asm_register(&player->sm, (ASM_sound_cb_t)__mmplayer_asm_callback, (void*)player) )
+       {
+               /* NOTE : we are dealing it as an error since we cannot expect it's behavior */
+               debug_error("failed to register asm server\n");
+               return MM_ERROR_POLICY_INTERNAL;
+       }
 
-int
-_mmplayer_get_volume(MMHandleType hplayer, MMPlayerVolumeType* volume)
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       int i = 0;
+       if (MMPLAYER_IS_HTTP_PD(player))
+       {
+               player->pd_downloader = NULL;
+               player->pd_file_save_path = NULL;
+       }
 
-       debug_fenter();
+       /* give default value of audio effect setting */
+       player->bypass_audio_effect = TRUE;
+       player->sound.volume = MM_VOLUME_FACTOR_DEFAULT;
+       player->playback_rate = DEFAULT_PLAYBACK_RATE;
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail( volume, MM_ERROR_INVALID_ARGUMENT );
+       player->play_subtitle = FALSE;
+       player->use_textoverlay = FALSE;
 
-       /* returning stored volume */
-       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++)
-               volume->level[i] = player->sound.volume;
+       /* set player state to null */
+       MMPLAYER_STATE_CHANGE_TIMEOUT(player) = PLAYER_INI()->localplayback_state_change_timeout;
+       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_NULL );
 
        debug_fleave();
 
        return MM_ERROR_NONE;
-}
-
-
 
-int
-_mmplayer_set_mute(MMHandleType hplayer, int mute) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       GstElement* vol_element = NULL;
-
-       debug_fenter();
+ERROR:
+       /* free lock */
+       if ( player->fsink_lock )
+               g_mutex_free( player->fsink_lock );
+       player->fsink_lock = NULL;
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       /* free thread */
+       if ( player->repeat_thread_cond &&
+                player->repeat_thread_mutex &&
+                player->repeat_thread )
+       {
+               player->repeat_thread_exit = TRUE;
+               g_cond_signal( player->repeat_thread_cond );
 
-       debug_log("mute : %d\n", mute);
+               g_thread_join( player->repeat_thread );
+               player->repeat_thread = NULL;
 
-       /* mute value shoud 0 or 1 */
-       if ( mute != 0 && mute != 1 )
-       {
-               debug_error("bad mute value\n");
+               g_mutex_free ( player->repeat_thread_mutex );
+               player->repeat_thread_mutex = NULL;
 
-               /* FIXIT : definitly, we need _BAD_PARAM error code */
-               return MM_ERROR_INVALID_ARGUMENT;
+               g_cond_free ( player->repeat_thread_cond );
+               player->repeat_thread_cond = NULL;
        }
+       /* clear repeat thread mutex/cond if still alive
+        * this can happen if only thread creating has failed
+        */
+       if ( player->repeat_thread_mutex )
+               g_mutex_free ( player->repeat_thread_mutex );
+
+       if ( player->repeat_thread_cond )
+               g_cond_free ( player->repeat_thread_cond );
 
+       /* release attributes */
+       _mmplayer_deconstruct_attribute(handle);
 
-       /* just hold mute value if pipeline is not ready */
-       if ( !player->pipeline || !player->pipeline->audiobin )
-       {
-               debug_log("pipeline is not ready. holding mute value\n");
-               player->sound.mute = mute;
-               return MM_ERROR_NONE;
-       }
+       return MM_ERROR_PLAYER_INTERNAL;
+}
 
+static gboolean
+__mmplayer_gstreamer_init(void) // @
+{
+       static gboolean initialized = FALSE;
+       static const int max_argc = 50;
+       gint* argc = NULL;
+       gchar** argv = NULL;
+       GError *err = NULL;
+       int i = 0;
 
-       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+       debug_fenter();
 
-       /* NOTE : volume will only created when the bt is enabled */
-       if ( vol_element )
-       {
-               g_object_set(vol_element, "mute", mute, NULL);
-       }
-       else
+       if ( initialized )
        {
-               debug_log("volume elemnet is not created. using volume in audiosink\n");
+               debug_log("gstreamer already initialized.\n");
+               return TRUE;
        }
 
-       player->sound.mute = mute;
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-}
+       /* alloc */
+       argc = malloc( sizeof(int) );
+       argv = malloc( sizeof(gchar*) * max_argc );
 
-int
-_mmplayer_get_mute(MMHandleType hplayer, int* pmute) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       GstElement* vol_element = NULL;
+       if ( !argc || !argv )
+               goto ERROR;
 
-       debug_fenter();
+       memset( argv, 0, sizeof(gchar*) * max_argc );
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( pmute, MM_ERROR_INVALID_ARGUMENT );
+       /* add initial */
+       *argc = 1;
+       argv[0] = g_strdup( "mmplayer" );
 
-       /* just hold mute value if pipeline is not ready */
-       if ( !player->pipeline || !player->pipeline->audiobin )
+       /* add gst_param */
+       for ( i = 0; i < 5; i++ ) /* FIXIT : num of param is now fixed to 5. make it dynamic */
        {
-               debug_log("pipeline is not ready. returning stored value\n");
-               *pmute = player->sound.mute;
-               return MM_ERROR_NONE;
+               if ( strlen( PLAYER_INI()->gst_param[i] ) > 0 )
+               {
+                       argv[*argc] = g_strdup( PLAYER_INI()->gst_param[i] );
+                       (*argc)++;
+               }
        }
 
+       /* we would not do fork for scanning plugins */
+       argv[*argc] = g_strdup("--gst-disable-registry-fork");
+       (*argc)++;
 
-       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
-
-       if ( vol_element )
+       /* check disable registry scan */
+       if ( PLAYER_INI()->skip_rescan )
        {
-               g_object_get(vol_element, "mute", pmute, NULL);
-               debug_log("mute=%d\n\n", *pmute);
+               argv[*argc] = g_strdup("--gst-disable-registry-update");
+               (*argc)++;
        }
-       else
+
+       /* check disable segtrap */
+       if ( PLAYER_INI()->disable_segtrap )
        {
-               *pmute = player->sound.mute;
+               argv[*argc] = g_strdup("--gst-disable-segtrap");
+               (*argc)++;
        }
 
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-int
-_mmplayer_set_videostream_cb(MMHandleType hplayer, mm_player_video_stream_callback callback, void *user_param) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-
-       debug_fenter();
+       debug_log("initializing gstreamer with following parameter\n");
+       debug_log("argc : %d\n", *argc);
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( callback, MM_ERROR_INVALID_ARGUMENT );
+       for ( i = 0; i < *argc; i++ )
+       {
+               debug_log("argv[%d] : %s\n", i, argv[i]);
+       }
 
-       player->video_stream_cb = callback;
-       player->video_stream_cb_user_param = user_param;
-       player->use_video_stream = TRUE;
-       debug_log("Stream cb Handle value is %p : %p\n", player, player->video_stream_cb);
 
-       debug_fleave();
+       /* initializing gstreamer */
+       __ta__("gst_init time",
 
-       return MM_ERROR_NONE;
-}
+               if ( ! gst_init_check (argc, &argv, &err))
+               {
+                       debug_error("Could not initialize GStreamer: %s\n", err ? err->message : "unknown error occurred");
+                       if (err)
+                       {
+                               g_error_free (err);
+                       }
 
-int
-_mmplayer_set_audiostream_cb(MMHandleType hplayer, mm_player_audio_stream_callback callback, void *user_param) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
+                       goto ERROR;
+               }
+       );
 
-       debug_fenter();
+       /* release */
+       for ( i = 0; i < *argc; i++ )
+       {
+               MMPLAYER_FREEIF( argv[i] );
+       }
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+       MMPLAYER_FREEIF( argv );
+       MMPLAYER_FREEIF( argc );
 
-       player->audio_stream_cb = callback;
-       player->audio_stream_cb_user_param = user_param;
-       debug_log("Audio Stream cb Handle value is %p : %p\n", player, player->audio_stream_cb);
+       /* done */
+       initialized = TRUE;
 
        debug_fleave();
 
-       return MM_ERROR_NONE;
-}
-
-int
-_mmplayer_set_audiobuffer_cb(MMHandleType hplayer, mm_player_audio_stream_callback callback, void *user_param) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-
-       debug_fenter();
-
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+       return TRUE;
 
-       player->audio_buffer_cb = callback;
-       player->audio_buffer_cb_user_param = user_param;
-       debug_log("Audio Stream cb Handle value is %p : %p\n", player, player->audio_buffer_cb);
+ERROR:
 
-       debug_fleave();
+       MMPLAYER_FREEIF( argv );
+       MMPLAYER_FREEIF( argc );
 
-       return MM_ERROR_NONE;
+       return FALSE;
 }
 
 int
-_mmplayer_set_buffer_need_data_cb(MMHandleType hplayer, mm_player_buffer_need_data_callback callback, void *user_param) // @
+__mmplayer_destroy_streaming_ext(mm_player_t* player)
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
-
-       debug_fenter();
-
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
-
-       player->need_data_cb = callback;
-       player->buffer_cb_user_param = user_param;
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       debug_log("buffer need dataHandle value is %p : %p\n", player, player->need_data_cb);
+       if (player->pd_downloader)
+               _mmplayer_unrealize_pd_downloader((MMHandleType)player);
 
-       debug_fleave();
+       if (MMPLAYER_IS_HTTP_PD(player))
+               _mmplayer_destroy_pd_downloader((MMHandleType)player);
 
+       if (MMPLAYER_IS_STREAMING(player))
+       {
+               if (player->streamer)
+               {
+                       __mm_player_streaming_deinitialize (player->streamer);
+                       __mm_player_streaming_destroy(player->streamer);
+                       player->streamer = NULL;
+               }
+       }
        return MM_ERROR_NONE;
 }
 
 int
-_mmplayer_set_buffer_enough_data_cb(MMHandleType hplayer, mm_player_buffer_enough_data_callback callback, void *user_param) // @
+_mmplayer_destroy(MMHandleType handle) // @
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
+       mm_player_t* player = MM_PLAYER_CAST(handle);
 
        debug_fenter();
 
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
-
-       player->enough_data_cb = callback;
-       player->buffer_cb_user_param = user_param;
-
-       debug_log("buffer enough data cb Handle value is %p : %p\n", player, player->enough_data_cb);
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-}
+       /* check player handle */
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-int
-_mmplayer_set_buffer_seek_data_cb(MMHandleType hplayer, mm_player_buffer_seek_data_callback callback, void *user_param) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
+       /* destroy can called at anytime */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL ( player, MMPLAYER_COMMAND_DESTROY );
 
-       debug_fenter();
+       __mmplayer_destroy_streaming_ext(player);
 
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+       /* release repeat thread */
+       if ( player->repeat_thread_cond &&
+                player->repeat_thread_mutex &&
+                player->repeat_thread )
+       {
+               player->repeat_thread_exit = TRUE;
+               g_cond_signal( player->repeat_thread_cond );
 
-       player->seek_data_cb = callback;
-       player->buffer_cb_user_param = user_param;
+               debug_log("waitting for repeat thread exit\n");
+               g_thread_join ( player->repeat_thread );
+               g_mutex_free ( player->repeat_thread_mutex );
+               g_cond_free ( player->repeat_thread_cond );
+               debug_log("repeat thread released\n");
+       }
 
-       debug_log("buffer seek data cb Handle value is %p : %p\n", player, player->seek_data_cb);
+       if (MM_ERROR_NONE != _mmplayer_release_video_capture(player))
+       {
+               debug_error("failed to release video capture\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-       debug_fleave();
+       /* withdraw asm */
+       if ( MM_ERROR_NONE != _mmplayer_asm_unregister(&player->sm) )
+       {
+               debug_error("failed to deregister asm server\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-       return MM_ERROR_NONE;
-}
+       /* release pipeline */
+       if ( MM_ERROR_NONE != __mmplayer_gst_destroy_pipeline( player ) )
+       {
+               debug_error("failed to destory pipeline\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-int
-_mmplayer_set_videoframe_render_error_cb(MMHandleType hplayer, mm_player_video_frame_render_error_callback callback, void *user_param) // @
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
+       /* release attributes */
+       _mmplayer_deconstruct_attribute( handle );
 
-       debug_fenter();
+       /* release factories */
+       __mmplayer_release_factories( player );
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( callback, MM_ERROR_INVALID_ARGUMENT );
+       /* release lock */
+       if ( player->fsink_lock )
+               g_mutex_free( player->fsink_lock );
 
-       player->video_frame_render_error_cb = callback;
-       player->video_frame_render_error_cb_user_param = user_param;
+       if ( player->msg_cb_lock )
+               g_mutex_free( player->msg_cb_lock );
 
-       debug_log("Video frame render error cb Handle value is %p : %p\n", player, player->video_frame_render_error_cb);
+       if (player->lazy_pause_event_id)
+       {
+               g_source_remove (player->lazy_pause_event_id);
+               player->lazy_pause_event_id = 0;
+       }
 
        debug_fleave();
 
@@ -7341,35 +2801,30 @@ _mmplayer_set_videoframe_render_error_cb(MMHandleType hplayer, mm_player_video_f
 }
 
 int
-__mmplayer_start_streaming_ext(mm_player_t *player)
+__mmplayer_realize_streaming_ext(mm_player_t* player)
 {
-       gint ret = MM_ERROR_NONE;
+       int ret = MM_ERROR_NONE;
 
        debug_fenter();
        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 )
                {
-                       ret = __mmplayer_realize_streaming_ext(player);
-
-                       if ( ret != MM_ERROR_NONE)
-                       {
-                               debug_error ("failed to realize streaming ext\n");
-                               return ret;
-                       }
+                       debug_error ("Unable to create PD Downloader...");
+                       ret = MM_ERROR_PLAYER_NO_FREE_SPACE;
                }
 
-               if (player->pd_downloader && player->pd_mode == MM_PLAYER_PD_MODE_URI)
+               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)
                {
-                       ret = _mmplayer_start_pd_downloader ((MMHandleType)player);
-                       if ( !ret )
-                       {
-                               debug_error ("ERROR while starting PD...\n");
-                               return MM_ERROR_PLAYER_NOT_INITIALIZED;
-                       }
-                       ret = MM_ERROR_NONE;
+                       debug_error ("Unable to create PD Downloader...");
+                       ret = MM_ERROR_PLAYER_NOT_INITIALIZED;
                }
        }
 
@@ -7378,176 +2833,146 @@ __mmplayer_start_streaming_ext(mm_player_t *player)
 }
 
 int
-_mmplayer_start(MMHandleType hplayer) // @
+_mmplayer_realize(MMHandleType hplayer) // @
 {
-       mm_player_t* player = (mm_player_t*) hplayer;
-       gint ret = MM_ERROR_NONE;
+       mm_player_t* player =  (mm_player_t*)hplayer;
+       char *uri =NULL;
+       void *param = NULL;
+       int application_pid = -1;
+       gboolean update_registry = FALSE;
+       MMHandleType attrs = 0;
+       int ret = MM_ERROR_NONE;
 
        debug_fenter();
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       /* check player handle */
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED )
 
        /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_START );
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_REALIZE );
 
-       ret = _mmplayer_asm_set_state(hplayer, ASM_STATE_PLAYING);
-       if ( ret != MM_ERROR_NONE )
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
        {
-               debug_error("failed to set asm state to PLAYING\n");
-               return ret;
+               debug_error("fail to get attributes.\n");
+               return MM_ERROR_PLAYER_INTERNAL;
        }
 
-       /* NOTE : we should check and create pipeline again if not created as we destroy
-        * whole pipeline when stopping in streamming playback
-        */
-       if ( ! player->pipeline )
+       mm_attrs_get_int_by_name(attrs, "sound_application_pid", &application_pid );
+       player->sm.pid = application_pid;
+
+       mm_attrs_get_string_by_name(attrs, "profile_uri", &uri);
+       mm_attrs_get_data_by_name(attrs, "profile_user_param", &param);
+
+       if (! __mmfplayer_parse_profile((const char*)uri, param, &player->profile) )
        {
-               ret = __gst_realize( player );
-               if ( MM_ERROR_NONE != ret )
-               {
-                       debug_error("failed to realize before starting. only in streamming\n");
-                       return ret;
-               }
+               debug_error("failed to parse profile\n");
+               return MM_ERROR_PLAYER_INVALID_URI;
        }
 
-       ret = __mmplayer_start_streaming_ext(player);
-       if ( ret != MM_ERROR_NONE )
+       /* FIXIT : we can use thouse in player->profile directly */
+       if (player->profile.uri_type == MM_PLAYER_URI_TYPE_MEM)
        {
-               debug_error("failed to start streaming ext \n");
+               player->mem_buf.buf = (char *)player->profile.mem;
+               player->mem_buf.len = player->profile.mem_size;
+               player->mem_buf.offset = 0;
        }
 
-       /* start pipeline */
-       ret = __gst_start( player );
-       if ( ret != MM_ERROR_NONE )
+       if (player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_MMS)
        {
-               debug_error("failed to start player.\n");
+               debug_warning("mms protocol is not supported format.\n");
+               return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
        }
 
-       debug_fleave();
-
-       return ret;
-}
-
-/* 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().
- * 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)
-{
-       MMMessageParamType msg_param;
-       memset (&msg_param, 0, sizeof(MMMessageParamType));
-       gboolean post_msg_direct = FALSE;
+       if (MMPLAYER_IS_STREAMING(player))
+               MMPLAYER_STATE_CHANGE_TIMEOUT(player) = PLAYER_INI()->live_state_change_timeout;
+       else
+               MMPLAYER_STATE_CHANGE_TIMEOUT(player) = PLAYER_INI()->localplayback_state_change_timeout;
 
-       debug_fenter();
+       player->videodec_linked  = 0;
+       player->videosink_linked = 0;
+       player->audiodec_linked  = 0;
+       player->audiosink_linked = 0;
+       player->textsink_linked = 0;
 
-       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       /* set the subtitle ON default */
+       player->is_subtitle_off = FALSE;
 
-       debug_log("not_supported_codec = 0x%02x, can_support_codec = 0x%02x\n",
-                       player->not_supported_codec, player->can_support_codec);
+       /* registry should be updated for downloadable codec */
+       mm_attrs_get_int_by_name(attrs, "profile_update_registry", &update_registry);
 
-       if( player->not_found_demuxer )
+       if ( update_registry )
        {
-               msg_param.code = MM_ERROR_PLAYER_CODEC_NOT_FOUND;
-               msg_param.data = g_strdup_printf("%s", player->unlinked_demuxer_mime);
-
-               MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
-               MMPLAYER_FREEIF(msg_param.data);
+               debug_log("updating registry...\n");
+               gst_update_registry();
 
-               return MM_ERROR_NONE;
+               /* then we have to rebuild factories */
+               __mmplayer_release_factories( player );
+               __mmplayer_init_factories(player);
        }
 
-       if (player->not_supported_codec)
+       /* realize pipeline */
+       ret = __gst_realize( player );
+       if ( ret != MM_ERROR_NONE )
        {
-               if ( player->can_support_codec ) // There is one codec to play
-               {
-                       post_msg_direct = TRUE;
-               }
-               else
-               {
-                       if ( player->pipeline->audiobin ) // Some content has only PCM data in container.
-                               post_msg_direct = TRUE;
-               }
-
-               if ( post_msg_direct )
-               {
-                       MMMessageParamType msg_param;
-                       memset (&msg_param, 0, sizeof(MMMessageParamType));
-
-                       if ( player->not_supported_codec ==  MISSING_PLUGIN_AUDIO )
-                       {
-                               debug_warning("not found AUDIO codec, posting error code to application.\n");
-
-                               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 )
-                       {
-                               debug_warning("not found VIDEO codec, posting error code to application.\n");
-
-                               msg_param.code = MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
-                               msg_param.data = g_strdup_printf("%s", player->unlinked_video_mime);
-                       }
-
-                       MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
-
-                       MMPLAYER_FREEIF(msg_param.data);
+               debug_error("fail to realize the player.\n");
+       }
+       else
+       {
+               ret = __mmplayer_realize_streaming_ext(player);
+       }
 
-                       return MM_ERROR_NONE;
-               }
-               else // no any supported codec case
-               {
-                       debug_warning("not found any codec, posting error code to application.\n");
+       debug_fleave();
 
-                       if ( player->not_supported_codec ==  MISSING_PLUGIN_AUDIO )
-                       {
-                               msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
-                               msg_param.data = g_strdup_printf("%s", player->unlinked_audio_mime);
-                       }
-                       else
-                       {
-                               msg_param.code = MM_ERROR_PLAYER_CODEC_NOT_FOUND;
-                               msg_param.data = g_strdup_printf("%s, %s", player->unlinked_video_mime, player->unlinked_audio_mime);
-                       }
+       return ret;
+}
 
-                       MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+int
+__mmplayer_unrealize_streaming_ext(mm_player_t *player)
+{
+       debug_fenter();
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-                       MMPLAYER_FREEIF(msg_param.data);
-               }
+       /* destroy can called at anytime */
+       if (player->pd_downloader && MMPLAYER_IS_HTTP_PD(player))
+       {
+               _mmplayer_unrealize_pd_downloader ((MMHandleType)player);
+               player->pd_downloader = NULL;
        }
 
        debug_fleave();
-
        return MM_ERROR_NONE;
 }
 
-/* NOTE : it should be able to call 'stop' anytime*/
 int
-_mmplayer_stop(MMHandleType hplayer) // @
+_mmplayer_unrealize(MMHandleType hplayer) // @
 {
        mm_player_t* player = (mm_player_t*)hplayer;
        int ret = MM_ERROR_NONE;
 
        debug_fenter();
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED )
 
        /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_STOP );
-
-       /* NOTE : application should not wait for EOS after calling STOP */
-       __mmplayer_cancel_delayed_eos( player );
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_UNREALIZE );
 
        __mmplayer_unrealize_streaming_ext(player);
 
-       /* stop pipeline */
-       ret = __gst_stop( player );
+       /* unrealize pipeline */
+       ret = __gst_unrealize( player );
 
-       if ( ret != MM_ERROR_NONE )
+       /* set player state if success */
+       if ( MM_ERROR_NONE == ret )
        {
-               debug_error("failed to stop player.\n");
+               if (player->sm.state != ASM_STATE_STOP) {
+                       ret = _mmplayer_asm_set_state(hplayer, ASM_STATE_STOP);
+                       if ( ret )
+                       {
+                               debug_error("failed to set asm state to STOP\n");
+                               return ret;
+                       }
+               }
        }
 
        debug_fleave();
@@ -7556,241 +2981,148 @@ _mmplayer_stop(MMHandleType hplayer) // @
 }
 
 int
-_mmplayer_pause(MMHandleType hplayer) // @
+_mmplayer_set_message_callback(MMHandleType hplayer, MMMessageCallback callback, gpointer user_param) // @
 {
        mm_player_t* player = (mm_player_t*)hplayer;
-#ifndef GST_API_VERSION_1
-       GstFormat fmt = GST_FORMAT_TIME;
-#endif
-       gint64 pos_msec = 0;
-       gboolean async = FALSE;
-       gint ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-
-       /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_PAUSE );
-
-       switch (MMPLAYER_CURRENT_STATE(player))
-       {
-               case MM_PLAYER_STATE_READY:
-               {
-                       /* check prepare async or not.
-                        * In the case of streaming playback, it's recommned to avoid blocking wait.
-                        */
-                       mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
-                       debug_log("prepare mode : %s", (async ? "async" : "sync"));
-               }
-               break;
 
-               case MM_PLAYER_STATE_PLAYING:
-               {
-                       /* NOTE : store current point to overcome some bad operation
-                       * ( returning zero when getting current position in paused state) of some
-                       * elements
-                       */
-#ifdef GST_API_VERSION_1
-                       ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_msec);
-#else
-                       ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &pos_msec);
-#endif
-                       if ( ! ret )
-                       debug_warning("getting current position failed in paused\n");
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
 
-                       player->last_position = pos_msec;
-               }
-               break;
-       }
+       return __gst_set_message_callback(player, callback, user_param);
+}
 
-       /* pause pipeline */
-       ret = __gst_pause( player, async );
+int
+_mmplayer_get_state(MMHandleType hplayer, int* state) // @
+{
+       mm_player_t *player = (mm_player_t*)hplayer;
 
-       if ( ret != MM_ERROR_NONE )
-       {
-               debug_error("failed to pause player. ret : 0x%x\n", ret);
-       }
+       return_val_if_fail(state, MM_ERROR_INVALID_ARGUMENT);
 
-       debug_fleave();
+       *state = MMPLAYER_CURRENT_STATE(player);
 
-       return ret;
+       return MM_ERROR_NONE;
 }
 
+
 int
-_mmplayer_resume(MMHandleType hplayer)
+_mmplayer_set_volume(MMHandleType hplayer, MMPlayerVolumeType volume) // @
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
-       int ret = MM_ERROR_NONE;
-       gboolean async = FALSE;
+       mm_player_t* player = (mm_player_t*) hplayer;
+       GstElement* vol_element = NULL;
+       int i = 0;
 
        debug_fenter();
 
        return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       ret = _mmplayer_asm_set_state(hplayer, ASM_STATE_PLAYING);
-       if ( ret )
+       debug_log("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++ )
        {
-               debug_error("failed to set asm state to PLAYING\n");
-               return ret;
+               if (volume.level[i] < MM_VOLUME_FACTOR_MIN || volume.level[i] > MM_VOLUME_FACTOR_MAX) {
+                       debug_error("Invalid factor! (valid factor:0~1.0)\n");
+                       return MM_ERROR_INVALID_ARGUMENT;
+               }
        }
 
-       /* check current state */
-       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_RESUME );
+       /* Save volume to handle. Currently the first array element will be saved. */
+       player->sound.volume = volume.level[0];
+
+       /* check pipeline handle */
+       if ( ! player->pipeline || ! player->pipeline->audiobin )
+       {
+               debug_log("audiobin is not created yet\n");
+               debug_log("but, current stored volume will be set when it's created.\n");
+
+               /* NOTE : stored volume will be used in create_audiobin
+                * returning MM_ERROR_NONE here makes application to able to
+                * set volume at anytime.
+                */
+               return MM_ERROR_NONE;
+       }
 
-       /* resume pipeline */
-       ret = __gst_resume( player, FALSE );
+       /* setting volume to volume element */
+       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
 
-       if ( ret != MM_ERROR_NONE )
+       if ( vol_element )
        {
-               debug_error("failed to resume player.\n");
+               debug_log("volume is set [%f]\n", player->sound.volume);
+               g_object_set(vol_element, "volume", player->sound.volume, NULL);
        }
 
-
        debug_fleave();
 
-       return ret;
+       return MM_ERROR_NONE;
 }
 
+
 int
-__mmplayer_set_play_count(mm_player_t* player, gint count)
+_mmplayer_get_volume(MMHandleType hplayer, MMPlayerVolumeType* volume)
 {
-       MMHandleType attrs = 0;
+       mm_player_t* player = (mm_player_t*) hplayer;
+       int i = 0;
 
        debug_fenter();
 
        return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail( volume, MM_ERROR_INVALID_ARGUMENT );
 
-       attrs =  MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
-       {
-               debug_error("fail to get attributes.\n");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-
-       mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
-       if ( mmf_attrs_commit ( attrs ) ) /* return -1 if error */
-               debug_error("failed to commit\n");
+       /* returning stored volume */
+       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; i++)
+               volume->level[i] = player->sound.volume;
 
        debug_fleave();
 
-       return  MM_ERROR_NONE;
+       return MM_ERROR_NONE;
 }
 
+
+
 int
-_mmplayer_activate_section_repeat(MMHandleType hplayer, unsigned long start, unsigned long end)
+_mmplayer_set_mute(MMHandleType hplayer, int mute) // @
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
-       gint64 start_pos = 0;
-       gint64 end_pos = 0;
-       gint infinity = -1;
+       mm_player_t* player = (mm_player_t*) hplayer;
+       GstElement* vol_element = NULL;
 
        debug_fenter();
 
        return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( end <= GST_TIME_AS_MSECONDS(player->duration), MM_ERROR_INVALID_ARGUMENT );
-
-       player->section_repeat = TRUE;
-       player->section_repeat_start = start;
-       player->section_repeat_end = end;
-
-       start_pos = player->section_repeat_start * G_GINT64_CONSTANT(1000000);
-       end_pos = player->section_repeat_end * G_GINT64_CONSTANT(1000000);
 
-       __mmplayer_set_play_count( player, infinity );
+       debug_log("mute : %d\n", mute);
 
-       if ( (!__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_pos,
-                                       GST_SEEK_TYPE_SET, end_pos)))
+       /* mute value shoud 0 or 1 */
+       if ( mute != 0 && mute != 1 )
        {
-               debug_error("failed to activate section repeat\n");
+               debug_error("bad mute value\n");
 
-               return MM_ERROR_PLAYER_SEEK;
+               /* FIXIT : definitly, we need _BAD_PARAM error code */
+               return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       debug_log("succeeded to set section repeat from %d to %d\n",
-               player->section_repeat_start, player->section_repeat_end);
-
-       debug_fleave();
-
-       return  MM_ERROR_NONE;
-}
-
-static int
-__mmplayer_set_pcm_extraction(mm_player_t* player)
-{
-       guint64 start_nsec = 0;
-       guint64 end_nsec = 0;
-       guint64 dur_nsec = 0;
-       guint64 dur_msec = 0;
-#ifndef GST_API_VERSION_1
-       GstFormat fmt = GST_FORMAT_TIME;
-#endif
-       int required_start = 0;
-       int required_end = 0;
-       int ret = 0;
-
-       debug_fenter();
-
-       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);
-
-       debug_log("pcm extraction required position is from [%d] to [%d] (msec)\n", required_start, required_end);
 
-       if (required_start == 0 && required_end == 0)
+       /* just hold mute value if pipeline is not ready */
+       if ( !player->pipeline || !player->pipeline->audiobin )
        {
-               debug_log("extracting entire stream");
+               debug_log("pipeline is not ready. holding mute value\n");
+               player->sound.mute = mute;
                return MM_ERROR_NONE;
        }
-       else if (required_start < 0 || required_start > required_end || required_end < 0 )
-       {
-               debug_log("invalid range for pcm extraction");
-               return MM_ERROR_INVALID_ARGUMENT;
-       }
 
-       /* get duration */
-#ifdef GST_API_VERSION_1
-       ret = gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &dur_nsec);
-#else
-       ret = gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &dur_nsec);
-#endif
-       if ( !ret )
-       {
-               debug_error("failed to get duration");
-               return MM_ERROR_PLAYER_INTERNAL;
-       }
-       dur_msec = GST_TIME_AS_MSECONDS(dur_nsec);
 
-       if (dur_msec < required_end) // FIXME
+       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
+
+       /* NOTE : volume will only created when the bt is enabled */
+       if ( vol_element )
        {
-               debug_log("invalid end pos for pcm extraction");
-               return MM_ERROR_INVALID_ARGUMENT;
+               g_object_set(vol_element, "mute", mute, NULL);
        }
-
-       start_nsec = required_start * G_GINT64_CONSTANT(1000000);
-       end_nsec = required_end * G_GINT64_CONSTANT(1000000);
-
-       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)))
+       else
        {
-               debug_error("failed to seek for pcm extraction\n");
-
-               return MM_ERROR_PLAYER_SEEK;
+               debug_log("volume elemnet is not created. using volume in audiosink\n");
        }
 
-       debug_log("succeeded to set up segment extraction from [%llu] to [%llu] (nsec)\n", start_nsec, end_nsec);
+       player->sound.mute = mute;
 
        debug_fleave();
 
@@ -7798,2558 +3130,2382 @@ __mmplayer_set_pcm_extraction(mm_player_t* player)
 }
 
 int
-_mmplayer_deactivate_section_repeat(MMHandleType hplayer)
+_mmplayer_get_mute(MMHandleType hplayer, int* pmute) // @
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
-       gint64 cur_pos = 0;
-#ifndef GST_API_VERSION_1
-       GstFormat fmt  = GST_FORMAT_TIME;
-#endif
-       gint onetime = 1;
+       mm_player_t* player = (mm_player_t*) hplayer;
+       GstElement* vol_element = NULL;
 
        debug_fenter();
 
        return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( pmute, MM_ERROR_INVALID_ARGUMENT );
 
-       player->section_repeat = FALSE;
-
-       __mmplayer_set_play_count( player, onetime );
-#ifdef GST_API_VERSION_1
-       gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &cur_pos);
-#else
-       gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &cur_pos);
-#endif
-
-       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, cur_pos,
-                                       GST_SEEK_TYPE_SET, player->duration )))
-       {
-               debug_error("failed to deactivate section repeat\n");
-
-               return MM_ERROR_PLAYER_SEEK;
-       }
-
-       debug_fenter();
-
-       return MM_ERROR_NONE;
-}
-
-int
-_mmplayer_set_playspeed(MMHandleType hplayer, gdouble rate)
-{
-       mm_player_t* player = (mm_player_t*)hplayer;
-       signed long long pos_msec = 0;
-       int ret = MM_ERROR_NONE;
-       int mute = FALSE;
-#ifndef GST_API_VERSION_1
-       GstFormat format =GST_FORMAT_TIME;
-#endif
-       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
-       debug_fenter();
-
-       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( !MMPLAYER_IS_STREAMING(player), MM_ERROR_NOT_SUPPORT_API );
-
-       /* 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)
+       /* just hold mute value if pipeline is not ready */
+       if ( !player->pipeline || !player->pipeline->audiobin )
        {
-               if (player->can_support_codec & FOUND_PLUGIN_VIDEO)
-                       mute = TRUE;
-       }
-       _mmplayer_set_mute(hplayer, mute);
-
-       if (player->playback_rate == rate)
+               debug_log("pipeline is not ready. returning stored value\n");
+               *pmute = player->sound.mute;
                return MM_ERROR_NONE;
+       }
 
-       /* 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);
-#ifdef GST_API_VERSION_1
-       if ( current_state != MM_PLAYER_STATE_PAUSED )
-               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_msec);
-#else
-       if ( current_state != MM_PLAYER_STATE_PAUSED )
-               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &format, &pos_msec);
-#endif
 
-       debug_log ("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS (pos_msec), ret, current_state);
+       vol_element = player->pipeline->audiobin[MMPLAYER_A_VOL].gst;
 
-       if ( ( current_state == MM_PLAYER_STATE_PAUSED )
-               || ( ! ret ))
-               //|| ( player->last_position != 0 && pos_msec == 0 ) )
+       if ( vol_element )
        {
-               debug_warning("returning last point : %lld\n", player->last_position );
-               pos_msec = player->last_position;
+               g_object_get(vol_element, "mute", pmute, NULL);
+               debug_log("mute=%d\n\n", *pmute);
        }
-
-       if ((!gst_element_seek (player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
-                               rate,
-                               GST_FORMAT_TIME,
-                               ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
-                               //( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_KEY_UNIT),
-                               GST_SEEK_TYPE_SET, pos_msec,
-                               //GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE,
-                GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)))
+       else
        {
-               debug_error("failed to set speed playback\n");
-               return MM_ERROR_PLAYER_SEEK;
+               *pmute = player->sound.mute;
        }
 
-       debug_log("succeeded to set speed playback as %fl\n", rate);
-
        debug_fleave();
 
-       return MM_ERROR_NONE;;
+       return MM_ERROR_NONE;
 }
 
 int
-_mmplayer_set_position(MMHandleType hplayer, int format, int position) // @
+_mmplayer_set_videostream_cb(MMHandleType hplayer, mm_player_video_stream_callback callback, void *user_param) // @
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
-       int ret = MM_ERROR_NONE;
+       mm_player_t* player = (mm_player_t*) hplayer;
 
        debug_fenter();
 
        return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( callback, MM_ERROR_INVALID_ARGUMENT );
 
-       ret = __gst_set_position ( player, format, (unsigned long)position, FALSE );
+       player->video_stream_cb = callback;
+       player->video_stream_cb_user_param = user_param;
+       player->use_video_stream = TRUE;
+       debug_log("Stream cb Handle value is %p : %p\n", player, player->video_stream_cb);
 
        debug_fleave();
 
-       return ret;
+       return MM_ERROR_NONE;
 }
 
 int
-_mmplayer_get_position(MMHandleType hplayer, int format, unsigned long *position) // @
+_mmplayer_set_audiostream_cb(MMHandleType hplayer, mm_player_audio_stream_callback callback, void *user_param) // @
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
-       int ret = MM_ERROR_NONE;
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
 
        return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
 
-       ret = __gst_get_position ( player, format, position );
+       player->audio_stream_cb = callback;
+       player->audio_stream_cb_user_param = user_param;
+       debug_log("Audio Stream cb Handle value is %p : %p\n", player, player->audio_stream_cb);
 
-       return ret;
+       debug_fleave();
+
+       return MM_ERROR_NONE;
 }
 
 int
-_mmplayer_get_buffer_position(MMHandleType hplayer, int format, unsigned long* start_pos, unsigned long* stop_pos) // @
+_mmplayer_set_audiobuffer_cb(MMHandleType hplayer, mm_player_audio_stream_callback callback, void *user_param) // @
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
-       int ret = MM_ERROR_NONE;
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
 
        return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
 
-       ret = __gst_get_buffer_position ( player, format, start_pos, stop_pos );
+       player->audio_buffer_cb = callback;
+       player->audio_buffer_cb_user_param = user_param;
+       debug_log("Audio Stream cb Handle value is %p : %p\n", player, player->audio_buffer_cb);
 
-       return ret;
+       debug_fleave();
+
+       return MM_ERROR_NONE;
 }
 
 int
-_mmplayer_adjust_subtitle_postion(MMHandleType hplayer, int format, int position) // @
+_mmplayer_set_buffer_need_data_cb(MMHandleType hplayer, mm_player_buffer_need_data_callback callback, void *user_param) // @
 {
-       mm_player_t* player = (mm_player_t*)hplayer;
-       int ret = MM_ERROR_NONE;
+       mm_player_t* player = (mm_player_t*) hplayer;
 
        debug_fenter();
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
 
-       ret = __gst_adjust_subtitle_position(player, format, position);
+       player->need_data_cb = callback;
+       player->buffer_cb_user_param = user_param;
+
+       debug_log("buffer need dataHandle value is %p : %p\n", player, player->need_data_cb);
 
        debug_fleave();
 
-       return ret;
+       return MM_ERROR_NONE;
 }
 
-static gboolean
-__mmplayer_is_midi_type( gchar* str_caps)
+int
+_mmplayer_set_buffer_enough_data_cb(MMHandleType hplayer, mm_player_buffer_enough_data_callback callback, void *user_param) // @
 {
-       if ( ( g_strrstr(str_caps, "audio/midi") ) ||
-               ( g_strrstr(str_caps, "application/x-gst_ff-mmf") ) ||
-               ( g_strrstr(str_caps, "application/x-smaf") ) ||
-               ( g_strrstr(str_caps, "audio/x-imelody") ) ||
-               ( g_strrstr(str_caps, "audio/mobile-xmf") ) ||
-               ( g_strrstr(str_caps, "audio/xmf") ) ||
-               ( g_strrstr(str_caps, "audio/mxmf") ) )
-       {
-               debug_log("midi\n");
+       mm_player_t* player = (mm_player_t*) hplayer;
 
-               return TRUE;
-       }
+       debug_fenter();
 
-       return FALSE;
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+
+       player->enough_data_cb = callback;
+       player->buffer_cb_user_param = user_param;
+
+       debug_log("buffer enough data cb Handle value is %p : %p\n", player, player->enough_data_cb);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
 }
 
-static gboolean
-__mmplayer_is_amr_type (gchar *str_caps)
+int
+_mmplayer_set_buffer_seek_data_cb(MMHandleType hplayer, mm_player_buffer_seek_data_callback callback, void *user_param) // @
 {
-       if ((g_strrstr(str_caps, "AMR")) ||
-               (g_strrstr(str_caps, "amr")))
-       {
-               return TRUE;
-       }
-       return FALSE;
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
+
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail(callback, MM_ERROR_INVALID_ARGUMENT);
+
+       player->seek_data_cb = callback;
+       player->buffer_cb_user_param = user_param;
+
+       debug_log("buffer seek data cb Handle value is %p : %p\n", player, player->seek_data_cb);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
 }
 
-static gboolean
-__mmplayer_is_only_mp3_type (gchar *str_caps)
+int
+_mmplayer_set_videoframe_render_error_cb(MMHandleType hplayer, mm_player_video_frame_render_error_callback callback, void *user_param) // @
 {
-       if (g_strrstr(str_caps, "application/x-id3") ||
-               (g_strrstr(str_caps, "audio/mpeg") && g_strrstr(str_caps, "mpegversion=(int)1")))
+       mm_player_t* player = (mm_player_t*) hplayer;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( callback, MM_ERROR_INVALID_ARGUMENT );
+
+       player->video_frame_render_error_cb = callback;
+       player->video_frame_render_error_cb_user_param = user_param;
+
+       debug_log("Video frame render error cb Handle value is %p : %p\n", player, player->video_frame_render_error_cb);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+int
+__mmplayer_start_streaming_ext(mm_player_t *player)
+{
+       gint ret = MM_ERROR_NONE;
+
+       debug_fenter();
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       if (MMPLAYER_IS_HTTP_PD(player))
        {
-               return TRUE;
+               if ( !player->pd_downloader )
+               {
+                       ret = __mmplayer_realize_streaming_ext(player);
+
+                       if ( ret != MM_ERROR_NONE)
+                       {
+                               debug_error ("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 )
+                       {
+                               debug_error ("ERROR while starting PD...\n");
+                               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+                       }
+                       ret = MM_ERROR_NONE;
+               }
        }
-       return FALSE;
+
+       debug_fleave();
+       return ret;
 }
 
-static void
-__mmplayer_typefind_have_type(  GstElement *tf, guint probability,  // @
-GstCaps *caps, gpointer data)
+int
+_mmplayer_start(MMHandleType hplayer) // @
 {
-       mm_player_t* player = (mm_player_t*)data;
-       GstPad* pad = NULL;
+       mm_player_t* player = (mm_player_t*) hplayer;
+       gint ret = MM_ERROR_NONE;
 
        debug_fenter();
 
-       return_if_fail( player && tf && caps );
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       /* store type string */
-       MMPLAYER_FREEIF(player->type);
-       player->type = gst_caps_to_string(caps);
-       if (player->type)
-               debug_log("meida type %s found, probability %d%% / %d\n", player->type, probability, gst_caps_get_size(caps));
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_START );
 
-       /* midi type should be stored because it will be used to set audio gain in avsysaudiosink */
-       if ( __mmplayer_is_midi_type(player->type))
+       ret = _mmplayer_asm_set_state(hplayer, ASM_STATE_PLAYING);
+       if ( ret != MM_ERROR_NONE )
        {
-               player->profile.play_mode = MM_PLAYER_MODE_MIDI;
+               debug_error("failed to set asm state to PLAYING\n");
+               return ret;
        }
-       else if (__mmplayer_is_amr_type(player->type))
+
+       /* NOTE : we should check and create pipeline again if not created as we destroy
+        * whole pipeline when stopping in streamming playback
+        */
+       if ( ! player->pipeline )
        {
-               player->bypass_audio_effect = FALSE;
-               if ( (PLAYER_INI()->use_audio_effect_preset || PLAYER_INI()->use_audio_effect_custom) )
+               ret = __gst_realize( player );
+               if ( MM_ERROR_NONE != ret )
                {
-                       if ( player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_PRESET )
-                       {
-                               if (!_mmplayer_audio_effect_preset_apply(player, player->audio_effect_info.preset))
-                               {
-                                       debug_msg("apply audio effect(preset:%d) setting success\n",player->audio_effect_info.preset);
-                               }
-                       }
-                       else if ( player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM )
-                       {
-                               if (!_mmplayer_audio_effect_custom_apply(player))
-                               {
-                                       debug_msg("apply audio effect(custom) setting success\n");
-                               }
-                       }
+                       debug_error("failed to realize before starting. only in streamming\n");
+                       return ret;
                }
        }
-       else if ( g_strrstr(player->type, "application/x-hls"))
+
+       ret = __mmplayer_start_streaming_ext(player);
+       if ( ret != MM_ERROR_NONE )
        {
-               /* If it can't know exact type when it parses uri because of redirection case,
-                 * it will be fixed by typefinder here.
-                 */
-               player->profile.uri_type = MM_PLAYER_URI_TYPE_HLS;
+               debug_error("failed to start streaming ext \n");
        }
 
-       pad = gst_element_get_static_pad(tf, "src");
-       if ( !pad )
+       /* start pipeline */
+       ret = __gst_start( player );
+       if ( ret != MM_ERROR_NONE )
        {
-               debug_error("fail to get typefind src pad.\n");
-               return;
+               debug_error("failed to start player.\n");
        }
 
-       /* try to plug */
-       if ( ! __mmplayer_try_to_plug( player, pad, caps ) )
-       {
-               gboolean async = FALSE;
+       debug_fleave();
 
-               debug_error("failed to autoplug %s\n", player->type);
-               mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
+       return ret;
+}
 
-               if ( async && player->msg_posted == FALSE )
-               {
-                       __mmplayer_handle_missed_plugin( player );
-               }
+/* NOTE : it should be able to call 'stop' anytime*/
+int
+_mmplayer_stop(MMHandleType hplayer) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_STOP );
+
+       /* NOTE : application should not wait for EOS after calling STOP */
+       __mmplayer_cancel_delayed_eos( player );
 
-               goto DONE;
-       }
+       __mmplayer_unrealize_streaming_ext(player);
 
-       /* finish autopluging if no dynamic pad waiting */
-       if( ( ! player->have_dynamic_pad) && ( ! player->has_many_types) )
+       /* stop pipeline */
+       ret = __gst_stop( player );
+
+       if ( ret != MM_ERROR_NONE )
        {
-               if ( ! MMPLAYER_IS_RTSP_STREAMING( player ) )
-               {
-                       __mmplayer_pipeline_complete( NULL, (gpointer)player );
-               }
+               debug_error("failed to stop player.\n");
        }
 
-DONE:
-       gst_object_unref( GST_OBJECT(pad) );
-
        debug_fleave();
 
-       return;
+       return ret;
 }
 
-static gboolean
-__mmplayer_warm_up_video_codec( mm_player_t* player,  GstElementFactory *factory)
+int
+_mmplayer_pause(MMHandleType hplayer) // @
 {
-       GstElement *element;
-       GstStateChangeReturn  ret;
-       gboolean usable = TRUE;
+       mm_player_t* player = (mm_player_t*)hplayer;
+#ifndef GST_API_VERSION_1
+       GstFormat fmt = GST_FORMAT_TIME;
+#endif
+       gint64 pos_msec = 0;
+       gboolean async = FALSE;
+       gint ret = MM_ERROR_NONE;
 
-       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail ( factory, MM_ERROR_COMMON_INVALID_ARGUMENT );
+       debug_fenter();
 
-       element = gst_element_factory_create (factory, NULL);
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       ret = gst_element_set_state (element, GST_STATE_READY);
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_PAUSE );
 
-       if (ret != GST_STATE_CHANGE_SUCCESS)
+       switch (MMPLAYER_CURRENT_STATE(player))
        {
+               case MM_PLAYER_STATE_READY:
+               {
+                       /* check prepare async or not.
+                        * In the case of streaming playback, it's recommned to avoid blocking wait.
+                        */
+                       mm_attrs_get_int_by_name(player->attrs, "profile_prepare_async", &async);
+                       debug_log("prepare mode : %s", (async ? "async" : "sync"));
+               }
+               break;
+
+               case MM_PLAYER_STATE_PLAYING:
+               {
+                       /* NOTE : store current point to overcome some bad operation
+                       * ( returning zero when getting current position in paused state) of some
+                       * elements
+                       */
 #ifdef GST_API_VERSION_1
-               debug_error ("resource conflict so,  %s unusable\n", gst_object_get_name (GST_OBJECT (factory)));
+                       ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_msec);
 #else
-               debug_error ("resource conflict so,  %s unusable\n", GST_PLUGIN_FEATURE_NAME (factory));
+                       ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &pos_msec);
 #endif
-               usable = FALSE;
+                       if ( ! ret )
+                       debug_warning("getting current position failed in paused\n");
+
+                       player->last_position = pos_msec;
+               }
+               break;
        }
 
-       gst_element_set_state (element, GST_STATE_NULL);
-       gst_object_unref (element);
+       /* pause pipeline */
+       ret = __gst_pause( player, async );
 
-       return usable;
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to pause player. ret : 0x%x\n", ret);
+       }
+
+       debug_fleave();
+
+       return ret;
 }
 
-/* it will return first created element */
-static gboolean
-__mmplayer_try_to_plug(mm_player_t* player, GstPad *pad, const GstCaps *caps) // @
+int
+_mmplayer_resume(MMHandleType hplayer)
 {
-       MMPlayerGstElement* mainbin = NULL;
-       const char* mime = NULL;
-       const GList* item = NULL;
-       const gchar* klass = NULL;
-       GstCaps* res = NULL;
-       gboolean skip = FALSE;
-       GstPad* queue_pad = NULL;
-       GstElement* queue = NULL;
-       GstElement *element = NULL;
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
+       gboolean async = FALSE;
 
        debug_fenter();
 
-       return_val_if_fail( player && player->pipeline && player->pipeline->mainbin, FALSE );
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       mainbin = player->pipeline->mainbin;
+       ret = _mmplayer_asm_set_state(hplayer, ASM_STATE_PLAYING);
+       if ( ret )
+       {
+               debug_error("failed to set asm state to PLAYING\n");
+               return ret;
+       }
 
-       mime = gst_structure_get_name(gst_caps_get_structure(caps, 0));
+       /* check current state */
+       MMPLAYER_CHECK_STATE_RETURN_IF_FAIL( player, MMPLAYER_COMMAND_RESUME );
 
-       /* return if we got raw output */
-       if(g_str_has_prefix(mime, "video/x-raw") || g_str_has_prefix(mime, "audio/x-raw")
-               || g_str_has_prefix(mime, "video/x-surface")
-               || g_str_has_prefix(mime, "text/plain") ||g_str_has_prefix(mime, "text/x-pango-markup"))
-       {
+       /* resume pipeline */
+       ret = __gst_resume( player, FALSE );
 
-               element = (GstElement*)gst_pad_get_parent(pad);
-/* NOTE : When no decoder has added during autoplugging. like a simple wave playback.
- * No queue will be added. I think it can caused breaking sound when playing raw audio
- * frames but there's no different. Decodebin also doesn't add with those wav fils.
- * Anyway, currentely raw-queue seems not necessary.
- */
-#if 1
-               /* NOTE : check if previously linked element is demuxer/depayloader/parse means no decoder
-                * has linked. if so, we need to add queue for quality of output. note that
-                * decodebin also has same problem.
-                */
-               klass = gst_element_factory_get_klass( gst_element_get_factory(element) );
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to resume player.\n");
+       }
 
-               /* add queue if needed */
-               if( (g_strrstr(klass, "Demux") || g_strrstr(klass, "Depayloader")
-                       || g_strrstr(klass, "Parse")) &&  !g_str_has_prefix(mime, "text"))
-               {
-                       debug_log("adding raw queue\n");
 
-                       queue = gst_element_factory_make("queue", NULL);
-                       if ( ! queue )
-                       {
-                               debug_warning("failed to create queue\n");
-                               goto ERROR;
-                       }
+       debug_fleave();
 
-                       /* warmup */
-                       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(queue, GST_STATE_READY) )
-                       {
-                               debug_warning("failed to set state READY to queue\n");
-                               goto ERROR;
-                       }
+       return ret;
+}
 
-                       /* add to pipeline */
-                       if ( ! gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue) )
-                       {
-                               debug_warning("failed to add queue\n");
-                               goto ERROR;
-                       }
+int
+__mmplayer_set_play_count(mm_player_t* player, gint count)
+{
+       MMHandleType attrs = 0;
 
-                       /* link queue */
-                       queue_pad = gst_element_get_static_pad(queue, "sink");
+       debug_fenter();
 
-                       if ( GST_PAD_LINK_OK != gst_pad_link(pad, queue_pad) )
-                       {
-                               debug_warning("failed to link queue\n");
-                               goto ERROR;
-                       }
-                       gst_object_unref ( GST_OBJECT(queue_pad) );
-                       queue_pad = NULL;
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-                       /* running */
-                       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(queue, GST_STATE_PAUSED) )
-                       {
-                               debug_warning("failed to set state READY to queue\n");
-                               goto ERROR;
-                       }
+       attrs =  MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("fail to get attributes.\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
 
-                       /* replace given pad to queue:src */
-                       pad = gst_element_get_static_pad(queue, "src");
-                       if ( ! pad )
-                       {
-                               debug_warning("failed to get pad from queue\n");
-                               goto ERROR;
-                       }
-               }
-#endif
-               /* check if player can do start continually */
-               MMPLAYER_CHECK_CMD_IF_EXIT(player);
+       mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
+       if ( mmf_attrs_commit ( attrs ) ) /* return -1 if error */
+               debug_error("failed to commit\n");
 
-               if(__mmplayer_link_sink(player,pad))
-                        __mmplayer_gst_decode_callback(element, pad, FALSE, player);
+       debug_fleave();
 
-               gst_object_unref( GST_OBJECT(element));
-               element = NULL;
+       return  MM_ERROR_NONE;
+}
 
-               return TRUE;
-       }
+int
+_mmplayer_activate_section_repeat(MMHandleType hplayer, unsigned long start, unsigned long end)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       gint64 start_pos = 0;
+       gint64 end_pos = 0;
+       gint infinity = -1;
 
-       item = player->factories;
-       for(; item != NULL ; item = item->next)
-       {
-               GstElementFactory *factory = GST_ELEMENT_FACTORY(item->data);
-               const GList *pads;
-               gint idx = 0;
+       debug_fenter();
 
-               skip = FALSE;
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( end <= GST_TIME_AS_MSECONDS(player->duration), MM_ERROR_INVALID_ARGUMENT );
 
-               /* filtering exclude keyword */
-#ifdef GST_API_VERSION_1
-               for ( idx = 0; PLAYER_INI()->exclude_element_keyword[idx][0] != '\0'; idx++ )
-               {
-                       if ( g_strrstr(gst_object_get_name (GST_OBJECT (factory)),
-                                       PLAYER_INI()->exclude_element_keyword[idx]) )
-                       {
-                               debug_warning("skipping [%s] by exculde keyword [%s]\n",
-                                       gst_object_get_name (GST_OBJECT (factory)),
-                                       PLAYER_INI()->exclude_element_keyword[idx] );
+       player->section_repeat = TRUE;
+       player->section_repeat_start = start;
+       player->section_repeat_end = end;
 
-                               skip = TRUE;
-                               break;
-                       }
-               }
-#else
-               for ( idx = 0; PLAYER_INI()->exclude_element_keyword[idx][0] != '\0'; idx++ )
-               {
-                       if ( g_strrstr(GST_PLUGIN_FEATURE_NAME (factory),
-                                       PLAYER_INI()->exclude_element_keyword[idx] ) )
-                       {
-                               debug_warning("skipping [%s] by exculde keyword [%s]\n",
-                                       GST_PLUGIN_FEATURE_NAME (factory),
-                                       PLAYER_INI()->exclude_element_keyword[idx] );
+       start_pos = player->section_repeat_start * G_GINT64_CONSTANT(1000000);
+       end_pos = player->section_repeat_end * G_GINT64_CONSTANT(1000000);
+
+       __mmplayer_set_play_count( player, infinity );
+
+       if ( (!__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_pos,
+                                       GST_SEEK_TYPE_SET, end_pos)))
+       {
+               debug_error("failed to activate section repeat\n");
+
+               return MM_ERROR_PLAYER_SEEK;
+       }
 
-                               skip = TRUE;
-                               break;
-                       }
-               }
+       debug_log("succeeded to set section repeat from %d to %d\n",
+               player->section_repeat_start, player->section_repeat_end);
+
+       debug_fleave();
+
+       return  MM_ERROR_NONE;
+}
+
+static int
+__mmplayer_set_pcm_extraction(mm_player_t* player)
+{
+       guint64 start_nsec = 0;
+       guint64 end_nsec = 0;
+       guint64 dur_nsec = 0;
+       guint64 dur_msec = 0;
+#ifndef GST_API_VERSION_1
+       GstFormat fmt = GST_FORMAT_TIME;
 #endif
+       int required_start = 0;
+       int required_end = 0;
+       int ret = 0;
 
-               if ( skip ) continue;
+       debug_fenter();
 
-               /* check factory class for filtering */
-               klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(factory));
+       return_val_if_fail( player, FALSE );
 
-               /* NOTE : msl don't need to use image plugins.
-                * So, those plugins should be skipped for error handling.
-                */
-               if ( g_strrstr(klass, "Codec/Decoder/Image") )
-               {
+       mm_attrs_multiple_get(player->attrs,
+               NULL,
+               "pcm_extraction_start_msec", &required_start,
+               "pcm_extraction_end_msec", &required_end,
+               NULL);
+
+       debug_log("pcm extraction required position is from [%d] to [%d] (msec)\n", required_start, required_end);
+
+       if (required_start == 0 && required_end == 0)
+       {
+               debug_log("extracting entire stream");
+               return MM_ERROR_NONE;
+       }
+       else if (required_start < 0 || required_start > required_end || required_end < 0 )
+       {
+               debug_log("invalid range for pcm extraction");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       /* get duration */
 #ifdef GST_API_VERSION_1
-                       debug_log("skipping [%s] by not required\n",
-                               gst_object_get_name (GST_OBJECT (factory)) );
+       ret = gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &dur_nsec);
 #else
-                       debug_log("skipping [%s] by not required\n",
-                               GST_PLUGIN_FEATURE_NAME (factory) );
+       ret = gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &dur_nsec);
 #endif
-                       continue;
-               }
+       if ( !ret )
+       {
+               debug_error("failed to get duration");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+       dur_msec = GST_TIME_AS_MSECONDS(dur_nsec);
 
-               /* check pad compatability */
-               for(pads = gst_element_factory_get_static_pad_templates(factory);
-                    pads != NULL; pads=pads->next)
-               {
-                      GstStaticPadTemplate *temp1 = pads->data;
-                       GstCaps* static_caps = NULL;
+       if (dur_msec < required_end) // FIXME
+       {
+               debug_log("invalid end pos for pcm extraction");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
 
-                       if( temp1->direction != GST_PAD_SINK ||
-                               temp1->presence != GST_PAD_ALWAYS)
-                               continue;
+       start_nsec = required_start * G_GINT64_CONSTANT(1000000);
+       end_nsec = required_end * G_GINT64_CONSTANT(1000000);
 
+       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)))
+       {
+               debug_error("failed to seek for pcm extraction\n");
 
-                       if ( GST_IS_CAPS( &temp1->static_caps.caps) )
-                       {
-                               /* using existing caps */
-                               static_caps = gst_caps_ref( &temp1->static_caps.caps );
-                       }
-                       else
-                       {
-                               /* create one */
-                               static_caps = gst_caps_from_string ( temp1->static_caps.string );
-                       }
+               return MM_ERROR_PLAYER_SEEK;
+       }
 
-                       res = gst_caps_intersect(caps, static_caps);
+       debug_log("succeeded to set up segment extraction from [%llu] to [%llu] (nsec)\n", start_nsec, end_nsec);
 
-                       gst_caps_unref( static_caps );
-                       static_caps = NULL;
+       debug_fleave();
 
-                       if( res && !gst_caps_is_empty(res) )
-                       {
-#ifdef GST_API_VERSION_1
-                               GstElement *new_element;
-                               GList *elements = player->parsers;
-                               char *name_template = g_strdup(temp1->name_template);
-                               gchar *name_to_plug = gst_object_get_name (GST_OBJECT (factory));
+       return MM_ERROR_NONE;
+}
 
-                               gst_caps_unref(res);
+int
+_mmplayer_deactivate_section_repeat(MMHandleType hplayer)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       gint64 cur_pos = 0;
+#ifndef GST_API_VERSION_1
+       GstFormat fmt  = GST_FORMAT_TIME;
+#endif
+       gint onetime = 1;
 
-                               debug_log("found %s to plug\n", name_to_plug);
+       debug_fenter();
 
-                               new_element = gst_element_factory_create(GST_ELEMENT_FACTORY(factory), NULL);
-                               if ( ! new_element )
-                               {
-                                       debug_error("failed to create element [%s]. continue with next.\n",
-                                               gst_object_get_name (GST_OBJECT (factory)));
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-                                       MMPLAYER_FREEIF(name_template);
+       player->section_repeat = FALSE;
 
-                                       continue;
-                               }
+       __mmplayer_set_play_count( player, onetime );
+#ifdef GST_API_VERSION_1
+       gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &cur_pos);
 #else
-                               GstElement *new_element;
-                               GList *elements = player->parsers;
-                               char *name_template = g_strdup(temp1->name_template);
-                               gchar *name_to_plug = GST_PLUGIN_FEATURE_NAME(factory);
+       gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &cur_pos);
+#endif
 
-                               gst_caps_unref(res);
+       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, cur_pos,
+                                       GST_SEEK_TYPE_SET, player->duration )))
+       {
+               debug_error("failed to deactivate section repeat\n");
 
-                               debug_log("found %s to plug\n", name_to_plug);
+               return MM_ERROR_PLAYER_SEEK;
+       }
 
-                               new_element = gst_element_factory_create(GST_ELEMENT_FACTORY(factory), NULL);
-                               if ( ! new_element )
-                               {
-                                       debug_error("failed to create element [%s]. continue with next.\n",
-                                               GST_PLUGIN_FEATURE_NAME (factory));
+       debug_fenter();
 
-                                       MMPLAYER_FREEIF(name_template);
+       return MM_ERROR_NONE;
+}
 
-                                       continue;
-                               }
+int
+_mmplayer_set_playspeed(MMHandleType hplayer, gdouble rate)
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       signed long long pos_msec = 0;
+       int ret = MM_ERROR_NONE;
+       int mute = FALSE;
+#ifndef GST_API_VERSION_1
+       GstFormat format =GST_FORMAT_TIME;
 #endif
+       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
+       debug_fenter();
 
-                               /* check and skip it if it was already used. Otherwise, it can be an infinite loop
-                                * because parser can accept its own output as input.
-                                */
-                               if (g_strrstr(klass, "Parser"))
-                               {
-                                       gchar *selected = NULL;
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( !MMPLAYER_IS_STREAMING(player), MM_ERROR_NOT_SUPPORT_API );
 
-                                       for ( ; elements; elements = g_list_next(elements))
-                                       {
-                                               gchar *element_name = elements->data;
+       /* 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;
+       }
+       _mmplayer_set_mute(hplayer, mute);
 
-                                               if (g_strrstr(element_name, name_to_plug))
-                                               {
-                                                       debug_log("but, %s already linked, so skipping it\n", name_to_plug);
-                                                       skip = TRUE;
-                                               }
-                                       }
+       if (player->playback_rate == rate)
+               return MM_ERROR_NONE;
 
-                                       if (skip) continue;
+       /* 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;
 
-                                       selected = g_strdup(name_to_plug);
+       current_state = MMPLAYER_CURRENT_STATE(player);
+#ifdef GST_API_VERSION_1
+       if ( current_state != MM_PLAYER_STATE_PAUSED )
+               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_msec);
+#else
+       if ( current_state != MM_PLAYER_STATE_PAUSED )
+               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &format, &pos_msec);
+#endif
 
-                                       player->parsers = g_list_append(player->parsers, selected);
-                               }
+       debug_log ("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS (pos_msec), ret, current_state);
 
-                               /* store specific handles for futher control */
-                               if(g_strrstr(klass, "Demux") || g_strrstr(klass, "Parse"))
-                               {
-                                       /* FIXIT : first value will be overwritten if there's more
-                                        * than 1 demuxer/parser
-                                        */
-                                       debug_log("plugged element is demuxer. take it\n");
-                                       mainbin[MMPLAYER_M_DEMUX].id = MMPLAYER_M_DEMUX;
-                                       mainbin[MMPLAYER_M_DEMUX].gst = new_element;
-                               }
-                               else if(g_strrstr(klass, "Decoder") && __mmplayer_link_decoder(player,pad))
-                               {
-                                       if(mainbin[MMPLAYER_M_DEC1].gst == NULL)
-                                       {
-                                               debug_log("plugged element is decoder. take it[MMPLAYER_M_DEC1]\n");
-                                               mainbin[MMPLAYER_M_DEC1].id = MMPLAYER_M_DEC1;
-                                               mainbin[MMPLAYER_M_DEC1].gst = new_element;
-                                       }
-                                       else if(mainbin[MMPLAYER_M_DEC2].gst == NULL)
-                                       {
-                                               debug_log("plugged element is decoder. take it[MMPLAYER_M_DEC2]\n");
-                                               mainbin[MMPLAYER_M_DEC2].id = MMPLAYER_M_DEC2;
-                                               mainbin[MMPLAYER_M_DEC2].gst = new_element;
-                                       }
-                                       /* NOTE : IF one codec is found, add it to supported_codec and remove from
-                                        * missing plugin. Both of them are used to check what's supported codec
-                                        * before returning result of play start. And, missing plugin should be
-                                        * updated here for multi track files.
-                                        */
-                                       if(g_str_has_prefix(mime, "video"))
-                                       {
-                                               GstPad *src_pad = NULL;
-                                               GstPadTemplate *pad_templ = NULL;
-                                               GstCaps *caps = NULL;
-                                               gchar *caps_type = NULL;
+       if ( ( current_state == MM_PLAYER_STATE_PAUSED )
+               || ( ! ret ))
+               //|| ( player->last_position != 0 && pos_msec == 0 ) )
+       {
+               debug_warning("returning last point : %lld\n", player->last_position );
+               pos_msec = player->last_position;
+       }
 
-                                               debug_log("found VIDEO decoder\n");
-                                               player->not_supported_codec &= MISSING_PLUGIN_AUDIO;
-                                               player->can_support_codec |= FOUND_PLUGIN_VIDEO;
+       if ((!gst_element_seek (player->pipeline->mainbin[MMPLAYER_M_PIPE].gst,
+                               rate,
+                               GST_FORMAT_TIME,
+                               ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
+                               //( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_KEY_UNIT),
+                               GST_SEEK_TYPE_SET, pos_msec,
+                               //GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE,
+                GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)))
+       {
+               debug_error("failed to set speed playback\n");
+               return MM_ERROR_PLAYER_SEEK;
+       }
 
-                                               src_pad = gst_element_get_static_pad (new_element, "src");
-                                               pad_templ = gst_pad_get_pad_template (src_pad);
-                                               caps = GST_PAD_TEMPLATE_CAPS(pad_templ);
+       debug_log("succeeded to set speed playback as %fl\n", rate);
 
-                                               caps_type = gst_caps_to_string(caps);
+       debug_fleave();
 
-                                               if ( g_strrstr( caps_type, "ST12") )
-                                                       player->is_nv12_tiled = TRUE;
+       return MM_ERROR_NONE;;
+}
 
-                                               /* clean */
-                                               MMPLAYER_FREEIF( caps_type );
-                                               gst_object_unref (src_pad);
-                                       }
-                                       else if (g_str_has_prefix(mime, "audio"))
-                                       {
-                                               debug_log("found AUDIO decoder\n");
-                                               player->not_supported_codec &= MISSING_PLUGIN_VIDEO;
-                                               player->can_support_codec |= FOUND_PLUGIN_AUDIO;
-                                       }
-                               }
-                               if ( ! __mmplayer_close_link(player, pad, new_element,
-                                           name_template,gst_element_factory_get_static_pad_templates(factory)) )
-                               {
-                                       if (player->keep_detecting_vcodec)
-                                               continue;
+int
+_mmplayer_set_position(MMHandleType hplayer, int format, int position) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
 
-                                       /* Link is failed even though a supportable codec is found. */
-                                       __mmplayer_check_not_supported_codec(player, (gchar *)mime);
+       debug_fenter();
 
-                                       MMPLAYER_FREEIF(name_template);
-                                       debug_error("failed to call _close_link\n");
-                                       return FALSE;
-                               }
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-                               MMPLAYER_FREEIF(name_template);
-                               return TRUE;
-                       }
+       ret = __gst_set_position ( player, format, (unsigned long)position, FALSE );
 
-                       gst_caps_unref(res);
+       debug_fleave();
 
-                       break;
-               }
-       }
+       return ret;
+}
 
-       /* There is no available codec. */
-       __mmplayer_check_not_supported_codec(player,(gchar *)mime);
+int
+_mmplayer_get_position(MMHandleType hplayer, int format, unsigned long *position) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
 
-       debug_fleave();
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       return FALSE;
+       ret = __gst_get_position ( player, format, position );
 
-ERROR:
-       /* release */
-       if ( queue )
-               gst_object_unref( queue );
+       return ret;
+}
 
+int
+_mmplayer_get_buffer_position(MMHandleType hplayer, int format, unsigned long* start_pos, unsigned long* stop_pos) // @
+{
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
 
-       if ( queue_pad )
-               gst_object_unref( queue_pad );
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       if ( element )
-               gst_object_unref ( element );
+       ret = __gst_get_buffer_position ( player, format, start_pos, stop_pos );
 
-       return FALSE;
+       return ret;
 }
 
-
-static
-int __mmplayer_check_not_supported_codec(mm_player_t* player, gchar* mime)
+int
+_mmplayer_adjust_subtitle_postion(MMHandleType hplayer, int format, int position) // @
 {
+       mm_player_t* player = (mm_player_t*)hplayer;
+       int ret = MM_ERROR_NONE;
+
        debug_fenter();
 
-       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
-       return_val_if_fail ( mime, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
 
-       debug_log("mimetype to check: %s\n", mime );
+       ret = __gst_adjust_subtitle_position(player, format, position);
 
-       /* add missing plugin */
-       /* NOTE : msl should check missing plugin for image mime type.
-        * Some motion jpeg clips can have playable audio track.
-        * So, msl have to play audio after displaying popup written video format not supported.
-        */
-       if ( !( player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst ) )
-       {
-               if ( !( player->can_support_codec | player->videodec_linked | player->audiodec_linked ) )
-               {
-                       debug_log("not found demuxer\n");
-                       player->not_found_demuxer = TRUE;
-                       player->unlinked_demuxer_mime = g_strdup_printf ( "%s", mime );
+       debug_fleave();
 
-                       goto DONE;
-               }
-       }
+       return ret;
+}
 
-       if( ( g_str_has_prefix(mime, "video") ) ||( g_str_has_prefix(mime, "image") ) )
+static gboolean
+__mmplayer_is_midi_type( gchar* str_caps)
+{
+       if ( ( g_strrstr(str_caps, "audio/midi") ) ||
+               ( g_strrstr(str_caps, "application/x-gst_ff-mmf") ) ||
+               ( g_strrstr(str_caps, "application/x-smaf") ) ||
+               ( g_strrstr(str_caps, "audio/x-imelody") ) ||
+               ( g_strrstr(str_caps, "audio/mobile-xmf") ) ||
+               ( g_strrstr(str_caps, "audio/xmf") ) ||
+               ( g_strrstr(str_caps, "audio/mxmf") ) )
        {
-               debug_log("can support codec=%d, vdec_linked=%d, adec_linked=%d\n",
-                       player->can_support_codec, player->videodec_linked, player->audiodec_linked);
+               debug_log("midi\n");
 
-               /* check that clip have multi tracks or not */
-               if ( ( player->can_support_codec & FOUND_PLUGIN_VIDEO ) && ( player->videodec_linked ) )
-               {
-                       debug_log("video plugin is already linked\n");
-               }
-               else
-               {
-                       debug_warning("add VIDEO to missing plugin\n");
-                       player->not_supported_codec |= MISSING_PLUGIN_VIDEO;
-               }
-       }
-       else if ( g_str_has_prefix(mime, "audio") )
-       {
-               if ( ( player->can_support_codec & FOUND_PLUGIN_AUDIO ) && ( player->audiodec_linked ) )
-               {
-                       debug_log("audio plugin is already linked\n");
-               }
-               else
-               {
-                       debug_warning("add AUDIO to missing plugin\n");
-                       player->not_supported_codec |= MISSING_PLUGIN_AUDIO;
-               }
+               return TRUE;
        }
 
-DONE:
-       debug_fleave();
-
-       return MM_ERROR_NONE;
+       return FALSE;
 }
 
-
-static void __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data) // @
+static gboolean
+__mmplayer_is_amr_type (gchar *str_caps)
 {
-    mm_player_t* player = (mm_player_t*)data;
-
-       debug_fenter();
-
-       return_if_fail( player );
-
-       /* remove fakesink */
-       if ( ! __mmplayer_gst_remove_fakesink( player,
-               &player->pipeline->mainbin[MMPLAYER_M_SRC_FAKESINK]) )
+       if ((g_strrstr(str_caps, "AMR")) ||
+               (g_strrstr(str_caps, "amr")))
        {
-               /* 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;
+               return TRUE;
        }
-       debug_log("pipeline has completely constructed\n");
-
-       player->pipeline_is_constructed = TRUE;
+       return FALSE;
+}
 
-       if ( ( PLAYER_INI()->async_start ) &&
-               ( player->msg_posted == FALSE ) &&
-               ( player->cmd >= MMPLAYER_COMMAND_START ))
+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")))
        {
-               __mmplayer_handle_missed_plugin( player );
+               return TRUE;
        }
-
-       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-complete" );
+       return FALSE;
 }
 
-static gboolean __mmplayer_configure_audio_callback(mm_player_t* player)
+void
+__mmplayer_typefind_have_type(  GstElement *tf, guint probability,  // @
+GstCaps *caps, gpointer data)
 {
-       debug_fenter();
+       mm_player_t* player = (mm_player_t*)data;
+       GstPad* pad = NULL;
 
-       return_val_if_fail ( player, FALSE );
+       debug_fenter();
 
+       return_if_fail( player && tf && caps );
 
-       if ( MMPLAYER_IS_STREAMING(player) )
-               return FALSE;
+       /* store type string */
+       MMPLAYER_FREEIF(player->type);
+       player->type = gst_caps_to_string(caps);
+       if (player->type)
+               debug_log("meida type %s found, probability %d%% / %d\n", player->type, probability, gst_caps_get_size(caps));
 
-       /* This callback can be set to music player only. */
-       if((player->can_support_codec & 0x02) == FOUND_PLUGIN_VIDEO)
+       /* midi type should be stored because it will be used to set audio gain in avsysaudiosink */
+       if ( __mmplayer_is_midi_type(player->type))
        {
-               debug_warning("audio callback is not supported for video");
-               return FALSE;
+               player->profile.play_mode = MM_PLAYER_MODE_MIDI;
        }
-
-       if (player->audio_stream_cb)
+       else if (__mmplayer_is_amr_type(player->type))
        {
+               player->bypass_audio_effect = FALSE;
+               if ( (PLAYER_INI()->use_audio_effect_preset || PLAYER_INI()->use_audio_effect_custom) )
                {
-                       GstPad *pad = NULL;
-
-#ifdef GST_API_VERSION_1
-                       pad = gst_element_get_static_pad (player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
-#else
-                       pad = gst_element_get_pad (player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
-#endif
-
-                       if ( !pad )
+                       if ( player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_PRESET )
                        {
-                               debug_error("failed to get sink pad from audiosink to probe data\n");
-                               return FALSE;
+                               if (!_mmplayer_audio_effect_preset_apply(player, player->audio_effect_info.preset))
+                               {
+                                       debug_msg("apply audio effect(preset:%d) setting success\n",player->audio_effect_info.preset);
+                               }
+                       }
+                       else if ( player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM )
+                       {
+                               if (!_mmplayer_audio_effect_custom_apply(player))
+                               {
+                                       debug_msg("apply audio effect(custom) setting success\n");
+                               }
                        }
+               }
+       }
+       else 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 here.
+                 */
+               player->profile.uri_type = MM_PLAYER_URI_TYPE_HLS;
+       }
 
-#ifdef GST_API_VERSION_1
-                       player->audio_cb_probe_id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER,
-                               __mmplayer_audio_stream_probe, player, NULL);
-#else
-                       player->audio_cb_probe_id = gst_pad_add_buffer_probe (pad,
-                               G_CALLBACK (__mmplayer_audio_stream_probe), player);
-#endif
+       pad = gst_element_get_static_pad(tf, "src");
+       if ( !pad )
+       {
+               debug_error("fail to get typefind src pad.\n");
+               return;
+       }
 
-                       gst_object_unref (pad);
+       /* try to plug */
+       if ( ! __mmplayer_try_to_plug( player, pad, caps ) )
+       {
+               gboolean async = FALSE;
 
-                       pad = NULL;
-              }
+               debug_error("failed to autoplug %s\n", 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;
        }
-       else
+
+       /* finish autopluging if no dynamic pad waiting */
+       if( ( ! player->have_dynamic_pad) && ( ! player->has_many_types) )
        {
-               debug_error("There is no audio callback to configure.\n");
-               return FALSE;
+               if ( ! MMPLAYER_IS_RTSP_STREAMING( player ) )
+               {
+                       __mmplayer_pipeline_complete( NULL, (gpointer)player );
+               }
        }
 
-       debug_fleave();
+DONE:
+       gst_object_unref( GST_OBJECT(pad) );
 
-       return TRUE;
+       debug_fleave();
+
+       return;
 }
 
-static void
-__mmplayer_init_factories(mm_player_t* player) // @
+static gboolean
+__mmplayer_warm_up_video_codec( mm_player_t* player,  GstElementFactory *factory)
 {
-       debug_fenter();
+       GstElement *element;
+       GstStateChangeReturn  ret;
+       gboolean usable = TRUE;
 
-       return_if_fail ( player );
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( factory, MM_ERROR_COMMON_INVALID_ARGUMENT );
+
+       element = gst_element_factory_create (factory, NULL);
 
+       ret = gst_element_set_state (element, GST_STATE_READY);
+
+       if (ret != GST_STATE_CHANGE_SUCCESS)
+       {
 #ifdef GST_API_VERSION_1
-       player->factories = gst_registry_feature_filter(gst_registry_get(),
-                                        (GstPluginFeatureFilter)__mmplayer_feature_filter, FALSE, NULL);
+               debug_error ("resource conflict so,  %s unusable\n", gst_object_get_name (GST_OBJECT (factory)));
 #else
-       player->factories = gst_registry_feature_filter(gst_registry_get_default(),
-                                        (GstPluginFeatureFilter)__mmplayer_feature_filter, FALSE, NULL);
+               debug_error ("resource conflict so,  %s unusable\n", GST_PLUGIN_FEATURE_NAME (factory));
 #endif
+               usable = FALSE;
+       }
 
-       player->factories = g_list_sort(player->factories, (GCompareFunc)util_factory_rank_compare);
+       gst_element_set_state (element, GST_STATE_NULL);
+       gst_object_unref (element);
 
-       debug_fleave();
+       return usable;
 }
 
-static void
-__mmplayer_release_factories(mm_player_t* player) // @
+/* it will return first created element */
+static gboolean
+__mmplayer_try_to_plug(mm_player_t* player, GstPad *pad, const GstCaps *caps) // @
 {
+       MMPlayerGstElement* mainbin = NULL;
+       const char* mime = NULL;
+       const GList* item = NULL;
+       const gchar* klass = NULL;
+       GstCaps* res = NULL;
+       gboolean skip = FALSE;
+       GstPad* queue_pad = NULL;
+       GstElement* queue = NULL;
+       GstElement *element = NULL;
+
        debug_fenter();
 
-       return_if_fail ( player );
+       return_val_if_fail( player && player->pipeline && player->pipeline->mainbin, FALSE );
 
-       if (player->factories)
+       mainbin = player->pipeline->mainbin;
+
+       mime = gst_structure_get_name(gst_caps_get_structure(caps, 0));
+
+       /* return if we got raw output */
+       if(g_str_has_prefix(mime, "video/x-raw") || g_str_has_prefix(mime, "audio/x-raw")
+               || g_str_has_prefix(mime, "video/x-surface")
+               || g_str_has_prefix(mime, "text/plain") ||g_str_has_prefix(mime, "text/x-pango-markup"))
        {
-               gst_plugin_feature_list_free (player->factories);
-               player->factories = NULL;
-       }
 
-       debug_fleave();
-}
+               element = (GstElement*)gst_pad_get_parent(pad);
+/* NOTE : When no decoder has added during autoplugging. like a simple wave playback.
+ * No queue will be added. I think it can caused breaking sound when playing raw audio
+ * frames but there's no different. Decodebin also doesn't add with those wav fils.
+ * Anyway, currentely raw-queue seems not necessary.
+ */
+#if 1
+               /* NOTE : check if previously linked element is demuxer/depayloader/parse means no decoder
+                * has linked. if so, we need to add queue for quality of output. note that
+                * decodebin also has same problem.
+                */
+               klass = gst_element_factory_get_klass( gst_element_get_factory(element) );
 
-static void
-__mmplayer_release_misc(mm_player_t* player)
-{
-       int i;
-       debug_fenter();
+               /* add queue if needed */
+               if( (g_strrstr(klass, "Demux") || g_strrstr(klass, "Depayloader")
+                       || g_strrstr(klass, "Parse")) &&  !g_str_has_prefix(mime, "text"))
+               {
+                       debug_log("adding raw queue\n");
 
-       return_if_fail ( player );
+                       queue = gst_element_factory_make("queue", NULL);
+                       if ( ! queue )
+                       {
+                               debug_warning("failed to create queue\n");
+                               goto ERROR;
+                       }
 
-       player->use_video_stream = FALSE;
-       player->video_stream_cb = NULL;
-       player->video_stream_cb_user_param = NULL;
+                       /* warmup */
+                       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(queue, GST_STATE_READY) )
+                       {
+                               debug_warning("failed to set state READY to queue\n");
+                               goto ERROR;
+                       }
 
-       player->audio_stream_cb = NULL;
-       player->audio_stream_cb_user_param = NULL;
+                       /* add to pipeline */
+                       if ( ! gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue) )
+                       {
+                               debug_warning("failed to add queue\n");
+                               goto ERROR;
+                       }
 
-       player->audio_buffer_cb = NULL;
-       player->audio_buffer_cb_user_param = NULL;
+                       /* link queue */
+                       queue_pad = gst_element_get_static_pad(queue, "sink");
 
-       player->sent_bos = FALSE;
-       player->playback_rate = DEFAULT_PLAYBACK_RATE;
+                       if ( GST_PAD_LINK_OK != gst_pad_link(pad, queue_pad) )
+                       {
+                               debug_warning("failed to link queue\n");
+                               goto ERROR;
+                       }
+                       gst_object_unref ( GST_OBJECT(queue_pad) );
+                       queue_pad = NULL;
 
-       player->doing_seek = FALSE;
+                       /* running */
+                       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(queue, GST_STATE_PAUSED) )
+                       {
+                               debug_warning("failed to set state READY to queue\n");
+                               goto ERROR;
+                       }
 
-       player->streamer = NULL;
-       player->updated_bitrate_count = 0;
-       player->total_bitrate = 0;
-       player->updated_maximum_bitrate_count = 0;
-       player->total_maximum_bitrate = 0;
+                       /* replace given pad to queue:src */
+                       pad = gst_element_get_static_pad(queue, "src");
+                       if ( ! pad )
+                       {
+                               debug_warning("failed to get pad from queue\n");
+                               goto ERROR;
+                       }
+               }
+#endif
+               /* check if player can do start continually */
+               MMPLAYER_CHECK_CMD_IF_EXIT(player);
 
-       player->not_found_demuxer = 0;
+               if(__mmplayer_link_sink(player,pad))
+                       __mmplayer_gst_decode_callback(element, pad, FALSE, player);
 
-       player->last_position = 0;
-       player->duration = 0;
-       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.pos = 0;
-       player->msg_posted = FALSE;
-       player->has_many_types = FALSE;
+               gst_object_unref( GST_OBJECT(element));
+               element = NULL;
 
-       for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++)
-       {
-               player->bitrate[i] = 0;
-               player->maximum_bitrate[i] = 0;
+               return TRUE;
        }
 
-       /* clean found parsers */
-       if (player->parsers)
+       item = player->factories;
+       for(; item != NULL ; item = item->next)
        {
-               g_list_free(player->parsers);
-               player->parsers = NULL;
-       }
+               GstElementFactory *factory = GST_ELEMENT_FACTORY(item->data);
+               const GList *pads;
+               gint idx = 0;
 
-       MMPLAYER_FREEIF(player->album_art);
+               skip = FALSE;
 
-       /* free memory related to audio effect */
-       if(player->audio_effect_info.custom_ext_level_for_plugin)
-       {
-               free(player->audio_effect_info.custom_ext_level_for_plugin);
-       }
+               /* filtering exclude keyword */
+#ifdef GST_API_VERSION_1
+               for ( idx = 0; PLAYER_INI()->exclude_element_keyword[idx][0] != '\0'; idx++ )
+               {
+                       if ( g_strrstr(gst_object_get_name (GST_OBJECT (factory)),
+                                       PLAYER_INI()->exclude_element_keyword[idx]) )
+                       {
+                               debug_warning("skipping [%s] by exculde keyword [%s]\n",
+                                       gst_object_get_name (GST_OBJECT (factory)),
+                                       PLAYER_INI()->exclude_element_keyword[idx] );
 
-       debug_fleave();
-}
+                               skip = TRUE;
+                               break;
+                       }
+               }
+#else
+               for ( idx = 0; PLAYER_INI()->exclude_element_keyword[idx][0] != '\0'; idx++ )
+               {
+                       if ( g_strrstr(GST_PLUGIN_FEATURE_NAME (factory),
+                                       PLAYER_INI()->exclude_element_keyword[idx] ) )
+                       {
+                               debug_warning("skipping [%s] by exculde keyword [%s]\n",
+                                       GST_PLUGIN_FEATURE_NAME (factory),
+                                       PLAYER_INI()->exclude_element_keyword[idx] );
 
-static GstElement *__mmplayer_element_create_and_link(mm_player_t *player, GstPad* pad, const char* name)
-{
-       GstElement *element = NULL;
-       GstPad *sinkpad;
+                               skip = TRUE;
+                               break;
+                       }
+               }
+#endif
 
-       debug_log("creating %s to plug\n", name);
+               if ( skip ) continue;
 
-       element = gst_element_factory_make(name, NULL);
-       if ( ! element )
-       {
-               debug_error("failed to create queue\n");
-               return NULL;
-       }
+               /* check factory class for filtering */
+               klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(factory));
+
+               /* NOTE : msl don't need to use image plugins.
+                * So, those plugins should be skipped for error handling.
+                */
+               if ( g_strrstr(klass, "Codec/Decoder/Image") )
+               {
+#ifdef GST_API_VERSION_1
+                       debug_log("skipping [%s] by not required\n",
+                               gst_object_get_name (GST_OBJECT (factory)) );
+#else
+                       debug_log("skipping [%s] by not required\n",
+                               GST_PLUGIN_FEATURE_NAME (factory) );
+#endif
+                       continue;
+               }
 
-       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(element, GST_STATE_READY) )
-       {
-               debug_error("failed to set state READY to %s\n", name);
-               return NULL;
-       }
+               /* check pad compatability */
+               for(pads = gst_element_factory_get_static_pad_templates(factory);
+                       pads != NULL; pads=pads->next)
+               {
+                       GstStaticPadTemplate *temp1 = pads->data;
+                       GstCaps* static_caps = NULL;
 
-       if ( ! gst_bin_add(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), element))
-       {
-               debug_error("failed to add %s\n", name);
-               return NULL;
-       }
+                       if( temp1->direction != GST_PAD_SINK ||
+                               temp1->presence != GST_PAD_ALWAYS)
+                               continue;
 
-       sinkpad = gst_element_get_static_pad(element, "sink");
+                       if ( GST_IS_CAPS( &temp1->static_caps.caps) )
+                       {
+                               /* using existing caps */
+                               static_caps = gst_caps_ref( &temp1->static_caps.caps );
+                       }
+                       else
+                       {
+                               /* create one */
+                               static_caps = gst_caps_from_string ( temp1->static_caps.string );
+                       }
 
-       if ( GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad) )
-       {
-               debug_error("failed to link %s\n", name);
-               gst_object_unref (sinkpad);
+                       res = gst_caps_intersect(caps, static_caps);
 
-               return NULL;
-       }
+                       gst_caps_unref( static_caps );
+                       static_caps = NULL;
 
-       debug_log("linked %s to pipeline successfully\n", name);
+                       if( res && !gst_caps_is_empty(res) )
+                       {
+#ifdef GST_API_VERSION_1
+                               GstElement *new_element;
+                               GList *elements = player->parsers;
+                               char *name_template = g_strdup(temp1->name_template);
+                               gchar *name_to_plug = gst_object_get_name (GST_OBJECT (factory));
 
-       gst_object_unref (sinkpad);
+                               gst_caps_unref(res);
 
-       return element;
-}
+                               debug_log("found %s to plug\n", name_to_plug);
 
-static gboolean
-__mmplayer_close_link(mm_player_t* player, GstPad *srcpad, GstElement *sinkelement,
-const char *padname, const GList *templlist)
-{
-       GstPad *pad = NULL;
-       gboolean has_dynamic_pads = FALSE;
-       gboolean has_many_types = FALSE;
-       const char *klass = NULL;
-       GstStaticPadTemplate *padtemplate = NULL;
-       GstElementFactory *factory = NULL;
-       GstElement* queue = NULL;
-       GstElement* parser = NULL;
-       GstPad *pssrcpad = NULL;
-       GstPad *qsrcpad = NULL, *qsinkpad = NULL;
-       MMPlayerGstElement *mainbin = NULL;
-       GstStructure* str = NULL;
-       GstCaps* srccaps = NULL;
-       GstState warmup = GST_STATE_READY;
-       gboolean isvideo_decoder = FALSE;
-       guint q_max_size_time = 0;
+                               new_element = gst_element_factory_create(GST_ELEMENT_FACTORY(factory), NULL);
+                               if ( ! new_element )
+                               {
+                                       debug_error("failed to create element [%s]. continue with next.\n",
+                                               gst_object_get_name (GST_OBJECT (factory)));
 
-       debug_fenter();
+                                       MMPLAYER_FREEIF(name_template);
 
-       return_val_if_fail ( player &&
-               player->pipeline &&
-               player->pipeline->mainbin,
-               FALSE );
+                                       continue;
+                               }
+#else
+                               GstElement *new_element;
+                               GList *elements = player->parsers;
+                               char *name_template = g_strdup(temp1->name_template);
+                               gchar *name_to_plug = GST_PLUGIN_FEATURE_NAME(factory);
 
-       mainbin = player->pipeline->mainbin;
+                               gst_caps_unref(res);
 
-       debug_log("plugging pad %s:%s to newly create %s:%s\n",
-                                       GST_ELEMENT_NAME( GST_PAD_PARENT ( srcpad ) ),
-                       GST_PAD_NAME( srcpad ),
-                       GST_ELEMENT_NAME( sinkelement ),
-                       padname);
+                               debug_log("found %s to plug\n", name_to_plug);
 
-       factory = gst_element_get_factory(sinkelement);
-       klass = gst_element_factory_get_klass(factory);
+                               new_element = gst_element_factory_create(GST_ELEMENT_FACTORY(factory), NULL);
+                               if ( ! new_element )
+                               {
+                                       debug_error("failed to create element [%s]. continue with next.\n",
+                                               GST_PLUGIN_FEATURE_NAME (factory));
 
-       /* check if player can do start continually */
-       MMPLAYER_CHECK_CMD_IF_EXIT(player);
+                                       MMPLAYER_FREEIF(name_template);
 
-       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkelement, warmup) )
-       {
-               if (isvideo_decoder)
-                       player->keep_detecting_vcodec = TRUE;
+                                       continue;
+                               }
+#endif
 
-               debug_error("failed to set %d state to %s\n", warmup, GST_ELEMENT_NAME( sinkelement ));
-               goto ERROR;
-       }
+                               /* check and skip it if it was already used. Otherwise, it can be an infinite loop
+                                * because parser can accept its own output as input.
+                                */
+                               if (g_strrstr(klass, "Parser"))
+                               {
+                                       gchar *selected = NULL;
 
-       /* add to pipeline */
-       if ( ! gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), sinkelement) )
-       {
-               debug_error("failed to add %s to mainbin\n", GST_ELEMENT_NAME( sinkelement ));
-               goto ERROR;
-       }
+                                       for ( ; elements; elements = g_list_next(elements))
+                                       {
+                                               gchar *element_name = elements->data;
 
-       debug_log("element klass : %s\n", klass);
+                                               if (g_strrstr(element_name, name_to_plug))
+                                               {
+                                                       debug_log("but, %s already linked, so skipping it\n", name_to_plug);
+                                                       skip = TRUE;
+                                               }
+                                       }
 
-       /* added to support multi track files */
-       /* only decoder case and any of the video/audio still need to link*/
-       if(g_strrstr(klass, "Decoder") && __mmplayer_link_decoder(player,srcpad))
-       {
-               gchar *name = NULL;
+                                       if (skip) continue;
 
-               name = g_strdup(GST_ELEMENT_NAME( GST_PAD_PARENT ( srcpad )));
+                                       selected = g_strdup(name_to_plug);
 
-               if (g_strrstr(name, "mpegtsdemux"))
-               {
-                       gchar *demux_caps = NULL;
-                       gchar *parser_name = NULL;
-                       GstCaps *dcaps = NULL;
+                                       player->parsers = g_list_append(player->parsers, selected);
+                               }
 
-#ifdef GST_API_VERSION_1
-                       dcaps = gst_pad_get_current_caps(srcpad);
-#else
-                       dcaps = gst_pad_get_caps(srcpad);
-#endif
-                       demux_caps = gst_caps_to_string(dcaps);
+                               /* store specific handles for futher control */
+                               if(g_strrstr(klass, "Demux") || g_strrstr(klass, "Parse"))
+                               {
+                                       /* FIXIT : first value will be overwritten if there's more
+                                        * than 1 demuxer/parser
+                                        */
+                                       debug_log("plugged element is demuxer. take it\n");
+                                       mainbin[MMPLAYER_M_DEMUX].id = MMPLAYER_M_DEMUX;
+                                       mainbin[MMPLAYER_M_DEMUX].gst = new_element;
+                               }
+                               else if(g_strrstr(klass, "Decoder") && __mmplayer_link_decoder(player,pad))
+                               {
+                                       if(mainbin[MMPLAYER_M_DEC1].gst == NULL)
+                                       {
+                                               debug_log("plugged element is decoder. take it[MMPLAYER_M_DEC1]\n");
+                                               mainbin[MMPLAYER_M_DEC1].id = MMPLAYER_M_DEC1;
+                                               mainbin[MMPLAYER_M_DEC1].gst = new_element;
+                                       }
+                                       else if(mainbin[MMPLAYER_M_DEC2].gst == NULL)
+                                       {
+                                               debug_log("plugged element is decoder. take it[MMPLAYER_M_DEC2]\n");
+                                               mainbin[MMPLAYER_M_DEC2].id = MMPLAYER_M_DEC2;
+                                               mainbin[MMPLAYER_M_DEC2].gst = new_element;
+                                       }
+                                       /* NOTE : IF one codec is found, add it to supported_codec and remove from
+                                        * missing plugin. Both of them are used to check what's supported codec
+                                        * before returning result of play start. And, missing plugin should be
+                                        * updated here for multi track files.
+                                        */
+                                       if(g_str_has_prefix(mime, "video"))
+                                       {
+                                               GstPad *src_pad = NULL;
+                                               GstPadTemplate *pad_templ = NULL;
+                                               GstCaps *caps = NULL;
+                                               gchar *caps_type = NULL;
 
-                       if (g_strrstr(demux_caps, "video/x-h264"))
-                       {
-                               parser_name = g_strdup("h264parse");
-                       }
-                       else if (g_strrstr(demux_caps, "video/mpeg"))
-                       {
-                               parser_name = g_strdup("mpeg4videoparse");
-                       }
+                                               debug_log("found VIDEO decoder\n");
+                                               player->not_supported_codec &= MISSING_PLUGIN_AUDIO;
+                                               player->can_support_codec |= FOUND_PLUGIN_VIDEO;
 
-                       gst_caps_unref(dcaps);
-                       MMPLAYER_FREEIF( demux_caps );
+                                               src_pad = gst_element_get_static_pad (new_element, "src");
+                                               pad_templ = gst_pad_get_pad_template (src_pad);
+                                               caps = GST_PAD_TEMPLATE_CAPS(pad_templ);
 
-                       if (parser_name)
-                       {
-                               parser = __mmplayer_element_create_and_link(player, srcpad, parser_name);
+                                               caps_type = gst_caps_to_string(caps);
 
-                               MMPLAYER_FREEIF(parser_name);
+                                               if ( g_strrstr( caps_type, "ST12") )
+                                                       player->is_nv12_tiled = TRUE;
 
-                               if ( ! parser )
-                               {
-                                       debug_error("failed to create parser\n");
+                                               /* clean */
+                                               MMPLAYER_FREEIF( caps_type );
+                                               gst_object_unref (src_pad);
+                                       }
+                                       else if (g_str_has_prefix(mime, "audio"))
+                                       {
+                                               debug_log("found AUDIO decoder\n");
+                                               player->not_supported_codec &= MISSING_PLUGIN_VIDEO;
+                                               player->can_support_codec |= FOUND_PLUGIN_AUDIO;
+                                       }
                                }
-                               else
+                               if ( ! __mmplayer_close_link(player, pad, new_element,
+                                               name_template,gst_element_factory_get_static_pad_templates(factory)) )
                                {
-                                       /* update srcpad if parser is created */
-                                       pssrcpad = gst_element_get_static_pad(parser, "src");
-                                       srcpad = pssrcpad;
+                                       if (player->keep_detecting_vcodec)
+                                               continue;
+
+                                       /* Link is failed even though a supportable codec is found. */
+                                       __mmplayer_check_not_supported_codec(player, (gchar *)mime);
+
+                                       MMPLAYER_FREEIF(name_template);
+                                       debug_error("failed to call _close_link\n");
+                                       return FALSE;
                                }
+
+                               MMPLAYER_FREEIF(name_template);
+                               return TRUE;
                        }
-               }
-               MMPLAYER_FREEIF(name);
 
-               queue = __mmplayer_element_create_and_link(player, srcpad, "queue"); // parser - queue or demuxer - queue
-               if ( ! queue )
-               {
-                       debug_error("failed to create queue\n");
-                       goto ERROR;
+                       gst_caps_unref(res);
+
+                       break;
                }
+       }
 
-               /* update srcpad to link with decoder */
-               qsrcpad = gst_element_get_static_pad(queue, "src");
-               srcpad = qsrcpad;
+       /* There is no available codec. */
+       __mmplayer_check_not_supported_codec(player,(gchar *)mime);
 
-               q_max_size_time = GST_QUEUE_DEFAULT_TIME;
+       debug_fleave();
 
-               /* assigning queue handle for futher manipulation purpose */
-               /* FIXIT : make it some kind of list so that msl can support more then two stream (text, data, etc...) */
-               if(mainbin[MMPLAYER_M_Q1].gst == NULL)
-               {
-                       mainbin[MMPLAYER_M_Q1].id = MMPLAYER_M_Q1;
-                       mainbin[MMPLAYER_M_Q1].gst = queue;
+       return FALSE;
+
+ERROR:
+       /* release */
+       if ( queue )
+               gst_object_unref( queue );
 
-                       g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q1].gst), "max-size-time", q_max_size_time * GST_SECOND, NULL);
-               }
-               else if(mainbin[MMPLAYER_M_Q2].gst == NULL)
-               {
-                       mainbin[MMPLAYER_M_Q2].id = MMPLAYER_M_Q2;
-                       mainbin[MMPLAYER_M_Q2].gst = queue;
 
-                       g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q2].gst), "max-size-time", q_max_size_time * GST_SECOND, NULL);
-               }
-               else
-               {
-                       debug_critical("Not supporting more then two elementary stream\n");
-                       g_assert(1);
-               }
+       if ( queue_pad )
+               gst_object_unref( queue_pad );
 
-               pad = gst_element_get_static_pad(sinkelement, padname);
+       if ( element )
+               gst_object_unref ( element );
 
-               if ( ! pad )
-               {
-                       debug_warning("failed to get pad(%s) from %s. retrying with [sink]\n",
-                               padname, GST_ELEMENT_NAME(sinkelement) );
+       return FALSE;
+}
 
-                       pad = gst_element_get_static_pad(sinkelement, "sink");
-                       if ( ! pad )
-                       {
-                               debug_error("failed to get pad(sink) from %s. \n",
-                               GST_ELEMENT_NAME(sinkelement) );
-                               goto ERROR;
-                       }
-               }
 
-               /*  to check the video/audio type set the proper flag*/
-               {
-#ifdef GST_API_VERSION_1
-                       srccaps = gst_pad_get_current_caps( srcpad );
-#else
-                       srccaps = gst_pad_get_caps( srcpad );
-#endif
-                       if ( !srccaps )
-                               goto ERROR;
+static
+int __mmplayer_check_not_supported_codec(mm_player_t* player, gchar* mime)
+{
+       debug_fenter();
 
-                       str = gst_caps_get_structure( srccaps, 0 );
-                       if ( ! str )
-                               goto ERROR;
+       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+       return_val_if_fail ( mime, MM_ERROR_INVALID_ARGUMENT );
 
-                       name = gst_structure_get_name(str);
-                       if ( ! name )
-                               goto ERROR;
-               }
+       debug_log("mimetype to check: %s\n", mime );
 
-               /* link queue and decoder. so, it will be queue - decoder. */
-               if ( GST_PAD_LINK_OK != gst_pad_link(srcpad, pad) )
+       /* add missing plugin */
+       /* NOTE : msl should check missing plugin for image mime type.
+        * Some motion jpeg clips can have playable audio track.
+        * So, msl have to play audio after displaying popup written video format not supported.
+        */
+       if ( !( player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst ) )
+       {
+               if ( !( player->can_support_codec | player->videodec_linked | player->audiodec_linked ) )
                {
-                       gst_object_unref(GST_OBJECT(pad));
-                       debug_error("failed to link (%s) to pad(%s)\n", GST_ELEMENT_NAME( sinkelement ), padname );
+                       debug_log("not found demuxer\n");
+                       player->not_found_demuxer = TRUE;
+                       player->unlinked_demuxer_mime = g_strdup_printf ( "%s", mime );
 
-                       /* reconstitute supportable codec */
-                       if (strstr(name, "video"))
-                       {
-                               player->can_support_codec ^= FOUND_PLUGIN_VIDEO;
-                       }
-                       else if (strstr(name, "audio"))
-                       {
-                               player->can_support_codec ^= FOUND_PLUGIN_AUDIO;
-                       }
-                       goto ERROR;
+                       goto DONE;
                }
+       }
 
-               if (strstr(name, "video"))
-               {
-                       player->videodec_linked = 1;
-                       debug_msg("player->videodec_linked set to 1\n");
+       if( ( g_str_has_prefix(mime, "video") ) ||( g_str_has_prefix(mime, "image") ) )
+       {
+               debug_log("can support codec=%d, vdec_linked=%d, adec_linked=%d\n",
+                       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 ) )
+               {
+                       debug_log("video plugin is already linked\n");
                }
-               else if (strstr(name, "audio"))
+               else
                {
-                       player->audiodec_linked = 1;
-                       debug_msg("player->auddiodec_linked set to 1\n");
+                       debug_warning("add VIDEO to missing plugin\n");
+                       player->not_supported_codec |= MISSING_PLUGIN_VIDEO;
                }
-
-               gst_object_unref(GST_OBJECT(pad));
-               gst_caps_unref(GST_CAPS(srccaps));
-               srccaps = NULL;
        }
-
-       if ( !MMPLAYER_IS_HTTP_PD(player) )
+       else if ( g_str_has_prefix(mime, "audio") )
        {
-               if( (g_strrstr(klass, "Demux") && !g_strrstr(klass, "Metadata")) || (g_strrstr(klass, "Parser") ) )
+               if ( ( player->can_support_codec & FOUND_PLUGIN_AUDIO ) && ( player->audiodec_linked ) )
                {
-                       if (MMPLAYER_IS_HTTP_STREAMING(player))
-                       {
-#ifndef GST_API_VERSION_1
-                               GstFormat fmt  = GST_FORMAT_BYTES;
-#endif
-                               gint64 dur_bytes = 0L;
-                               gchar *file_buffering_path = NULL;
-                               gboolean use_file_buffer = FALSE;
+                       debug_log("audio plugin is already linked\n");
+               }
+               else
+               {
+                       debug_warning("add AUDIO to missing plugin\n");
+                       player->not_supported_codec |= MISSING_PLUGIN_AUDIO;
+               }
+       }
 
-                               if ( !mainbin[MMPLAYER_M_S_BUFFER].gst)
-                               {
-                                       debug_log("creating http streaming buffering queue\n");
+DONE:
+       debug_fleave();
 
-                                       queue = gst_element_factory_make("queue2", "http_streaming_buffer");
-                                       if ( ! queue )
-                                       {
-                                               debug_critical ( "failed to create buffering queue element\n" );
-                                               goto ERROR;
-                                       }
+       return MM_ERROR_NONE;
+}
 
-                                       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(queue, GST_STATE_READY) )
-                                       {
-                                               debug_error("failed to set state READY to buffering queue\n");
-                                               goto ERROR;
-                                       }
 
-                                       if ( !gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue) )
-                                       {
-                                               debug_error("failed to add buffering queue\n");
-                                               goto ERROR;
-                                       }
+static void __mmplayer_pipeline_complete(GstElement *decodebin,  gpointer data) // @
+{
+    mm_player_t* player = (mm_player_t*)data;
 
-                                       qsinkpad = gst_element_get_static_pad(queue, "sink");
-                                       qsrcpad = gst_element_get_static_pad(queue, "src");
+       debug_fenter();
 
-                                       if ( GST_PAD_LINK_OK != gst_pad_link(srcpad, qsinkpad) )
-                                       {
-                                               debug_error("failed to link buffering queue\n");
-                                               goto ERROR;
-                                       }
-                                       srcpad = qsrcpad;
+       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;
+       }
+       debug_log("pipeline has completely constructed\n");
 
-                                       mainbin[MMPLAYER_M_S_BUFFER].id = MMPLAYER_M_S_BUFFER;
-                                       mainbin[MMPLAYER_M_S_BUFFER].gst = queue;
+       player->pipeline_is_constructed = TRUE;
 
-                                       if ( !MMPLAYER_IS_HTTP_LIVE_STREAMING(player))
-                                        {
-#ifdef GST_API_VERSION_1
-                                               if ( !gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
-                                                       debug_error("fail to get duration.\n");
-#else
-                                               if ( !gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, &fmt, &dur_bytes))
-                                                       debug_error("fail to get duration.\n");
-#endif
+       if ( ( PLAYER_INI()->async_start ) &&
+               ( player->msg_posted == FALSE ) &&
+               ( player->cmd >= MMPLAYER_COMMAND_START ))
+       {
+               __mmplayer_handle_missed_plugin( player );
+       }
 
-                                               if (dur_bytes>0)
-                                               {
-                                                       use_file_buffer = MMPLAYER_USE_FILE_FOR_BUFFERING(player);
-                                                       file_buffering_path = g_strdup(PLAYER_INI()->http_file_buffer_path);
-                                               }
-                                       }
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-complete" );
+}
 
-                                       __mm_player_streaming_set_buffer(player->streamer,
-                                               queue,
-                                               TRUE,
-                                               PLAYER_INI()->http_max_size_bytes,
-                                               1.0,
-                                               PLAYER_INI()->http_buffering_limit,
-                                               PLAYER_INI()->http_buffering_time,
-                                               use_file_buffer,
-                                               file_buffering_path,
-                                               dur_bytes);
+static gboolean __mmplayer_configure_audio_callback(mm_player_t* player)
+{
+       debug_fenter();
 
-                                       MMPLAYER_FREEIF(file_buffering_path);
-                               }
-                       }
-               }
-       }
-       /* if it is not decoder or */
-       /* in decoder case any of the video/audio still need to link*/
-       if(!g_strrstr(klass, "Decoder"))
+       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)
        {
+               debug_warning("audio callback is not supported for video");
+               return FALSE;
+       }
 
-               pad = gst_element_get_static_pad(sinkelement, padname);
-               if ( ! pad )
+       if (player->audio_stream_cb)
+       {
                {
-                       debug_warning("failed to get pad(%s) from %s. retrying with [sink]\n",
-                                       padname, GST_ELEMENT_NAME(sinkelement) );
+                       GstPad *pad = NULL;
 
-                       pad = gst_element_get_static_pad(sinkelement, "sink");
+#ifdef GST_API_VERSION_1
+                       pad = gst_element_get_static_pad (player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
+#else
+                       pad = gst_element_get_pad (player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
+#endif
 
-                       if ( ! pad )
+                       if ( !pad )
                        {
-                               debug_error("failed to get pad(sink) from %s. \n",
-                                       GST_ELEMENT_NAME(sinkelement) );
-                               goto ERROR;
+                               debug_error("failed to get sink pad from audiosink to probe data\n");
+                               return FALSE;
                        }
-               }
 
-               if ( GST_PAD_LINK_OK != gst_pad_link(srcpad, pad) )
-               {
-                       gst_object_unref(GST_OBJECT(pad));
-                       debug_error("failed to link (%s) to pad(%s)\n", GST_ELEMENT_NAME( sinkelement ), padname );
-                       goto ERROR;
-               }
+#ifdef GST_API_VERSION_1
+                       player->audio_cb_probe_id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER,
+                               __mmplayer_audio_stream_probe, player, NULL);
+#else
+                       player->audio_cb_probe_id = gst_pad_add_buffer_probe (pad,
+                               G_CALLBACK (__mmplayer_audio_stream_probe), player);
+#endif
+
+                       gst_object_unref (pad);
 
-               gst_object_unref(GST_OBJECT(pad));
+                       pad = NULL;
+               }
        }
-
-       for(;templlist != NULL; templlist = templlist->next)
+       else
        {
-               padtemplate = templlist->data;
+               debug_error("There is no audio callback to configure.\n");
+               return FALSE;
+       }
 
-               debug_log ("director = [%d], presence = [%d]\n", padtemplate->direction, padtemplate->presence);
+       debug_fleave();
 
-               if(     padtemplate->direction != GST_PAD_SRC ||
-                       padtemplate->presence == GST_PAD_REQUEST        )
-                       continue;
+       return TRUE;
+}
+
+static void
+__mmplayer_init_factories(mm_player_t* player) // @
+{
+       debug_fenter();
+
+       return_if_fail ( player );
 
-               switch(padtemplate->presence)
-               {
-                       case GST_PAD_ALWAYS:
-                       {
-                               GstPad *srcpad = gst_element_get_static_pad(sinkelement, "src");
 #ifdef GST_API_VERSION_1
-                               GstCaps *caps = gst_pad_get_current_caps(srcpad);
+       player->factories = gst_registry_feature_filter(gst_registry_get(),
+                                        (GstPluginFeatureFilter)__mmplayer_feature_filter, FALSE, NULL);
 #else
-                               GstCaps *caps = gst_pad_get_caps(srcpad);
+       player->factories = gst_registry_feature_filter(gst_registry_get_default(),
+                                        (GstPluginFeatureFilter)__mmplayer_feature_filter, FALSE, NULL);
 #endif
 
-                               /* Check whether caps has many types */
-                               if ( gst_caps_get_size (caps) > 1 && g_strrstr(klass, "Parser")) {
-                                       debug_log ("has_many_types for this caps [%s]\n", gst_caps_to_string(caps));
-                                       has_many_types = TRUE;
-                                       break;
-                               }
+       player->factories = g_list_sort(player->factories, (GCompareFunc)util_factory_rank_compare);
 
-                               if ( ! __mmplayer_try_to_plug(player, srcpad, caps) )
-                               {
-                                       gst_object_unref(GST_OBJECT(srcpad));
-                                       gst_caps_unref(GST_CAPS(caps));
+       debug_fleave();
+}
 
-                                       debug_error("failed to plug something after %s\n", GST_ELEMENT_NAME( sinkelement ));
-                                       goto ERROR;
-                               }
+static void
+__mmplayer_release_factories(mm_player_t* player) // @
+{
+       debug_fenter();
 
-                               gst_caps_unref(GST_CAPS(caps));
-                               gst_object_unref(GST_OBJECT(srcpad));
+       return_if_fail ( player );
 
-                       }
-                       break;
+       if (player->factories)
+       {
+               gst_plugin_feature_list_free (player->factories);
+               player->factories = NULL;
+       }
 
+       debug_fleave();
+}
 
-                       case GST_PAD_SOMETIMES:
-                               has_dynamic_pads = TRUE;
-                       break;
+static void
+__mmplayer_release_misc(mm_player_t* player)
+{
+       int i;
+       debug_fenter();
 
-                       default:
-                               break;
-               }
-       }
+       return_if_fail ( player );
 
-       /* check if player can do start continually */
-       MMPLAYER_CHECK_CMD_IF_EXIT(player);
+       player->use_video_stream = FALSE;
+       player->video_stream_cb = NULL;
+       player->video_stream_cb_user_param = NULL;
 
-       if( has_dynamic_pads )
-       {
-               player->have_dynamic_pad = TRUE;
-               MMPLAYER_SIGNAL_CONNECT ( player, sinkelement, "pad-added",
-                       G_CALLBACK(__mmplayer_add_new_pad), player);
+       player->audio_stream_cb = NULL;
+       player->audio_stream_cb_user_param = NULL;
 
-               /* for streaming, more then one typefind will used for each elementary stream
-                * so this doesn't mean the whole pipeline completion
-                */
-               if ( ! MMPLAYER_IS_RTSP_STREAMING( player ) )
-               {
-                       MMPLAYER_SIGNAL_CONNECT( player, sinkelement, "no-more-pads",
-                               G_CALLBACK(__mmplayer_pipeline_complete), player);
-               }
+       player->audio_buffer_cb = NULL;
+       player->audio_buffer_cb_user_param = NULL;
+
+       player->sent_bos = FALSE;
+       player->playback_rate = DEFAULT_PLAYBACK_RATE;
+
+       player->doing_seek = FALSE;
+
+       player->streamer = NULL;
+       player->updated_bitrate_count = 0;
+       player->total_bitrate = 0;
+       player->updated_maximum_bitrate_count = 0;
+       player->total_maximum_bitrate = 0;
+
+       player->not_found_demuxer = 0;
+
+       player->last_position = 0;
+       player->duration = 0;
+       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.pos = 0;
+       player->msg_posted = FALSE;
+       player->has_many_types = FALSE;
+
+       for (i = 0; i < MM_PLAYER_STREAM_COUNT_MAX; i++)
+       {
+               player->bitrate[i] = 0;
+               player->maximum_bitrate[i] = 0;
        }
 
-       if (has_many_types)
+       /* clean found parsers */
+       if (player->parsers)
        {
-               GstPad *pad = NULL;
+               g_list_free(player->parsers);
+               player->parsers = NULL;
+       }
 
-               player->has_many_types = has_many_types;
+       MMPLAYER_FREEIF(player->album_art);
 
-               pad = gst_element_get_static_pad(sinkelement, "src");
-               MMPLAYER_SIGNAL_CONNECT (player, pad, "notify::caps", G_CALLBACK(__mmplayer_add_new_caps), player);
-               gst_object_unref (GST_OBJECT(pad));
+       /* free memory related to audio effect */
+       if(player->audio_effect_info.custom_ext_level_for_plugin)
+       {
+               free(player->audio_effect_info.custom_ext_level_for_plugin);
        }
 
+       debug_fleave();
+}
 
-       /* check if player can do start continually */
-       MMPLAYER_CHECK_CMD_IF_EXIT(player);
+static GstElement *__mmplayer_element_create_and_link(mm_player_t *player, GstPad* pad, const char* name)
+{
+       GstElement *element = NULL;
+       GstPad *sinkpad;
 
-       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkelement, GST_STATE_PAUSED) )
+       debug_log("creating %s to plug\n", name);
+
+       element = gst_element_factory_make(name, NULL);
+       if ( ! element )
        {
-               debug_error("failed to set state PAUSED to %s\n", GST_ELEMENT_NAME( sinkelement ));
-               goto ERROR;
+               debug_error("failed to create queue\n");
+               return NULL;
        }
 
-       if ( queue )
+       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(element, GST_STATE_READY) )
        {
-               if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state (queue, GST_STATE_PAUSED) )
-               {
-                       debug_error("failed to set state PAUSED to queue\n");
-                       goto ERROR;
-               }
-
-               queue = NULL;
-
-               gst_object_unref (GST_OBJECT(qsrcpad));
-               qsrcpad = NULL;
+               debug_error("failed to set state READY to %s\n", name);
+               return NULL;
        }
 
-       if ( parser )
+       if ( ! gst_bin_add(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), element))
        {
-               if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state (parser, GST_STATE_PAUSED) )
-               {
-                       debug_error("failed to set state PAUSED to queue\n");
-                       goto ERROR;
-               }
+               debug_error("failed to add %s\n", name);
+               return NULL;
+       }
 
-               parser = NULL;
+       sinkpad = gst_element_get_static_pad(element, "sink");
 
-               gst_object_unref (GST_OBJECT(pssrcpad));
-               pssrcpad = NULL;
+       if ( GST_PAD_LINK_OK != gst_pad_link(pad, sinkpad) )
+       {
+               debug_error("failed to link %s\n", name);
+               gst_object_unref (sinkpad);
+
+               return NULL;
        }
 
-       debug_fleave();
+       debug_log("linked %s to pipeline successfully\n", name);
 
-       return TRUE;
+       gst_object_unref (sinkpad);
 
-ERROR:
+       return element;
+}
 
-       if ( queue )
-       {
-               gst_object_unref(GST_OBJECT(qsrcpad));
+static gboolean
+__mmplayer_close_link(mm_player_t* player, GstPad *srcpad, GstElement *sinkelement,
+const char *padname, const GList *templlist)
+{
+       GstPad *pad = NULL;
+       gboolean has_dynamic_pads = FALSE;
+       gboolean has_many_types = FALSE;
+       const char *klass = NULL;
+       GstStaticPadTemplate *padtemplate = NULL;
+       GstElementFactory *factory = NULL;
+       GstElement* queue = NULL;
+       GstElement* parser = NULL;
+       GstPad *pssrcpad = NULL;
+       GstPad *qsrcpad = NULL, *qsinkpad = NULL;
+       MMPlayerGstElement *mainbin = NULL;
+       GstStructure* str = NULL;
+       GstCaps* srccaps = NULL;
+       GstState warmup = GST_STATE_READY;
+       gboolean isvideo_decoder = FALSE;
+       guint q_max_size_time = 0;
 
-               /* 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
-                * dropping the final reference, to allow them to clean up.
-                */
-               gst_element_set_state(queue, GST_STATE_NULL);
-               /* And, it still has a parent "player".
-                * You need to let the parent manage the object instead of unreffing the object directly.
-                */
+       debug_fenter();
 
-               gst_bin_remove (GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue);
-               //gst_object_unref( queue );
-       }
+       return_val_if_fail ( player &&
+               player->pipeline &&
+               player->pipeline->mainbin,
+               FALSE );
 
-       if ( srccaps )
-               gst_caps_unref(GST_CAPS(srccaps));
+       mainbin = player->pipeline->mainbin;
+
+       debug_log("plugging pad %s:%s to newly create %s:%s\n",
+                                       GST_ELEMENT_NAME( GST_PAD_PARENT ( srcpad ) ),
+                       GST_PAD_NAME( srcpad ),
+                       GST_ELEMENT_NAME( sinkelement ),
+                       padname);
 
-    return FALSE;
-}
+       factory = gst_element_get_factory(sinkelement);
+       klass = gst_element_factory_get_klass(factory);
 
-static gboolean __mmplayer_feature_filter(GstPluginFeature *feature, gpointer data) // @
-{
-       const gchar *klass;
-       //const gchar *name;
+       /* check if player can do start continually */
+       MMPLAYER_CHECK_CMD_IF_EXIT(player);
 
-       /* we only care about element factories */
-       if (!GST_IS_ELEMENT_FACTORY(feature))
-               return FALSE;
+       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkelement, warmup) )
+       {
+               if (isvideo_decoder)
+                       player->keep_detecting_vcodec = TRUE;
 
-       /* only parsers, demuxers and decoders */
-       klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(feature));
-       //name = gst_element_factory_get_longname(GST_ELEMENT_FACTORY(feature));
+               debug_error("failed to set %d state to %s\n", warmup, GST_ELEMENT_NAME( sinkelement ));
+               goto ERROR;
+       }
 
-       if( g_strrstr(klass, "Demux") == NULL &&
-               g_strrstr(klass, "Codec/Decoder") == NULL &&
-               g_strrstr(klass, "Depayloader") == NULL &&
-               g_strrstr(klass, "Parse") == NULL)
-       {
-               return FALSE;
-       }
-    return TRUE;
-}
+       /* add to pipeline */
+       if ( ! gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), sinkelement) )
+       {
+               debug_error("failed to add %s to mainbin\n", GST_ELEMENT_NAME( sinkelement ));
+               goto ERROR;
+       }
 
+       debug_log("element klass : %s\n", klass);
 
-static void    __mmplayer_add_new_caps(GstPad* pad, GParamSpec* unused, gpointer data)
-{
-       mm_player_t* player = (mm_player_t*) data;
-       GstCaps *caps = NULL;
-       GstStructure *str = NULL;
-       const char *name;
+       /* added to support multi track files */
+       /* only decoder case and any of the video/audio still need to link*/
+       if(g_strrstr(klass, "Decoder") && __mmplayer_link_decoder(player,srcpad))
+       {
+               gchar *name = NULL;
 
-       debug_fenter();
+               name = g_strdup(GST_ELEMENT_NAME( GST_PAD_PARENT ( srcpad )));
 
-       return_if_fail ( pad )
-       return_if_fail ( unused )
-       return_if_fail ( data )
+               if (g_strrstr(name, "mpegtsdemux"))
+               {
+                       gchar *demux_caps = NULL;
+                       gchar *parser_name = NULL;
+                       GstCaps *dcaps = NULL;
 
 #ifdef GST_API_VERSION_1
-       caps = gst_pad_get_current_caps(pad);
+                       dcaps = gst_pad_get_current_caps(srcpad);
 #else
-       caps = gst_pad_get_caps(pad);
+                       dcaps = gst_pad_get_caps(srcpad);
 #endif
-       if ( !caps )
-               return;
-
-       str = gst_caps_get_structure(caps, 0);
-       if ( !str )
-               return;
+                       demux_caps = gst_caps_to_string(dcaps);
 
-       name = gst_structure_get_name(str);
-       if ( !name )
-               return;
-       debug_log("name=%s\n", name);
+                       if (g_strrstr(demux_caps, "video/x-h264"))
+                       {
+                               parser_name = g_strdup("h264parse");
+                       }
+                       else if (g_strrstr(demux_caps, "video/mpeg"))
+                       {
+                               parser_name = g_strdup("mpeg4videoparse");
+                       }
 
-       if ( ! __mmplayer_try_to_plug(player, pad, caps) )
-       {
-               debug_error("failed to autoplug for type (%s)\n", name);
-               gst_caps_unref(caps);
-               return;
-       }
+                       gst_caps_unref(dcaps);
+                       MMPLAYER_FREEIF( demux_caps );
 
-       gst_caps_unref(caps);
+                       if (parser_name)
+                       {
+                               parser = __mmplayer_element_create_and_link(player, srcpad, parser_name);
 
-       __mmplayer_pipeline_complete( NULL, (gpointer)player );
+                               MMPLAYER_FREEIF(parser_name);
 
-       debug_fleave();
+                               if ( ! parser )
+                               {
+                                       debug_error("failed to create parser\n");
+                               }
+                               else
+                               {
+                                       /* update srcpad if parser is created */
+                                       pssrcpad = gst_element_get_static_pad(parser, "src");
+                                       srcpad = pssrcpad;
+                               }
+                       }
+               }
+               MMPLAYER_FREEIF(name);
 
-       return;
-}
+               queue = __mmplayer_element_create_and_link(player, srcpad, "queue"); // parser - queue or demuxer - queue
+               if ( ! queue )
+               {
+                       debug_error("failed to create queue\n");
+                       goto ERROR;
+               }
 
-static void __mmplayer_set_unlinked_mime_type(mm_player_t* player, GstCaps *caps)
-{
-       GstStructure *str;
-       gint version = 0;
-       const char *stream_type;
-       gchar *version_field = NULL;
+               /* update srcpad to link with decoder */
+               qsrcpad = gst_element_get_static_pad(queue, "src");
+               srcpad = qsrcpad;
 
-       debug_fenter();
+               q_max_size_time = GST_QUEUE_DEFAULT_TIME;
 
-       return_if_fail ( player );
-       return_if_fail ( caps );
+               /* assigning queue handle for futher manipulation purpose */
+               /* FIXIT : make it some kind of list so that msl can support more then two stream (text, data, etc...) */
+               if(mainbin[MMPLAYER_M_Q1].gst == NULL)
+               {
+                       mainbin[MMPLAYER_M_Q1].id = MMPLAYER_M_Q1;
+                       mainbin[MMPLAYER_M_Q1].gst = queue;
 
-       str = gst_caps_get_structure(caps, 0);
-       if ( !str )
-               return;
+                       g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q1].gst), "max-size-time", q_max_size_time * GST_SECOND, NULL);
+               }
+               else if(mainbin[MMPLAYER_M_Q2].gst == NULL)
+               {
+                       mainbin[MMPLAYER_M_Q2].id = MMPLAYER_M_Q2;
+                       mainbin[MMPLAYER_M_Q2].gst = queue;
 
-       stream_type = gst_structure_get_name(str);
-       if ( !stream_type )
-               return;
+                       g_object_set (G_OBJECT (mainbin[MMPLAYER_M_Q2].gst), "max-size-time", q_max_size_time * GST_SECOND, NULL);
+               }
+               else
+               {
+                       debug_critical("Not supporting more then two elementary stream\n");
+                       g_assert(1);
+               }
 
+               pad = gst_element_get_static_pad(sinkelement, padname);
 
-       /* set unlinked mime type for downloadable codec */
-       if (g_str_has_prefix(stream_type, "video/"))
-       {
-               if (g_str_has_prefix(stream_type, "video/mpeg"))
+               if ( ! pad )
                {
-                       gst_structure_get_int (str, MM_PLAYER_MPEG_VNAME, &version);
-                       version_field = MM_PLAYER_MPEG_VNAME;
+                       debug_warning("failed to get pad(%s) from %s. retrying with [sink]\n",
+                               padname, GST_ELEMENT_NAME(sinkelement) );
+
+                       pad = gst_element_get_static_pad(sinkelement, "sink");
+                       if ( ! pad )
+                       {
+                               debug_error("failed to get pad(sink) from %s. \n",
+                               GST_ELEMENT_NAME(sinkelement) );
+                               goto ERROR;
+                       }
                }
-               else if (g_str_has_prefix(stream_type, "video/x-wmv"))
+
+               /*  to check the video/audio type set the proper flag*/
                {
-                       gst_structure_get_int (str, MM_PLAYER_WMV_VNAME, &version);
-                       version_field = MM_PLAYER_WMV_VNAME;
+#ifdef GST_API_VERSION_1
+                       srccaps = gst_pad_get_current_caps( srcpad );
+#else
+                       srccaps = gst_pad_get_caps( srcpad );
+#endif
+                       if ( !srccaps )
+                               goto ERROR;
+
+                       str = gst_caps_get_structure( srccaps, 0 );
+                       if ( ! str )
+                               goto ERROR;
 
+                       name = gst_structure_get_name(str);
+                       if ( ! name )
+                               goto ERROR;
                }
-               else if (g_str_has_prefix(stream_type, "video/x-divx"))
+
+               /* link queue and decoder. so, it will be queue - decoder. */
+               if ( GST_PAD_LINK_OK != gst_pad_link(srcpad, pad) )
                {
-                       gst_structure_get_int (str, MM_PLAYER_DIVX_VNAME, &version);
-                       version_field = MM_PLAYER_DIVX_VNAME;
+                       gst_object_unref(GST_OBJECT(pad));
+                       debug_error("failed to link (%s) to pad(%s)\n", GST_ELEMENT_NAME( sinkelement ), padname );
+
+                       /* reconstitute supportable codec */
+                       if (strstr(name, "video"))
+                       {
+                               player->can_support_codec ^= FOUND_PLUGIN_VIDEO;
+                       }
+                       else if (strstr(name, "audio"))
+                       {
+                               player->can_support_codec ^= FOUND_PLUGIN_AUDIO;
+                       }
+                       goto ERROR;
                }
 
-               if (version)
+               if (strstr(name, "video"))
                {
-                       player->unlinked_video_mime = g_strdup_printf("%s, %s=%d", stream_type, version_field, version);
+                       player->videodec_linked = 1;
+                       debug_msg("player->videodec_linked set to 1\n");
+
                }
-               else
+               else if (strstr(name, "audio"))
                {
-                       player->unlinked_video_mime = g_strdup_printf("%s", stream_type);
+                       player->audiodec_linked = 1;
+                       debug_msg("player->auddiodec_linked set to 1\n");
                }
+
+               gst_object_unref(GST_OBJECT(pad));
+               gst_caps_unref(GST_CAPS(srccaps));
+               srccaps = NULL;
        }
-       else if (g_str_has_prefix(stream_type, "audio/"))
+
+       if ( !MMPLAYER_IS_HTTP_PD(player) )
        {
-               if (g_str_has_prefix(stream_type, "audio/mpeg")) // mp3 or aac
-               {
-                       gst_structure_get_int (str, MM_PLAYER_MPEG_VNAME, &version);
-                       version_field = MM_PLAYER_MPEG_VNAME;
-               }
-               else if (g_str_has_prefix(stream_type, "audio/x-wma"))
+               if( (g_strrstr(klass, "Demux") && !g_strrstr(klass, "Metadata")) || (g_strrstr(klass, "Parser") ) )
                {
-                       gst_structure_get_int (str, MM_PLAYER_WMA_VNAME, &version);
-                       version_field = MM_PLAYER_WMA_VNAME;
-               }
+                       if (MMPLAYER_IS_HTTP_STREAMING(player))
+                       {
+#ifndef GST_API_VERSION_1
+                               GstFormat fmt  = GST_FORMAT_BYTES;
+#endif
+                               gint64 dur_bytes = 0L;
+                               gchar *file_buffering_path = NULL;
+                               gboolean use_file_buffer = FALSE;
+
+                               if ( !mainbin[MMPLAYER_M_S_BUFFER].gst)
+                               {
+                                       debug_log("creating http streaming buffering queue\n");
+
+                                       queue = gst_element_factory_make("queue2", "http_streaming_buffer");
+                                       if ( ! queue )
+                                       {
+                                               debug_critical ( "failed to create buffering queue element\n" );
+                                               goto ERROR;
+                                       }
 
-               if (version)
-               {
-                       player->unlinked_audio_mime = g_strdup_printf("%s, %s=%d", stream_type, version_field, version);
-               }
-               else
-               {
-                       player->unlinked_audio_mime = g_strdup_printf("%s", stream_type);
-               }
-       }
+                                       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(queue, GST_STATE_READY) )
+                                       {
+                                               debug_error("failed to set state READY to buffering queue\n");
+                                               goto ERROR;
+                                       }
 
-       debug_fleave();
-}
+                                       if ( !gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue) )
+                                       {
+                                               debug_error("failed to add buffering queue\n");
+                                               goto ERROR;
+                                       }
 
-static void __mmplayer_add_new_pad(GstElement *element, GstPad *pad, gpointer data)
-{
-       mm_player_t* player = (mm_player_t*) data;
-       GstCaps *caps = NULL;
-       GstStructure *str = NULL;
-       const char *name;
+                                       qsinkpad = gst_element_get_static_pad(queue, "sink");
+                                       qsrcpad = gst_element_get_static_pad(queue, "src");
 
-       debug_fenter();
-       return_if_fail ( player );
-       return_if_fail ( pad );
+                                       if ( GST_PAD_LINK_OK != gst_pad_link(srcpad, qsinkpad) )
+                                       {
+                                               debug_error("failed to link buffering queue\n");
+                                               goto ERROR;
+                                       }
+                                       srcpad = qsrcpad;
 
-       GST_OBJECT_LOCK (pad);
-#ifdef GST_API_VERSION_1
-       if ((caps = gst_pad_get_current_caps (pad)))
-               gst_caps_ref(caps);
-#else
-       if ((caps = GST_PAD_CAPS(pad)))
-               gst_caps_ref(caps);
-#endif
-       GST_OBJECT_UNLOCK (pad);
 
-       if ( NULL == caps )
-       {
+                                       mainbin[MMPLAYER_M_S_BUFFER].id = MMPLAYER_M_S_BUFFER;
+                                       mainbin[MMPLAYER_M_S_BUFFER].gst = queue;
+
+                                       if ( !MMPLAYER_IS_HTTP_LIVE_STREAMING(player))
+                                       {
 #ifdef GST_API_VERSION_1
-               caps = gst_pad_get_current_caps(pad);
+                                               if ( !gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, GST_FORMAT_BYTES, &dur_bytes))
+                                                       debug_error("fail to get duration.\n");
 #else
-               caps = gst_pad_get_caps(pad);
+                                               if ( !gst_element_query_duration(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, &fmt, &dur_bytes))
+                                                       debug_error("fail to get duration.\n");
 #endif
-               if ( !caps ) return;
-       }
-
-       //MMPLAYER_LOG_GST_CAPS_TYPE(caps);
-
-       str = gst_caps_get_structure(caps, 0);
-       if ( !str )
-               return;
 
-       name = gst_structure_get_name(str);
-       if ( !name )
-               return;
+                                               if (dur_bytes>0)
+                                               {
+                                                       use_file_buffer = MMPLAYER_USE_FILE_FOR_BUFFERING(player);
+                                                       file_buffering_path = g_strdup(PLAYER_INI()->http_file_buffer_path);
+                                               }
+                                       }
 
-       player->num_dynamic_pad++;
-       debug_log("stream count inc : %d\n", player->num_dynamic_pad);
+                                       __mm_player_streaming_set_buffer(player->streamer,
+                                               queue,
+                                               TRUE,
+                                               PLAYER_INI()->http_max_size_bytes,
+                                               1.0,
+                                               PLAYER_INI()->http_buffering_limit,
+                                               PLAYER_INI()->http_buffering_time,
+                                               use_file_buffer,
+                                               file_buffering_path,
+                                               dur_bytes);
 
-       /* Note : If the stream is the subtitle, we try not to play it. Just close the demuxer subtitle pad.
-         *     If want to play it, remove this code.
-         */
-       if (g_strrstr(name, "application"))
-       {
-               if (g_strrstr(name, "x-id3") || g_strrstr(name, "x-apetag"))
-               {
-                       /* If id3/ape tag comes, keep going */
-                       debug_log("application mime exception : id3/ape tag");
-               }
-               else
-               {
-                       /* Otherwise, we assume that this stream is subtile. */
-                       debug_log(" application mime type pad is closed.");
-                       return;
+                                       MMPLAYER_FREEIF(file_buffering_path);
+                               }
+                       }
                }
        }
-       else if (g_strrstr(name, "audio"))
+       /* if it is not decoder or */
+       /* in decoder case any of the video/audio still need to link*/
+       if(!g_strrstr(klass, "Decoder"))
        {
-               gint samplerate = 0, channels = 0;
 
-               /* set stream information */
-               /* if possible, set it here because the caps is not distrubed by resampler. */
-               gst_structure_get_int (str, "rate", &samplerate);
-               mm_attrs_set_int_by_name(player->attrs, "content_audio_samplerate", samplerate);
+               pad = gst_element_get_static_pad(sinkelement, padname);
+               if ( ! pad )
+               {
+                       debug_warning("failed to get pad(%s) from %s. retrying with [sink]\n",
+                                       padname, GST_ELEMENT_NAME(sinkelement) );
 
-               gst_structure_get_int (str, "channels", &channels);
-               mm_attrs_set_int_by_name(player->attrs, "content_audio_channels", channels);
+                       pad = gst_element_get_static_pad(sinkelement, "sink");
 
-               debug_log("audio samplerate : %d        channels : %d", samplerate, channels);
-       }
-       else if (g_strrstr(name, "video"))
-       {
-               gint stype;
-               mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &stype);
+                       if ( ! pad )
+                       {
+                               debug_error("failed to get pad(sink) from %s. \n",
+                                       GST_ELEMENT_NAME(sinkelement) );
+                               goto ERROR;
+                       }
+               }
 
-               /* don't make video because of not required */
-               if (stype == MM_DISPLAY_SURFACE_NULL)
+               if ( GST_PAD_LINK_OK != gst_pad_link(srcpad, pad) )
                {
-                       debug_log("no video because it's not required");
-                       return;
+                       gst_object_unref(GST_OBJECT(pad));
+                       debug_error("failed to link (%s) to pad(%s)\n", GST_ELEMENT_NAME( sinkelement ), padname );
+                       goto ERROR;
                }
 
-               player->v_stream_caps = gst_caps_copy(caps); //if needed, video caps is required when videobin is created
+               gst_object_unref(GST_OBJECT(pad));
        }
 
-       if ( ! __mmplayer_try_to_plug(player, pad, caps) )
+       for(;templlist != NULL; templlist = templlist->next)
        {
-               debug_error("failed to autoplug for type (%s)", name);
-
-               __mmplayer_set_unlinked_mime_type(player, caps);
-       }
-
-       gst_caps_unref(caps);
+               padtemplate = templlist->data;
 
-       debug_fleave();
-       return;
-}
+               debug_log ("director = [%d], presence = [%d]\n", padtemplate->direction, padtemplate->presence);
 
-/* test API for tuning audio gain. this API should be
- * deprecated before the day of final release
- */
-int
-_mmplayer_set_volume_tune(MMHandleType hplayer, MMPlayerVolumeType volume)
-{
-       mm_player_t* player = (mm_player_t*) hplayer;
-       gint error = MM_ERROR_NONE;
-       gint vol_max = 0;
-       gboolean isMidi = FALSE;
-       gint i = 0;
+               if(     padtemplate->direction != GST_PAD_SRC ||
+                       padtemplate->presence == GST_PAD_REQUEST        )
+                       continue;
 
-       debug_fenter();
+               switch(padtemplate->presence)
+               {
+                       case GST_PAD_ALWAYS:
+                       {
+                               GstPad *srcpad = gst_element_get_static_pad(sinkelement, "src");
+#ifdef GST_API_VERSION_1
+                               GstCaps *caps = gst_pad_get_current_caps(srcpad);
+#else
+                               GstCaps *caps = gst_pad_get_caps(srcpad);
+#endif
 
-       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail( player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED )
+                               /* Check whether caps has many types */
+                               if ( gst_caps_get_size (caps) > 1 && g_strrstr(klass, "Parser")) {
+                                       debug_log ("has_many_types for this caps [%s]\n", gst_caps_to_string(caps));
+                                       has_many_types = TRUE;
+                                       break;
+                               }
 
-       debug_log("clip type=%d(1-midi, 0-others), volume [L]=%d:[R]=%d\n",
-               player->profile.play_mode, volume.level[0], volume.level[1]);
+                               if ( ! __mmplayer_try_to_plug(player, srcpad, caps) )
+                               {
+                                       gst_object_unref(GST_OBJECT(srcpad));
+                                       gst_caps_unref(GST_CAPS(caps));
 
-       isMidi = ( player->profile.play_mode == MM_PLAYER_MODE_MIDI ) ? TRUE : FALSE;
+                                       debug_error("failed to plug something after %s\n", GST_ELEMENT_NAME( sinkelement ));
+                                       goto ERROR;
+                               }
 
-       if ( isMidi )
-               vol_max = 1000;
-       else
-               vol_max = 100;
+                               gst_caps_unref(GST_CAPS(caps));
+                               gst_object_unref(GST_OBJECT(srcpad));
 
-       /* is it proper volume level? */
-       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; ++i)
-       {
-               if (volume.level[i] < 0 || volume.level[i] > vol_max) {
-                       debug_log("Invalid Volume level!!!! \n");
-                       return MM_ERROR_INVALID_ARGUMENT;
-               }
-       }
+                       }
+                       break;
 
-       if ( isMidi )
-       {
-               if ( player->pipeline->mainbin )
-               {
-                       GstElement *midi_element = player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst;
 
-                       if ( midi_element && ( strstr(GST_ELEMENT_NAME(midi_element), "midiparse")) )
-                       {
-                               debug_log("setting volume (%d) level to midi plugin\n", volume.level[0]);
+                       case GST_PAD_SOMETIMES:
+                               has_dynamic_pads = TRUE;
+                       break;
 
-                               g_object_set(midi_element, "volume", volume.level[0], NULL);
-                       }
+                       default:
+                               break;
                }
        }
-       else
-       {
-               if ( player->pipeline->audiobin )
-               {
-                       GstElement *sink_element = player->pipeline->audiobin[MMPLAYER_A_SINK].gst;
-
-                       /* Set to Avsysaudiosink element */
-                       if ( sink_element )
-                       {
-                               gint vol_value = 0;
-                               gboolean mute = FALSE;
-                               vol_value = volume.level[0];
-
-                               g_object_set(G_OBJECT(sink_element), "tuningvolume", vol_value, NULL);
 
-                               mute = (vol_value == 0)? TRUE:FALSE;
+       /* check if player can do start continually */
+       MMPLAYER_CHECK_CMD_IF_EXIT(player);
 
-                               g_object_set(G_OBJECT(sink_element), "mute", mute, NULL);
-                       }
+       if( has_dynamic_pads )
+       {
+               player->have_dynamic_pad = TRUE;
+               MMPLAYER_SIGNAL_CONNECT ( player, sinkelement, "pad-added",
+                       G_CALLBACK(__mmplayer_add_new_pad), player);
 
+               /* for streaming, more then one typefind will used for each elementary stream
+                * so this doesn't mean the whole pipeline completion
+                */
+               if ( ! MMPLAYER_IS_RTSP_STREAMING( player ) )
+               {
+                       MMPLAYER_SIGNAL_CONNECT( player, sinkelement, "no-more-pads",
+                               G_CALLBACK(__mmplayer_pipeline_complete), player);
                }
        }
 
-       debug_fleave();
-
-       return error;
-}
-
-gboolean
-__mmplayer_dump_pipeline_state( mm_player_t* player )
-{
-       GstIterator*iter = NULL;
-       gboolean done = FALSE;
-
-       GstElement *item = NULL;
-       GstElementFactory *factory = NULL;
+       if (has_many_types)
+       {
+               GstPad *pad = NULL;
 
-       GstState state = GST_STATE_VOID_PENDING;
-       GstState pending = GST_STATE_VOID_PENDING;
-       GstClockTime time = 200*GST_MSECOND;
+               player->has_many_types = has_many_types;
 
-       debug_fenter();
+               pad = gst_element_get_static_pad(sinkelement, "src");
+               MMPLAYER_SIGNAL_CONNECT (player, pad, "notify::caps", G_CALLBACK(__mmplayer_add_new_caps), player);
+               gst_object_unref (GST_OBJECT(pad));
+       }
 
-       return_val_if_fail ( player &&
-               player->pipeline &&
-               player->pipeline->mainbin,
-               FALSE );
 
-       iter = gst_bin_iterate_recurse(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst) );
+       /* check if player can do start continually */
+       MMPLAYER_CHECK_CMD_IF_EXIT(player);
 
-       if ( iter != NULL )
+       if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state(sinkelement, GST_STATE_PAUSED) )
        {
-               while (!done) {
-                        switch ( gst_iterator_next (iter, (gpointer)&item) )
-                        {
-                          case GST_ITERATOR_OK:
-                               gst_element_get_state(GST_ELEMENT (item),&state, &pending,time);
-
-                               factory = gst_element_get_factory (item) ;
-                               if (!factory)
-                               {
-                                        debug_error("%s:%s : From:%s To:%s   refcount : %d\n", GST_OBJECT_NAME(factory) , GST_ELEMENT_NAME(item) ,
-                                               gst_element_state_get_name(state), gst_element_state_get_name(pending) , GST_OBJECT_REFCOUNT_VALUE(item));
-                               }
-                                gst_object_unref (item);
-                                break;
-                          case GST_ITERATOR_RESYNC:
-                                gst_iterator_resync (iter);
-                                break;
-                          case GST_ITERATOR_ERROR:
-                                done = TRUE;
-                                break;
-                          case GST_ITERATOR_DONE:
-                                done = TRUE;
-                                break;
-                        }
-               }
+               debug_error("failed to set state PAUSED to %s\n", GST_ELEMENT_NAME( sinkelement ));
+               goto ERROR;
        }
 
-       item = GST_ELEMENT(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
-
-       gst_element_get_state(GST_ELEMENT (item),&state, &pending,time);
+       if ( queue )
+       {
+               if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state (queue, GST_STATE_PAUSED) )
+               {
+                       debug_error("failed to set state PAUSED to queue\n");
+                       goto ERROR;
+               }
 
-       factory = gst_element_get_factory (item) ;
+               queue = NULL;
 
-       if (!factory)
-       {
-               debug_error("%s:%s : From:%s To:%s  refcount : %d\n",
-                       GST_OBJECT_NAME(factory),
-                       GST_ELEMENT_NAME(item),
-                       gst_element_state_get_name(state),
-                       gst_element_state_get_name(pending),
-                       GST_OBJECT_REFCOUNT_VALUE(item) );
+               gst_object_unref (GST_OBJECT(qsrcpad));
+               qsrcpad = NULL;
        }
 
-       if ( iter )
-               gst_iterator_free (iter);
-
-       debug_fleave();
+       if ( parser )
+       {
+               if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state (parser, GST_STATE_PAUSED) )
+               {
+                       debug_error("failed to set state PAUSED to queue\n");
+                       goto ERROR;
+               }
 
-       return FALSE;
-}
+               parser = NULL;
 
+               gst_object_unref (GST_OBJECT(pssrcpad));
+               pssrcpad = NULL;
+       }
 
-gboolean
-__mmplayer_check_subtitle( mm_player_t* player )
-{
-       MMHandleType attrs = 0;
-       char *subtitle_uri = NULL;
+       debug_fleave();
 
-       debug_fenter();
+       return TRUE;
 
-       return_val_if_fail( player, FALSE );
+ERROR:
 
-       /* get subtitle attribute */
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
-               return FALSE;
+       if ( queue )
+       {
+               gst_object_unref(GST_OBJECT(qsrcpad));
 
-       mm_attrs_get_string_by_name(attrs, "subtitle_uri", &subtitle_uri);
-       if ( !subtitle_uri || !strlen(subtitle_uri))
-               return FALSE;
+               /* 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
+                * dropping the final reference, to allow them to clean up.
+                */
+               gst_element_set_state(queue, GST_STATE_NULL);
+               /* And, it still has a parent "player".
+                * You need to let the parent manage the object instead of unreffing the object directly.
+                */
 
-       debug_log ("subtite uri is %s[%d]\n", subtitle_uri, strlen(subtitle_uri));
+               gst_bin_remove (GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), queue);
+               //gst_object_unref( queue );
+       }
 
-       debug_fleave();
+       if ( srccaps )
+               gst_caps_unref(GST_CAPS(srccaps));
 
-       return TRUE;
+    return FALSE;
 }
 
-static gboolean
-__mmplayer_can_extract_pcm( mm_player_t* player )
+static gboolean __mmplayer_feature_filter(GstPluginFeature *feature, gpointer data) // @
 {
-       MMHandleType attrs = 0;
-       gboolean is_drm = FALSE;
-       gboolean sound_extraction = FALSE;
-
-       return_val_if_fail ( player, FALSE );
+       const gchar *klass;
+       //const gchar *name;
 
-       attrs = MMPLAYER_GET_ATTRS(player);
-       if ( !attrs )
-       {
-               debug_error("fail to get attributes.");
+       /* we only care about element factories */
+       if (!GST_IS_ELEMENT_FACTORY(feature))
                return FALSE;
-       }
-
-       /* check file is drm or not */
-       g_object_get(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "is-drm", &is_drm, NULL);
 
-       /* get sound_extraction property */
-       mm_attrs_get_int_by_name(attrs, "pcm_extraction", &sound_extraction);
+       /* only parsers, demuxers and decoders */
+       klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(feature));
+       //name = gst_element_factory_get_longname(GST_ELEMENT_FACTORY(feature));
 
-       if ( ! sound_extraction || is_drm )
+       if( g_strrstr(klass, "Demux") == NULL &&
+               g_strrstr(klass, "Codec/Decoder") == NULL &&
+               g_strrstr(klass, "Depayloader") == NULL &&
+               g_strrstr(klass, "Parse") == NULL)
        {
-               debug_log("checking pcm extraction mode : %d, drm : %d", sound_extraction, is_drm);
                return FALSE;
        }
-
-       return TRUE;
+    return TRUE;
 }
 
-static gboolean
-__mmplayer_handle_gst_error ( mm_player_t* player, GstMessage * message, GError* error )
+
+static void    __mmplayer_add_new_caps(GstPad* pad, GParamSpec* unused, gpointer data)
 {
-       MMMessageParamType msg_param;
-       gchar *msg_src_element;
+       mm_player_t* player = (mm_player_t*) data;
+       GstCaps *caps = NULL;
+       GstStructure *str = NULL;
+       const char *name;
 
        debug_fenter();
 
-       return_val_if_fail( player, FALSE );
-       return_val_if_fail( error, FALSE );
-
-       /* NOTE : do somthing necessary inside of __gst_handle_XXX_error. not here */
+       return_if_fail ( pad )
+       return_if_fail ( unused )
+       return_if_fail ( data )
 
-       memset (&msg_param, 0, sizeof(MMMessageParamType));
+#ifdef GST_API_VERSION_1
+       caps = gst_pad_get_current_caps(pad);
+#else
+       caps = gst_pad_get_caps(pad);
+#endif
+       if ( !caps )
+               return;
 
-       if ( error->domain == GST_CORE_ERROR )
-       {
-               msg_param.code = __gst_handle_core_error( player, error->code );
-       }
-       else if ( error->domain == GST_LIBRARY_ERROR )
-       {
-               msg_param.code = __gst_handle_library_error( player, error->code );
-       }
-       else if ( error->domain == GST_RESOURCE_ERROR )
-       {
-               msg_param.code = __gst_handle_resource_error( player, error->code );
-       }
-       else if ( error->domain == GST_STREAM_ERROR )
-       {
-               msg_param.code = __gst_handle_stream_error( player, error, message );
-       }
-       else
-       {
-               debug_warning("This error domain is not defined.\n");
+       str = gst_caps_get_structure(caps, 0);
+       if ( !str )
+               return;
 
-               /* we treat system error as an internal error */
-               msg_param.code = MM_ERROR_PLAYER_INVALID_STREAM;
-       }
+       name = gst_structure_get_name(str);
+       if ( !name )
+               return;
+       debug_log("name=%s\n", name);
 
-       if ( message->src )
+       if ( ! __mmplayer_try_to_plug(player, pad, caps) )
        {
-               msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( message->src ) );
-
-               msg_param.data = (void *) error->message;
-
-               debug_error("-Msg src : [%s]    Domain : [%s]   Error : [%s]  Code : [%d] is tranlated to error code : [0x%x]\n",
-                       msg_src_element, g_quark_to_string (error->domain), error->message, error->code, msg_param.code);
+               debug_error("failed to autoplug for type (%s)\n", name);
+               gst_caps_unref(caps);
+               return;
        }
 
-       /* 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
-       {
-               debug_log("skip error post because it's sent already.\n");
-       }
+       gst_caps_unref(caps);
+
+       __mmplayer_pipeline_complete( NULL, (gpointer)player );
 
        debug_fleave();
 
-       return TRUE;
+       return;
 }
 
-static gboolean
-__mmplayer_handle_streaming_error  ( mm_player_t* player, GstMessage * message )
+static void __mmplayer_set_unlinked_mime_type(mm_player_t* player, GstCaps *caps)
 {
-       debug_log("\n");
-       MMMessageParamType msg_param;
-       gchar *msg_src_element = NULL;
-       GstStructure *s = NULL;
-       guint error_id = 0;
-       gchar *error_string = NULL;
+       GstStructure *str;
+       gint version = 0;
+       const char *stream_type;
+       gchar *version_field = NULL;
 
        debug_fenter();
 
-       return_val_if_fail ( player, FALSE );
-       return_val_if_fail ( message, FALSE );
-
-       s = malloc( sizeof(GstStructure) );
-       memcpy ( s, gst_message_get_structure ( message ), sizeof(GstStructure));
+       return_if_fail ( player );
+       return_if_fail ( caps );
 
-       if ( !gst_structure_get_uint (s, "error_id", &error_id) )
-               error_id = MMPLAYER_STREAMING_ERROR_NONE;
+       str = gst_caps_get_structure(caps, 0);
+       if ( !str )
+               return;
 
-       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:
-                       return MM_ERROR_PLAYER_STREAMING_FAIL;
-       }
+       stream_type = gst_structure_get_name(str);
+       if ( !stream_type )
+               return;
 
-       error_string = g_strdup(gst_structure_get_string (s, "error_string"));
-       if ( error_string )
-               msg_param.data = (void *) error_string;
 
-       if ( message->src )
+       /* set unlinked mime type for downloadable codec */
+       if (g_str_has_prefix(stream_type, "video/"))
        {
-               msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( message->src ) );
+               if (g_str_has_prefix(stream_type, "video/mpeg"))
+               {
+                       gst_structure_get_int (str, MM_PLAYER_MPEG_VNAME, &version);
+                       version_field = MM_PLAYER_MPEG_VNAME;
+               }
+               else if (g_str_has_prefix(stream_type, "video/x-wmv"))
+               {
+                       gst_structure_get_int (str, MM_PLAYER_WMV_VNAME, &version);
+                       version_field = MM_PLAYER_WMV_VNAME;
+
+               }
+               else if (g_str_has_prefix(stream_type, "video/x-divx"))
+               {
+                       gst_structure_get_int (str, MM_PLAYER_DIVX_VNAME, &version);
+                       version_field = MM_PLAYER_DIVX_VNAME;
+               }
 
-               debug_error("-Msg src : [%s] Code : [%x] Error : [%s]  \n",
-                       msg_src_element, msg_param.code, (char*)msg_param.data );
+               if (version)
+               {
+                       player->unlinked_video_mime = g_strdup_printf("%s, %s=%d", stream_type, version_field, version);
+               }
+               else
+               {
+                       player->unlinked_video_mime = g_strdup_printf("%s", stream_type);
+               }
        }
-
-       /* post error to application */
-       if ( ! player->msg_posted )
+       else if (g_str_has_prefix(stream_type, "audio/"))
        {
-               MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+               if (g_str_has_prefix(stream_type, "audio/mpeg")) // mp3 or aac
+               {
+                       gst_structure_get_int (str, MM_PLAYER_MPEG_VNAME, &version);
+                       version_field = MM_PLAYER_MPEG_VNAME;
+               }
+               else if (g_str_has_prefix(stream_type, "audio/x-wma"))
+               {
+                       gst_structure_get_int (str, MM_PLAYER_WMA_VNAME, &version);
+                       version_field = MM_PLAYER_WMA_VNAME;
+               }
 
-               /* don't post more if one was sent already */
-               player->msg_posted = TRUE;
-       }
-       else
-       {
-               debug_log("skip error post because it's sent already.\n");
+               if (version)
+               {
+                       player->unlinked_audio_mime = g_strdup_printf("%s, %s=%d", stream_type, version_field, version);
+               }
+               else
+               {
+                       player->unlinked_audio_mime = g_strdup_printf("%s", stream_type);
+               }
        }
 
        debug_fleave();
-
-       return TRUE;
-
 }
 
-static gint
-__gst_handle_core_error( mm_player_t* player, int code )
+static void __mmplayer_add_new_pad(GstElement *element, GstPad *pad, gpointer data)
 {
-       gint trans_err = MM_ERROR_NONE;
+       mm_player_t* player = (mm_player_t*) data;
+       GstCaps *caps = NULL;
+       GstStructure *str = NULL;
+       const char *name;
 
        debug_fenter();
+       return_if_fail ( player );
+       return_if_fail ( pad );
 
-       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       GST_OBJECT_LOCK (pad);
+#ifdef GST_API_VERSION_1
+       if ((caps = gst_pad_get_current_caps (pad)))
+               gst_caps_ref(caps);
+#else
+       if ((caps = GST_PAD_CAPS(pad)))
+               gst_caps_ref(caps);
+#endif
+       GST_OBJECT_UNLOCK (pad);
 
-       switch ( code )
-       {
-               case GST_CORE_ERROR_STATE_CHANGE:
-               case GST_CORE_ERROR_MISSING_PLUGIN:
-               case GST_CORE_ERROR_SEEK:
-               case GST_CORE_ERROR_NOT_IMPLEMENTED:
-               case GST_CORE_ERROR_FAILED:
-               case GST_CORE_ERROR_TOO_LAZY:
-               case GST_CORE_ERROR_PAD:
-               case GST_CORE_ERROR_THREAD:
-               case GST_CORE_ERROR_NEGOTIATION:
-               case GST_CORE_ERROR_EVENT:
-               case GST_CORE_ERROR_CAPS:
-               case GST_CORE_ERROR_TAG:
-               case GST_CORE_ERROR_CLOCK:
-               case GST_CORE_ERROR_DISABLED:
-               default:
-                       trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
-               break;
+       if ( NULL == caps )
+       {
+#ifdef GST_API_VERSION_1
+               caps = gst_pad_get_current_caps(pad);
+#else
+               caps = gst_pad_get_caps(pad);
+#endif
+               if ( !caps ) return;
        }
 
-       debug_fleave();
-
-       return trans_err;
-}
+       //MMPLAYER_LOG_GST_CAPS_TYPE(caps);
 
-static gint
-__gst_handle_library_error( mm_player_t* player, int code )
-{
-       gint trans_err = MM_ERROR_NONE;
+       str = gst_caps_get_structure(caps, 0);
+       if ( !str )
+               return;
 
-       debug_fenter();
+       name = gst_structure_get_name(str);
+       if ( !name )
+               return;
 
-       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       player->num_dynamic_pad++;
+       debug_log("stream count inc : %d\n", player->num_dynamic_pad);
 
-       switch ( code )
+       /* Note : If the stream is the subtitle, we try not to play it. Just close the demuxer subtitle pad.
+         *     If want to play it, remove this code.
+         */
+       if (g_strrstr(name, "application"))
        {
-               case GST_LIBRARY_ERROR_FAILED:
-               case GST_LIBRARY_ERROR_TOO_LAZY:
-               case GST_LIBRARY_ERROR_INIT:
-               case GST_LIBRARY_ERROR_SHUTDOWN:
-               case GST_LIBRARY_ERROR_SETTINGS:
-               case GST_LIBRARY_ERROR_ENCODE:
-               default:
-                       trans_err =  MM_ERROR_PLAYER_INVALID_STREAM;
-               break;
+               if (g_strrstr(name, "x-id3") || g_strrstr(name, "x-apetag"))
+               {
+                       /* If id3/ape tag comes, keep going */
+                       debug_log("application mime exception : id3/ape tag");
+               }
+               else
+               {
+                       /* Otherwise, we assume that this stream is subtile. */
+                       debug_log(" application mime type pad is closed.");
+                       return;
+               }
        }
+       else if (g_strrstr(name, "audio"))
+       {
+               gint samplerate = 0, channels = 0;
 
-       debug_fleave();
-
-       return trans_err;
-}
+               /* set stream information */
+               /* if possible, set it here because the caps is not distrubed by resampler. */
+               gst_structure_get_int (str, "rate", &samplerate);
+               mm_attrs_set_int_by_name(player->attrs, "content_audio_samplerate", samplerate);
 
+               gst_structure_get_int (str, "channels", &channels);
+               mm_attrs_set_int_by_name(player->attrs, "content_audio_channels", channels);
 
-static gint
-__gst_handle_resource_error( mm_player_t* player, int code )
-{
-       gint trans_err = MM_ERROR_NONE;
+               debug_log("audio samplerate : %d        channels : %d", samplerate, channels);
+       }
+       else if (g_strrstr(name, "video"))
+       {
+               gint stype;
+               mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &stype);
 
-       debug_fenter();
+               /* don't make video because of not required */
+               if (stype == MM_DISPLAY_SURFACE_NULL)
+               {
+                       debug_log("no video because it's not required");
+                       return;
+               }
 
-       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+               player->v_stream_caps = gst_caps_copy(caps); //if needed, video caps is required when videobin is created
+       }
 
-       switch ( code )
+       if ( ! __mmplayer_try_to_plug(player, pad, caps) )
        {
-               case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
-                       trans_err = MM_ERROR_PLAYER_NO_FREE_SPACE;
-                       break;
-               case GST_RESOURCE_ERROR_NOT_FOUND:
-               case GST_RESOURCE_ERROR_OPEN_READ:
-                       if ( MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_HTTP_LIVE_STREAMING ( player )
-                               || MMPLAYER_IS_RTSP_STREAMING(player))
-                       {
-                               trans_err = MM_ERROR_PLAYER_STREAMING_CONNECTION_FAIL;
-                               break;
-                       }
-               case GST_RESOURCE_ERROR_READ:
-                       if ( MMPLAYER_IS_HTTP_STREAMING(player) ||  MMPLAYER_IS_HTTP_LIVE_STREAMING ( player )
-                               || MMPLAYER_IS_RTSP_STREAMING(player))
-                       {
-                               trans_err = MM_ERROR_PLAYER_STREAMING_FAIL;
-                               break;
-                       }
-               case GST_RESOURCE_ERROR_WRITE:
-               case GST_RESOURCE_ERROR_FAILED:
-                       trans_err = MM_ERROR_PLAYER_INTERNAL;
-                       break;
+               debug_error("failed to autoplug for type (%s)", name);
 
-               case GST_RESOURCE_ERROR_SEEK:
-               case GST_RESOURCE_ERROR_TOO_LAZY:
-               case GST_RESOURCE_ERROR_BUSY:
-               case GST_RESOURCE_ERROR_OPEN_WRITE:
-               case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
-               case GST_RESOURCE_ERROR_CLOSE:
-               case GST_RESOURCE_ERROR_SYNC:
-               case GST_RESOURCE_ERROR_SETTINGS:
-               default:
-                       trans_err = MM_ERROR_PLAYER_FILE_NOT_FOUND;
-               break;
+               __mmplayer_set_unlinked_mime_type(player, caps);
        }
 
-       debug_fleave();
-
-       return trans_err;
-}
-
-
-static gint
-__gst_handle_stream_error( mm_player_t* player, GError* error, GstMessage * message )
-{
-       gint trans_err = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
-       return_val_if_fail( error, MM_ERROR_INVALID_ARGUMENT );
-       return_val_if_fail ( message, MM_ERROR_INVALID_ARGUMENT );
-
-       switch ( error->code )
-       {
-               case GST_STREAM_ERROR_FAILED:
-               case GST_STREAM_ERROR_TYPE_NOT_FOUND:
-               case GST_STREAM_ERROR_DECODE:
-               case GST_STREAM_ERROR_WRONG_TYPE:
-               case GST_STREAM_ERROR_DECRYPT:
-               case GST_STREAM_ERROR_DECRYPT_NOKEY:
-                        trans_err = __gst_transform_gsterror( player, message, error );
-               break;
-
-               case GST_STREAM_ERROR_CODEC_NOT_FOUND:
-               case GST_STREAM_ERROR_NOT_IMPLEMENTED:
-               case GST_STREAM_ERROR_TOO_LAZY:
-               case GST_STREAM_ERROR_ENCODE:
-               case GST_STREAM_ERROR_DEMUX:
-               case GST_STREAM_ERROR_MUX:
-               case GST_STREAM_ERROR_FORMAT:
-               default:
-                       trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
-               break;
-       }
+       gst_caps_unref(caps);
 
        debug_fleave();
-
-       return trans_err;
+       return;
 }
 
-/* NOTE : decide gstreamer state whether there is some playable track or not. */
-static gint
-__gst_transform_gsterror( mm_player_t* player, GstMessage * message, GError* error )
+/* test API for tuning audio gain. this API should be
+ * deprecated before the day of final release
+ */
+int
+_mmplayer_set_volume_tune(MMHandleType hplayer, MMPlayerVolumeType volume)
 {
-       gchar *src_element_name = NULL;
-       GstElement *src_element = NULL;
-       GstElementFactory *factory = NULL;
-       const gchar* klass = NULL;
+       mm_player_t* player = (mm_player_t*) hplayer;
+       gint error = MM_ERROR_NONE;
+       gint vol_max = 0;
+       gboolean isMidi = FALSE;
+       gint i = 0;
 
        debug_fenter();
 
-       /* FIXIT */
-       return_val_if_fail ( message, MM_ERROR_INVALID_ARGUMENT );
-       return_val_if_fail ( message->src, MM_ERROR_INVALID_ARGUMENT );
-       return_val_if_fail ( error, MM_ERROR_INVALID_ARGUMENT );
-
-       src_element = GST_ELEMENT_CAST(message->src);
-       if ( !src_element )
-               goto INTERNAL_ERROR;
-
-       src_element_name = GST_ELEMENT_NAME(src_element);
-       if ( !src_element_name )
-               goto INTERNAL_ERROR;
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail( player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED )
 
-       factory = gst_element_get_factory(src_element);
-       if ( !factory )
-               goto INTERNAL_ERROR;
+       debug_log("clip type=%d(1-midi, 0-others), volume [L]=%d:[R]=%d\n",
+               player->profile.play_mode, volume.level[0], volume.level[1]);
 
-       klass = gst_element_factory_get_klass(factory);
-       if ( !klass )
-               goto INTERNAL_ERROR;
+       isMidi = ( player->profile.play_mode == MM_PLAYER_MODE_MIDI ) ? TRUE : FALSE;
 
-       debug_log("error code=%d, msg=%s, src element=%s, class=%s\n",
-                       error->code, error->message, src_element_name, klass);
+       if ( isMidi )
+               vol_max = 1000;
+       else
+               vol_max = 100;
 
-       switch ( error->code )
+       /* is it proper volume level? */
+       for (i = 0; i < MM_VOLUME_CHANNEL_NUM; ++i)
        {
-               case GST_STREAM_ERROR_DECODE:
-               {
-                       /* Demuxer can't parse one track because it's corrupted.
-                        * So, the decoder for it is not linked.
-                        * But, it has one playable track.
-                        */
-                       if ( g_strrstr(klass, "Demux") )
-                       {
-                               if ( player->can_support_codec == FOUND_PLUGIN_VIDEO )
-                               {
-                                       return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
-                               }
-                               else if ( player->can_support_codec == FOUND_PLUGIN_AUDIO )
-                               {
-                                       return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
-                               }
-                               else
-                               {
-                                       if ( player->pipeline->audiobin ) // PCM
-                                       {
-                                               return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
-                                       }
-                                       else
-                                       {
-                                               goto CODEC_NOT_FOUND;
-                                       }
-                               }
-                       }
-                       return MM_ERROR_PLAYER_INVALID_STREAM;
+               if (volume.level[i] < 0 || volume.level[i] > vol_max) {
+                       debug_log("Invalid Volume level!!!! \n");
+                       return MM_ERROR_INVALID_ARGUMENT;
                }
-               break;
+       }
 
-               case GST_STREAM_ERROR_WRONG_TYPE:
+       if ( isMidi )
+       {
+               if ( player->pipeline->mainbin )
                {
-                       return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
-               }
-               break;
+                       GstElement *midi_element = player->pipeline->mainbin[MMPLAYER_M_DEMUX].gst;
 
-               case GST_STREAM_ERROR_FAILED:
-               {
-                       /* Decoder Custom Message */
-                       if ( strstr(error->message, "ongoing") )
+                       if ( midi_element && ( strstr(GST_ELEMENT_NAME(midi_element), "midiparse")) )
                        {
-                               if ( strncasecmp(klass, "audio", 5) )
-                               {
-                                       if ( ( player->can_support_codec & FOUND_PLUGIN_VIDEO ) )
-                                       {
-                                               debug_log("Video can keep playing.\n");
-                                               return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
-                                       }
-                                       else
-                                       {
-                                               goto CODEC_NOT_FOUND;
-                                       }
+                               debug_log("setting volume (%d) level to midi plugin\n", volume.level[0]);
 
-                               }
-                               else if ( strncasecmp(klass, "video", 5) )
-                               {
-                                       if ( ( player->can_support_codec & FOUND_PLUGIN_AUDIO ) )
-                                       {
-                                               debug_log("Audio can keep playing.\n");
-                                               return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
-                                       }
-                                       else
-                                       {
-                                               goto CODEC_NOT_FOUND;
-                                       }
-                               }
+                               g_object_set(midi_element, "volume", volume.level[0], NULL);
                        }
-                       return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
                }
-               break;
-
-               case GST_STREAM_ERROR_TYPE_NOT_FOUND:
-                       return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
-               break;
-
-               case GST_STREAM_ERROR_DECRYPT:
-               case GST_STREAM_ERROR_DECRYPT_NOKEY:
+       }
+       else
+       {
+               if ( player->pipeline->audiobin )
                {
-                       debug_error("decryption error, [%s] failed, reason : [%s]\n", src_element_name, error->message);
+                       GstElement *sink_element = player->pipeline->audiobin[MMPLAYER_A_SINK].gst;
 
-                       if ( strstr(error->message, "rights expired") )
-                       {
-                               return MM_ERROR_PLAYER_DRM_EXPIRED;
-                       }
-                       else if ( strstr(error->message, "no rights") )
-                       {
-                               return MM_ERROR_PLAYER_DRM_NO_LICENSE;
-                       }
-                       else if ( strstr(error->message, "has future rights") )
-                       {
-                               return MM_ERROR_PLAYER_DRM_FUTURE_USE;
-                       }
-                       else if ( strstr(error->message, "opl violation") )
+                       /* Set to Avsysaudiosink element */
+                       if ( sink_element )
                        {
-                               return MM_ERROR_PLAYER_DRM_OUTPUT_PROTECTION;
-                       }
-                       return MM_ERROR_PLAYER_DRM_NOT_AUTHORIZED;
-               }
-               break;
+                               gint vol_value = 0;
+                               gboolean mute = FALSE;
+                               vol_value = volume.level[0];
+
+                               g_object_set(G_OBJECT(sink_element), "tuningvolume", vol_value, NULL);
+
+                               mute = (vol_value == 0)? TRUE:FALSE;
+
+                               g_object_set(G_OBJECT(sink_element), "mute", mute, NULL);
+                       }
 
-               default:
-               break;
+               }
        }
 
        debug_fleave();
 
-       return MM_ERROR_PLAYER_INVALID_STREAM;
-
-INTERNAL_ERROR:
-       return MM_ERROR_PLAYER_INTERNAL;
-
-CODEC_NOT_FOUND:
-       debug_log("not found any available codec. Player should be destroyed.\n");
-       return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
+       return error;
 }
 
-static void
-__mmplayer_post_delayed_eos( mm_player_t* player, int delay_in_ms )
+static gboolean
+__mmplayer_can_extract_pcm( mm_player_t* player )
 {
-       debug_fenter();
-
-       return_if_fail( player );
-
-       /* cancel if existing */
-       __mmplayer_cancel_delayed_eos( player );
+       MMHandleType attrs = 0;
+       gboolean is_drm = FALSE;
+       gboolean sound_extraction = FALSE;
 
+       return_val_if_fail ( player, FALSE );
 
-       /* post now if delay is zero */
-       if ( delay_in_ms == 0 || player->is_sound_extraction)
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
        {
-               debug_log("eos delay is zero. posting EOS now\n");
-               MMPLAYER_POST_MSG( player, MM_MESSAGE_END_OF_STREAM, NULL );
-
-               if ( player->is_sound_extraction )
-                       __mmplayer_cancel_delayed_eos(player);
-
-               return;
+               debug_error("fail to get attributes.");
+               return FALSE;
        }
 
-       /* init new timeout */
-       /* NOTE : consider give high priority to this timer */
-
-       debug_log("posting EOS message after [%d] msec\n", delay_in_ms);
-       player->eos_timer = g_timeout_add( delay_in_ms,
-               __mmplayer_eos_timer_cb, player );
+       /* check file is drm or not */
+       g_object_get(G_OBJECT(player->pipeline->mainbin[MMPLAYER_M_SRC].gst), "is-drm", &is_drm, NULL);
 
+       /* get sound_extraction property */
+       mm_attrs_get_int_by_name(attrs, "pcm_extraction", &sound_extraction);
 
-       /* check timer is valid. if not, send EOS now */
-       if ( player->eos_timer == 0 )
+       if ( ! sound_extraction || is_drm )
        {
-               debug_warning("creating timer for delayed EOS has failed. sending EOS now\n");
-               MMPLAYER_POST_MSG( player, MM_MESSAGE_END_OF_STREAM, NULL );
+               debug_log("checking pcm extraction mode : %d, drm : %d", sound_extraction, is_drm);
+               return FALSE;
        }
 
-       debug_fleave();
+       return TRUE;
 }
 
 static void
@@ -10371,7 +5527,7 @@ __mmplayer_cancel_delayed_eos( mm_player_t* player )
        return;
 }
 
-static gboolean
+gboolean
 __mmplayer_eos_timer_cb(gpointer u_data)
 {
        mm_player_t* player = NULL;
@@ -10434,313 +5590,6 @@ static void __mmplayer_set_antishock( mm_player_t* player, gboolean disable_by_f
        return;
 }
 
-
-static gboolean
-__mmplayer_link_decoder( mm_player_t* player, GstPad *srcpad)
-{
-       const gchar* name = NULL;
-       GstStructure* str = NULL;
-       GstCaps* srccaps = NULL;
-
-       debug_fenter();
-
-       return_val_if_fail( player, FALSE );
-       return_val_if_fail ( srcpad, FALSE );
-
-       /* to check any of the decoder (video/audio) need to be linked  to parser*/
-#ifdef GST_API_VERSION_1
-       srccaps = gst_pad_get_current_caps( srcpad );
-#else
-       srccaps = gst_pad_get_caps( srcpad );
-#endif
-       if ( !srccaps )
-               goto ERROR;
-
-       str = gst_caps_get_structure( srccaps, 0 );
-       if ( ! str )
-               goto ERROR;
-
-       name = gst_structure_get_name(str);
-       if ( ! name )
-               goto ERROR;
-
-       if (strstr(name, "video"))
-       {
-               if(player->videodec_linked)
-               {
-                   debug_msg("Video decoder already linked\n");
-                       return FALSE;
-               }
-       }
-       if (strstr(name, "audio"))
-       {
-               if(player->audiodec_linked)
-               {
-                   debug_msg("Audio decoder already linked\n");
-                       return FALSE;
-               }
-       }
-
-       gst_caps_unref( srccaps );
-
-       debug_fleave();
-
-       return TRUE;
-
-ERROR:
-       if ( srccaps )
-               gst_caps_unref( srccaps );
-
-       return FALSE;
-}
-
-static gboolean
-__mmplayer_link_sink( mm_player_t* player , GstPad *srcpad)
-{
-       const gchar* name = NULL;
-       GstStructure* str = NULL;
-       GstCaps* srccaps = NULL;
-
-       debug_fenter();
-
-       return_val_if_fail ( player, FALSE );
-       return_val_if_fail ( srcpad, FALSE );
-
-       /* to check any of the decoder (video/audio) need to be linked  to parser*/
-#ifdef GST_API_VERSION_1
-       srccaps = gst_pad_get_current_caps( srcpad );
-#else
-       srccaps = gst_pad_get_caps( srcpad );
-#endif
-       if ( !srccaps )
-               goto ERROR;
-
-       str = gst_caps_get_structure( srccaps, 0 );
-       if ( ! str )
-               goto ERROR;
-
-       name = gst_structure_get_name(str);
-       if ( ! name )
-               goto ERROR;
-
-       if (strstr(name, "video"))
-       {
-               if(player->videosink_linked)
-               {
-                       debug_msg("Video Sink already linked\n");
-                       return FALSE;
-               }
-       }
-       if (strstr(name, "audio"))
-       {
-               if(player->audiosink_linked)
-               {
-                       debug_msg("Audio Sink already linked\n");
-                       return FALSE;
-               }
-       }
-       if (strstr(name, "text"))
-       {
-               if(player->textsink_linked)
-               {
-                       debug_msg("Text Sink already linked\n");
-                       return FALSE;
-               }
-       }
-
-       gst_caps_unref( srccaps );
-
-       debug_fleave();
-
-       return TRUE;
-       //return (!player->videosink_linked || !player->audiosink_linked);
-
-ERROR:
-       if ( srccaps )
-               gst_caps_unref( srccaps );
-
-       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;
-
-       debug_fenter();
-
-       return_val_if_fail( player, FALSE );
-       return_val_if_fail ( event, FALSE );
-
-       if ( player->play_subtitle && !player->use_textoverlay)
-               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)) )
-                       {
-                               debug_log("sending event[%s] to sink element [%s] success!\n",
-                                       GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(sink) );
-                               break;
-                       }
-
-                       debug_log("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->use_textoverlay)
-        {
-               GstElement *text_sink = GST_ELEMENT_CAST (player->pipeline->textbin[MMPLAYER_T_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)) )
-                       {
-                               debug_error("sending event[%s] to subtitle sink element [%s] failed!\n",
-                                       GST_EVENT_TYPE_NAME(event2), GST_ELEMENT_NAME(text_sink) );
-                       }
-                       else
-                       {
-                               debug_log("sending event[%s] to subtitle sink element [%s] success!\n",
-                                       GST_EVENT_TYPE_NAME(event2), GST_ELEMENT_NAME(text_sink) );
-                       }
-
-                       gst_event_unref (event2);
-               }
-        }
-
-       gst_event_unref (event);
-
-       debug_fleave();
-
-       return res;
-}
-
-static void
-__mmplayer_add_sink( mm_player_t* player, GstElement* sink )
-{
-       debug_fenter();
-
-       return_if_fail ( player );
-       return_if_fail ( sink );
-
-       player->sink_elements =
-               g_list_append(player->sink_elements, sink);
-
-       debug_fleave();
-}
-
-static void
-__mmplayer_del_sink( mm_player_t* player, GstElement* sink )
-{
-       debug_fenter();
-
-       return_if_fail ( player );
-       return_if_fail ( sink );
-
-       player->sink_elements =
-                       g_list_remove(player->sink_elements, sink);
-
-       debug_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 )
-{
-       GstEvent* event = NULL;
-       gboolean result = FALSE;
-
-       debug_fenter();
-
-       return_val_if_fail( player, FALSE );
-
-       event = gst_event_new_seek (rate, format, flags, cur_type,
-               cur, stop_type, stop);
-
-       result = __gst_send_event_to_sink( player, event );
-
-       debug_fleave();
-
-       return result;
-}
-
-/* NOTE : be careful with calling this api. please refer to below glib comment
- * glib comment : Note that there is a bug in GObject that makes this function much
- * less useful than it might seem otherwise. Once gobject is disposed, the callback
- * will no longer be called, but, the signal handler is not currently disconnected.
- * If the instance is itself being freed at the same time than this doesn't matter,
- * since the signal will automatically be removed, but if instance persists,
- * then the signal handler will leak. You should not remove the signal yourself
- * because in a future versions of GObject, the handler will automatically be
- * disconnected.
- *
- * It's possible to work around this problem in a way that will continue to work
- * with future versions of GObject by checking that the signal handler is still
- * connected before disconnected it:
- *
- *  if (g_signal_handler_is_connected (instance, id))
- *    g_signal_handler_disconnect (instance, id);
- */
-static void
-__mmplayer_release_signal_connection(mm_player_t* player)
-{
-       GList* sig_list = player->signals;
-       MMPlayerSignalItem* item = NULL;
-
-       debug_fenter();
-
-       return_if_fail( player );
-
-       for ( ; sig_list; sig_list = sig_list->next )
-       {
-               item = sig_list->data;
-
-               if ( item && item->obj && GST_IS_ELEMENT(item->obj) )
-               {
-                       debug_log("checking signal connection : [%lud] from [%s]\n", item->sig, GST_OBJECT_NAME( item->obj ));
-
-                       if ( g_signal_handler_is_connected ( item->obj, item->sig ) )
-                       {
-                               debug_log("signal disconnecting : [%lud] from [%s]\n", item->sig, GST_OBJECT_NAME( item->obj ));
-                               g_signal_handler_disconnect ( item->obj, item->sig );
-                       }
-               }
-
-               MMPLAYER_FREEIF( item );
-
-       }
-       g_list_free ( player->signals );
-       player->signals = NULL;
-
-       debug_fleave();
-
-       return;
-}
-
-
 /* Note : if silent is true, then subtitle would not be displayed. :*/
 int _mmplayer_set_subtitle_silent (MMHandleType hplayer, int silent)
 {
@@ -10824,7 +5673,6 @@ int _mmplayer_get_track_count(MMHandleType hplayer,  MMPlayerTrackType track_typ
        return ret;
 }
 
-
 const gchar *
 __get_state_name ( int state )
 {
@@ -10845,50 +5693,3 @@ __get_state_name ( int state )
        }
 }
 
-gboolean
-__is_rtsp_streaming ( mm_player_t* player )
-{
-       return_val_if_fail ( player, FALSE );
-
-       return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_RTSP ) ? TRUE : FALSE;
-}
-
-static gboolean
-__is_http_streaming ( mm_player_t* player )
-{
-       return_val_if_fail ( player, FALSE );
-
-       return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_HTTP ) ? TRUE : FALSE;
-}
-
-static gboolean
-__is_streaming ( mm_player_t* player )
-{
-       return_val_if_fail ( player, FALSE );
-
-       return ( __is_rtsp_streaming ( player ) || __is_http_streaming ( player ) || __is_http_live_streaming ( player )) ? TRUE : FALSE;
-}
-
-gboolean
-__is_live_streaming ( mm_player_t* player )
-{
-       return_val_if_fail ( player, FALSE );
-
-       return ( __is_rtsp_streaming ( player ) && player->streaming_type == STREAMING_SERVICE_LIVE ) ? TRUE : FALSE;
-}
-
-static gboolean
-__is_http_live_streaming( mm_player_t* player )
-{
-       return_val_if_fail( player, FALSE );
-
-       return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS ) ? TRUE : FALSE;
-}
-
-static gboolean
-__is_http_progressive_down(mm_player_t* player)
-{
-       return_val_if_fail( player, FALSE );
-
-       return ((player->pd_mode) ? TRUE:FALSE);
-}
diff --git a/src/mm_player_priv_gst.c b/src/mm_player_priv_gst.c
new file mode 100755 (executable)
index 0000000..8f4fe65
--- /dev/null
@@ -0,0 +1,1145 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, Heechul Jeon <heechul.jeon@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  INCLUDE FILES                                                                                                                                                       |
+|                                                                                                                                                                                      |
+========================================================================================== */
+#include "mm_player_priv.h"
+#include "mm_player_priv_internal.h"
+#include "mm_player_priv_locl_func.h"
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE                                                                                       |
+|                                                                                                                                                                                      |
+========================================================================================== */
+
+/*---------------------------------------------------------------------------
+|    GLOBAL CONSTANT DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    IMPORTED VARIABLE DECLARATIONS:                                                                           |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    IMPORTED FUNCTION DECLARATIONS:                                                                           |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL #defines:                                                                                                           |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL CONSTANT DEFINITIONS:                      |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL DATA TYPE DEFINITIONS:                     |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS:                     |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS:                      |
+---------------------------------------------------------------------------*/
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  FUNCTION DEFINITIONS                                                                                                                                                |
+|                                                                                                                                                                                      |
+========================================================================================== */
+
+int __gst_realize(mm_player_t* player) // @
+{
+       gint timeout = 0;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
+
+       __ta__("__mmplayer_gst_create_pipeline",
+               ret = __mmplayer_gst_create_pipeline(player);
+               if ( ret )
+               {
+                       debug_critical("failed to create pipeline\n");
+                       return ret;
+               }
+       )
+
+       /* 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 */
+               debug_error("failed to set READY state");
+               return ret;
+       }
+       else
+       {
+               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_READY );
+       }
+
+       /* create dot before error-return. for debugging */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-realize" );
+
+       debug_fleave();
+
+       return ret;
+}
+
+int __gst_unrealize(mm_player_t* player) // @
+{
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       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 );
+
+       /* destroy pipeline */
+       ret = __mmplayer_gst_destroy_pipeline( player );
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to destory pipeline\n");
+               return ret;
+       }
+
+       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_NULL );
+
+       debug_fleave();
+
+       return ret;
+}
+
+int __gst_pending_seek ( mm_player_t* player )
+{
+       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
+       MMPlayerStateType pending_state = MM_PLAYER_STATE_NONE;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       if ( !player->pending_seek.is_pending )
+       {
+               debug_log("pending seek is not reserved. nothing to do.\n" );
+               return ret;
+       }
+
+       /* check player state if player could pending seek or not. */
+       current_state = MMPLAYER_CURRENT_STATE(player);
+       pending_state = MMPLAYER_PENDING_STATE(player);
+
+       if ( current_state != MM_PLAYER_STATE_PAUSED && current_state != MM_PLAYER_STATE_PLAYING  )
+       {
+               debug_warning("try to pending seek in %s state, try next time. \n",
+                       MMPLAYER_STATE_GET_NAME(current_state));
+               return ret;
+       }
+
+       debug_log("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 )
+               debug_error("failed to seek pending postion. just keep staying current position.\n");
+
+       player->pending_seek.is_pending = FALSE;
+
+       debug_fleave();
+
+       return ret;
+}
+
+int __gst_start(mm_player_t* player) // @
+{
+       gboolean sound_extraction = 0;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       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);
+
+       /* 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 )
+               {
+                       debug_error("failed to set state to PAUSED for pending seek\n");
+                       return ret;
+               }
+
+               MMPLAYER_TARGET_STATE(player) = MM_PLAYER_STATE_PLAYING;
+
+               if ( sound_extraction )
+               {
+                       debug_log("setting pcm extraction\n");
+
+                       ret = __mmplayer_set_pcm_extraction(player);
+                       if ( MM_ERROR_NONE != ret )
+                       {
+                               debug_warning("failed to set pcm extraction\n");
+                               return ret;
+                       }
+               }
+               else
+               {
+                       if ( MM_ERROR_NONE != __gst_pending_seek(player) )
+                       {
+                               debug_warning("failed to seek pending postion. starting from the begin of content.\n");
+                       }
+               }
+       }
+
+       debug_log("current state before doing transition");
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
+       MMPLAYER_PRINT_STATE(player);
+
+       /* set pipeline state to PLAYING  */
+       ret = __mmplayer_gst_set_state(player,
+               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, FALSE, MMPLAYER_STATE_CHANGE_TIMEOUT(player) );
+       if (ret == MM_ERROR_NONE)
+       {
+               MMPLAYER_SET_STATE(player, MM_PLAYER_STATE_PLAYING);
+       }
+       else
+       {
+               debug_error("failed to set state to PLAYING");
+               return ret;
+       }
+
+       /* generating debug info before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-start" );
+
+       debug_fleave();
+
+       return ret;
+}
+
+int __gst_stop(mm_player_t* player) // @
+{
+       GstStateChangeReturn change_ret = GST_STATE_CHANGE_SUCCESS;
+       MMHandleType attrs = 0;
+       gboolean fadewown = FALSE;
+       gboolean rewind = FALSE;
+       gint timeout = 0;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       debug_log("current state before doing transition");
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_READY;
+       MMPLAYER_PRINT_STATE(player);
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       mm_attrs_get_int_by_name(attrs,"sound_fadedown", &fadewown);
+
+       /* enable fadedown */
+       if (fadewown)
+               __mmplayer_do_sound_fadedown(player, MM_PLAYER_FADEOUT_TIME_DEFAULT);
+
+       /* Just set state to PAUESED and the rewind. it's usual player behavior. */
+       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT ( player );
+       if  ( player->profile.uri_type == MM_PLAYER_URI_TYPE_BUFF || player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS)
+       {
+               ret = __mmplayer_gst_set_state(player,
+                       player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_READY, FALSE, timeout );
+       }
+       else
+       {
+               ret = __mmplayer_gst_set_state( player,
+                       player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED, FALSE, timeout );
+
+               if ( !MMPLAYER_IS_STREAMING(player))
+                       rewind = TRUE;
+       }
+
+       /* disable fadeout */
+       if (fadewown)
+               __mmplayer_undo_sound_fadedown(player);
+
+
+       /* return if set_state has failed */
+       if ( ret != MM_ERROR_NONE )
+       {
+               debug_error("failed to set state.\n");
+               return ret;
+       }
+
+       /* 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) )
+               {
+                       debug_warning("failed to rewind\n");
+                       ret = MM_ERROR_PLAYER_SEEK;
+               }
+       }
+
+       /* initialize */
+       player->sent_bos = FALSE;
+
+       /* 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 );
+       }
+       else
+       {
+               debug_error("fail to stop player.\n");
+               ret = MM_ERROR_PLAYER_INTERNAL;
+               __mmplayer_dump_pipeline_state(player);
+       }
+
+       /* generate dot file if enabled */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-stop" );
+
+       debug_fleave();
+
+       return ret;
+}
+
+int __gst_pause(mm_player_t* player, gboolean async) // @
+{
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       debug_log("current state before doing transition");
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PAUSED;
+       MMPLAYER_PRINT_STATE(player);
+
+       /* 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));
+
+       if ( FALSE == async && ret != MM_ERROR_NONE )
+       {
+               GstMessage *msg = NULL;
+               GTimer *timer = NULL;
+               gdouble MAX_TIMEOUT_SEC = 3;
+
+               debug_error("failed to set state to PAUSED");
+
+               timer = g_timer_new();
+               g_timer_start(timer);
+
+               GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
+               /* check if gst error posted or not */
+               do
+               {
+                       msg = gst_bus_timed_pop(bus, GST_SECOND /2);
+                       if (msg)
+                       {
+                               if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR)
+                               {
+                                       GError *error = NULL;
+
+                                       debug_error("paring error posted from bus");
+                                       /* parse error code */
+                                       gst_message_parse_error(msg, &error, NULL);
+
+                                       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 );
+                                       }
+                                       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 );
+                                       }
+                                       player->msg_posted = TRUE;
+                               }
+                               gst_message_unref(msg);
+                       }
+               } while (g_timer_elapsed(timer, NULL) < MAX_TIMEOUT_SEC);
+
+               /* clean */
+               gst_object_unref(bus);
+               g_timer_stop (timer);
+               g_timer_destroy (timer);
+
+               return ret;
+       }
+       else
+       {
+               if ( async == FALSE )
+               {
+                       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PAUSED );
+               }
+       }
+
+       /* FIXIT : analyze so called "async problem" */
+       /* set async off */
+       __gst_set_async_state_change( player, TRUE);
+
+       /* generate dot file before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-pause" );
+
+       debug_fleave();
+
+       return ret;
+}
+
+int __gst_resume(mm_player_t* player, gboolean async) // @
+{
+       int ret = MM_ERROR_NONE;
+       gint timeout = 0;
+       GstBus *bus = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail(player && player->pipeline,
+               MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       debug_log("current state before doing transition");
+       MMPLAYER_PENDING_STATE(player) = MM_PLAYER_STATE_PLAYING;
+       MMPLAYER_PRINT_STATE(player);
+
+       /* generate dot file before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-resume" );
+
+       __mmplayer_set_antishock( player , FALSE );
+
+       if ( async )
+               debug_log("do async state transition to PLAYING.\n");
+
+       /* clean bus sync handler because it's not needed any more */
+       bus = gst_pipeline_get_bus (GST_PIPELINE(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst));
+#ifdef GST_API_VERSION_1
+                       gst_bus_set_sync_handler (bus, NULL, NULL, NULL);
+#else
+                       gst_bus_set_sync_handler (bus, NULL, NULL);
+#endif
+       gst_object_unref(bus);
+
+       /* set pipeline state to PLAYING */
+       timeout = MMPLAYER_STATE_CHANGE_TIMEOUT(player);
+
+       ret = __mmplayer_gst_set_state(player,
+               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, async, timeout );
+       if (ret != MM_ERROR_NONE)
+       {
+               debug_error("failed to set state to PLAYING\n");
+
+               return ret;
+       }
+       else
+       {
+               if (async == FALSE)
+               {
+                       MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PLAYING );
+               }
+       }
+
+       /* FIXIT : analyze so called "async problem" */
+       /* set async off */
+       __gst_set_async_state_change( player, FALSE );
+
+       /* generate dot file before returning error */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-resume" );
+
+       debug_fleave();
+
+       return ret;
+}
+
+int
+__gst_set_position(mm_player_t* player, int format, unsigned long position, gboolean internal_called) // @
+{
+#ifndef GST_API_VERSION_1
+       GstFormat fmt  = GST_FORMAT_TIME;
+#endif
+       unsigned long dur_msec = 0;
+       gint64 dur_nsec = 0;
+       gint64 pos_nsec = 0;
+       gboolean ret = TRUE;
+
+       debug_fenter();
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       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;
+
+       /* 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 )
+       {
+#ifdef GST_API_VERSION_1
+               if ( !gst_element_query_duration( player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &dur_nsec ))
+               {
+                       goto SEEK_ERROR;
+               }
+#else
+               if ( !gst_element_query_duration( player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &dur_nsec ))
+               {
+                       goto SEEK_ERROR;
+               }
+#endif
+               player->duration = dur_nsec;
+       }
+
+       if ( player->duration )
+       {
+               dur_msec = GST_TIME_AS_MSECONDS(player->duration);
+       }
+       else
+       {
+               debug_error("could not get the duration. fail to seek.\n");
+               goto SEEK_ERROR;
+       }
+
+       debug_log("playback rate: %f\n", player->playback_rate);
+
+       /* do seek */
+       switch ( format )
+       {
+               case MM_PLAYER_POS_FORMAT_TIME:
+               {
+                       /* check position is valid or not */
+                       if ( position > dur_msec )
+                               goto INVALID_ARGS;
+
+                       debug_log("seeking to (%lu) msec, duration is %d msec\n", position, dur_msec);
+
+                       if (player->doing_seek)
+                       {
+                               debug_log("not completed seek");
+                               return MM_ERROR_PLAYER_DOING_SEEK;
+                       }
+
+                       if ( !internal_called)
+                               player->doing_seek = TRUE;
+
+                       pos_nsec = position * G_GINT64_CONSTANT(1000000);
+                       ret = __gst_seek ( player, player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, player->playback_rate,
+                                                       GST_FORMAT_TIME, ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
+                                                       GST_SEEK_TYPE_SET, pos_nsec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
+                       if ( !ret  )
+                       {
+                               debug_error("failed to set position. dur[%lu]  pos[%lu]  pos_msec[%llu]\n", dur_msec, position, pos_nsec);
+                               goto SEEK_ERROR;
+                       }
+               }
+               break;
+
+               case MM_PLAYER_POS_FORMAT_PERCENT:
+               {
+                       debug_log("seeking to (%lu)%% \n", position);
+
+                       if (player->doing_seek)
+                       {
+                               debug_log("not completed seek");
+                               return MM_ERROR_PLAYER_DOING_SEEK;
+                       }
+
+                       if ( !internal_called)
+                               player->doing_seek = TRUE;
+
+                       /* 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, ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
+                                                       GST_SEEK_TYPE_SET, pos_nsec, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
+                       if ( !ret  )
+                       {
+                               debug_error("failed to set position. dur[%lud]  pos[%lud]  pos_msec[%llud]\n", dur_msec, position, pos_nsec);
+                               goto SEEK_ERROR;
+                       }
+               }
+               break;
+
+               default:
+                       goto INVALID_ARGS;
+
+       }
+
+       /* 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 );
+
+       debug_fleave();
+       return MM_ERROR_NONE;
+
+PENDING:
+       player->pending_seek.is_pending = TRUE;
+       player->pending_seek.format = format;
+       player->pending_seek.pos = position;
+
+       debug_warning("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);
+
+       return MM_ERROR_NONE;
+
+INVALID_ARGS:
+       debug_error("invalid arguments, position : %ld  dur : %ld format : %d \n", position, dur_msec, format);
+       return MM_ERROR_INVALID_ARGUMENT;
+
+SEEK_ERROR:
+       player->doing_seek = FALSE;
+       return MM_ERROR_PLAYER_SEEK;
+}
+
+#define TRICKPLAY_OFFSET GST_MSECOND
+
+int
+__gst_get_position(mm_player_t* player, int format, unsigned long* position) // @
+{
+       MMPlayerStateType current_state = MM_PLAYER_STATE_NONE;
+#ifndef GST_API_VERSION_1
+       GstFormat fmt = GST_FORMAT_TIME;
+#endif
+       signed long long pos_msec = 0;
+       gboolean ret = TRUE;
+
+       return_val_if_fail( player && position && player->pipeline && player->pipeline->mainbin,
+               MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       current_state = MMPLAYER_CURRENT_STATE(player);
+
+       /* 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 )
+       {
+#ifdef GST_API_VERSION_1
+               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_FORMAT_TIME, &pos_msec);
+#else
+               ret = gst_element_query_position(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, &fmt, &pos_msec);
+#endif
+       }
+
+       /* 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 ))
+               //|| ( player->last_position != 0 && pos_msec == 0 ) )
+       {
+               debug_warning ("pos_msec = %"GST_TIME_FORMAT" and ret = %d and state = %d", GST_TIME_ARGS (pos_msec), ret, current_state);
+
+               if(player->playback_rate < 0.0)
+                       pos_msec = player->last_position - TRICKPLAY_OFFSET;
+               else
+                       pos_msec = player->last_position;
+
+               if (!ret)
+                       pos_msec = player->last_position;
+               else
+                       player->last_position = pos_msec;
+
+               debug_warning("returning last point : %"GST_TIME_FORMAT, GST_TIME_ARGS(pos_msec));
+
+       }
+       else
+       {
+               player->last_position = pos_msec;
+       }
+
+       switch (format) {
+               case MM_PLAYER_POS_FORMAT_TIME:
+                       *position = GST_TIME_AS_MSECONDS(pos_msec);
+                       break;
+
+               case MM_PLAYER_POS_FORMAT_PERCENT:
+               {
+                       int dur = 0;
+                       int pos = 0;
+
+                       dur = player->duration / GST_SECOND;
+                       if (dur <= 0)
+                       {
+                               debug_log ("duration is [%d], so returning position 0\n",dur);
+                               *position = 0;
+                       }
+                       else
+                       {
+                               pos = pos_msec / GST_SECOND;
+                               *position = pos * 100 / dur;
+                       }
+                       break;
+               }
+               default:
+                       return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       debug_log("current position : %lu\n", *position);
+
+
+       return MM_ERROR_NONE;
+}
+
+int    __gst_get_buffer_position(mm_player_t* player, int format, unsigned long* start_pos, unsigned long* stop_pos)
+{
+       GstElement *element = NULL;
+       GstQuery *query = NULL;
+
+       return_val_if_fail( player &&
+               player->pipeline &&
+               player->pipeline->mainbin,
+               MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       return_val_if_fail( start_pos && stop_pos, MM_ERROR_INVALID_ARGUMENT );
+
+       if ( MMPLAYER_IS_HTTP_STREAMING ( player ))
+       {
+               /* Note : In case of http streaming or HLS, the buffering queue [ queue2 ] could handle buffering query. */
+               element = GST_ELEMENT ( player->pipeline->mainbin[MMPLAYER_M_S_BUFFER].gst );
+       }
+       else if ( MMPLAYER_IS_RTSP_STREAMING ( player ) )
+       {
+               debug_warning ( "it's not supported yet.\n" );
+               return MM_ERROR_NONE;
+       }
+       else
+       {
+               debug_warning ( "it's only used for streaming case.\n" );
+               return MM_ERROR_NONE;
+       }
+
+       *start_pos = 0;
+       *stop_pos = 0;
+
+       switch ( format )
+       {
+               case MM_PLAYER_POS_FORMAT_PERCENT :
+               {
+                               query = gst_query_new_buffering ( GST_FORMAT_PERCENT );
+                               if ( gst_element_query ( element, query ) )
+                               {
+                                       gint64 start, stop;
+                                       GstFormat format;
+                                       gboolean busy;
+                                       gint percent;
+
+                                       gst_query_parse_buffering_percent ( query, &busy, &percent);
+                                       gst_query_parse_buffering_range ( query, &format, &start, &stop, NULL );
+
+                                       debug_log ( "buffering start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT "\n",  start, stop);
+
+                                       if ( start != -1)
+                                               *start_pos = 100 * start / GST_FORMAT_PERCENT_MAX;
+                                       else
+                                               *start_pos = 0;
+
+                                       if ( stop != -1)
+                                               *stop_pos = 100 * stop / GST_FORMAT_PERCENT_MAX;
+                                       else
+                                               *stop_pos = 0;
+                               }
+                               gst_query_unref (query);
+               }
+               break;
+
+               case MM_PLAYER_POS_FORMAT_TIME :
+                       debug_warning ( "Time format is not supported yet.\n" );
+                       break;
+
+               default :
+                       break;
+       }
+
+debug_log("current buffer position : %lu~%lu \n", *start_pos, *stop_pos );
+
+       return MM_ERROR_NONE;
+}
+
+int
+__gst_set_message_callback(mm_player_t* player, MMMessageCallback callback, gpointer user_param) // @
+{
+       debug_fenter();
+
+       if ( !player )
+       {
+               debug_warning("set_message_callback is called with invalid player handle\n");
+               return MM_ERROR_PLAYER_NOT_INITIALIZED;
+       }
+
+       player->msg_cb = callback;
+       player->msg_cb_param = user_param;
+
+       debug_log("msg_cb : 0x%x     msg_cb_param : 0x%x\n", (guint)callback, (guint)user_param);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+/* sending event to one of sinkelements */
+gboolean
+__gst_send_event_to_sink( mm_player_t* player, GstEvent* event )
+{
+       GstEvent * event2 = NULL;
+       GList *sinks = NULL;
+       gboolean res = FALSE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, FALSE );
+       return_val_if_fail ( event, FALSE );
+
+       if ( player->play_subtitle && !player->use_textoverlay)
+               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)) )
+                       {
+                               debug_log("sending event[%s] to sink element [%s] success!\n",
+                                       GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(sink) );
+                               break;
+                       }
+
+                       debug_log("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->use_textoverlay)
+        {
+               GstElement *text_sink = GST_ELEMENT_CAST (player->pipeline->textbin[MMPLAYER_T_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)) )
+                       {
+                               debug_error("sending event[%s] to subtitle sink element [%s] failed!\n",
+                                       GST_EVENT_TYPE_NAME(event2), GST_ELEMENT_NAME(text_sink) );
+                       }
+                       else
+                       {
+                               debug_log("sending event[%s] to subtitle sink element [%s] success!\n",
+                                       GST_EVENT_TYPE_NAME(event2), GST_ELEMENT_NAME(text_sink) );
+                       }
+
+                       gst_event_unref (event2);
+               }
+        }
+
+       gst_event_unref (event);
+
+       debug_fleave();
+
+       return res;
+}
+
+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 )
+{
+       GstEvent* event = NULL;
+       gboolean result = FALSE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, FALSE );
+
+       event = gst_event_new_seek (rate, format, flags, cur_type,
+               cur, stop_type, stop);
+
+       result = __gst_send_event_to_sink( player, event );
+
+       debug_fleave();
+
+       return result;
+}
+
+int __gst_adjust_subtitle_position(mm_player_t* player, int format, int position)
+{
+       GstEvent* event = NULL;
+       gint64 current_pos = 0;
+       gint64 adusted_pos = 0;
+       gboolean ret = TRUE;
+
+       debug_fenter();
+
+       /* check player and subtitlebin are created */
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( player->play_subtitle, MM_ERROR_NOT_SUPPORT_API );
+
+       if (position == 0)
+       {
+               debug_log ("nothing to do\n");
+               return MM_ERROR_NONE;
+       }
+
+       switch (format)
+       {
+               case MM_PLAYER_POS_FORMAT_TIME:
+               {
+                       if (__gst_get_position(player, MM_PLAYER_POS_FORMAT_TIME, &current_pos ))
+                       {
+                               debug_error("failed to get position");
+                               return MM_ERROR_PLAYER_INTERNAL;
+                       }
+
+                       adusted_pos = (gint64)current_pos + ((gint64)position * G_GINT64_CONSTANT(1000000));
+                       if (adusted_pos < 0)
+                               adusted_pos = G_GUINT64_CONSTANT(0);
+                       debug_log("adjust subtitle postion : %lu -> %lu [msec]\n", GST_TIME_AS_MSECONDS(current_pos), GST_TIME_AS_MSECONDS(adusted_pos));
+
+                       event = gst_event_new_seek (1.0,        GST_FORMAT_TIME,
+                               ( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ),
+                               GST_SEEK_TYPE_SET, adusted_pos,
+                               GST_SEEK_TYPE_SET, -1);
+               }
+               break;
+
+               default:
+               {
+                       debug_warning("invalid format.\n");
+                       return MM_ERROR_INVALID_ARGUMENT;
+               }
+       }
+
+       /* keep ref to the event */
+       gst_event_ref (event);
+
+       debug_log("sending event[%s] to subparse element [%s]\n",
+                       GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst) );
+
+       if (gst_element_send_event (player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst, event))
+       {
+               debug_log("sending event[%s] to subparse element [%s] success!\n",
+                       GST_EVENT_TYPE_NAME(event), GST_ELEMENT_NAME(player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst) );
+       }
+
+       /* unref to the event */
+       gst_event_unref (event);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+#ifdef GST_API_VERSION_1
+void
+__gst_appsrc_feed_data_mem(GstElement *element, guint size, gpointer user_data) // @
+{
+       GstElement *appsrc = element;
+       tBuffer *buf = (tBuffer *)user_data;
+       GstBuffer *buffer = NULL;
+       GstFlowReturn ret = GST_FLOW_OK;
+       gint len = size;
+
+       return_if_fail ( element );
+       return_if_fail ( buf );
+
+       //buffer = gst_buffer_new ();
+
+       if (buf->offset >= buf->len)
+       {
+               debug_log("call eos appsrc\n");
+              g_signal_emit_by_name (appsrc, "end-of-stream", &ret);
+              return;
+       }
+
+       if ( buf->len - buf->offset < size)
+       {
+               len = buf->len - buf->offset + buf->offset;
+       }
+
+       buffer = gst_buffer_new();
+       GstMapInfo info;
+
+       info.data = (guint8*)(buf->buf + buf->offset);
+       gst_buffer_set_size(buffer, len);
+
+       //GST_BUFFER_DATA(buffer) = (guint8*)(buf->buf + buf->offset);
+       //GST_BUFFER_SIZE(buffer) = len;
+       GST_BUFFER_OFFSET(buffer) = buf->offset;
+       GST_BUFFER_OFFSET_END(buffer) = buf->offset + len;
+       gst_buffer_map (buffer, &info, GST_MAP_WRITE);
+
+       debug_log("feed buffer %p, offset %u-%u length %u\n", buffer, buf->offset, buf->len,len);
+       g_signal_emit_by_name (appsrc, "push-buffer", buffer, &ret);
+
+       buf->offset += len;
+}
+#else
+void
+__gst_appsrc_feed_data_mem(GstElement *element, guint size, gpointer user_data) // @
+{
+       GstElement *appsrc = element;
+       tBuffer *buf = (tBuffer *)user_data;
+       GstBuffer *buffer = NULL;
+       GstFlowReturn ret = GST_FLOW_OK;
+       gint len = size;
+
+       return_if_fail ( element );
+       return_if_fail ( buf );
+
+       buffer = gst_buffer_new ();
+
+       if (buf->offset >= buf->len)
+       {
+               debug_log("call eos appsrc\n");
+              g_signal_emit_by_name (appsrc, "end-of-stream", &ret);
+              return;
+       }
+
+       if ( buf->len - buf->offset < size)
+       {
+               len = buf->len - buf->offset + buf->offset;
+       }
+
+       GST_BUFFER_DATA(buffer) = (guint8*)(buf->buf + buf->offset);
+       GST_BUFFER_SIZE(buffer) = len;
+       GST_BUFFER_OFFSET(buffer) = buf->offset;
+       GST_BUFFER_OFFSET_END(buffer) = buf->offset + len;
+
+       debug_log("feed buffer %p, offset %u-%u length %u\n", buffer, buf->offset, buf->len,len);
+       g_signal_emit_by_name (appsrc, "push-buffer", buffer, &ret);
+
+       buf->offset += len;
+}
+#endif
+
+gboolean
+__gst_appsrc_seek_data_mem(GstElement *element, guint64 size, gpointer user_data) // @
+{
+       tBuffer *buf = (tBuffer *)user_data;
+
+       return_val_if_fail ( buf, FALSE );
+
+       buf->offset  = (int)size;
+
+       return TRUE;
+}
+
+void
+__gst_appsrc_feed_data(GstElement *element, guint size, gpointer user_data) // @
+{
+       mm_player_t *player  = (mm_player_t*)user_data;
+
+       return_if_fail ( player );
+
+       debug_msg("app-src: feed data\n");
+
+       if(player->need_data_cb)
+               player->need_data_cb(size, player->buffer_cb_user_param);
+}
+
+gboolean
+__gst_appsrc_seek_data(GstElement *element, guint64 offset, gpointer user_data) // @
+{
+       mm_player_t *player  = (mm_player_t*)user_data;
+
+       return_val_if_fail ( player, FALSE );
+
+       debug_msg("app-src: seek data\n");
+
+       if(player->seek_data_cb)
+               player->seek_data_cb(offset, player->buffer_cb_user_param);
+
+       return TRUE;
+}
+
+
+gboolean
+__gst_appsrc_enough_data(GstElement *element, gpointer user_data) // @
+{
+       mm_player_t *player  = (mm_player_t*)user_data;
+
+       return_val_if_fail ( player, FALSE );
+
+       debug_msg("app-src: enough data:%p\n", player->enough_data_cb);
+
+       if(player->enough_data_cb)
+               player->enough_data_cb(player->buffer_cb_user_param);
+
+       return TRUE;
+}
+
+
+
diff --git a/src/mm_player_priv_gst_wrapper.c b/src/mm_player_priv_gst_wrapper.c
new file mode 100755 (executable)
index 0000000..cef6bec
--- /dev/null
@@ -0,0 +1,3029 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, Heechul Jeon <heechul.jeon@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  INCLUDE FILES                                                                                                                                                       |
+|                                                                                                                                                                                      |
+========================================================================================== */
+#if 0
+#include <glib.h>
+#include <gst/gst.h>
+#ifndef GST_API_VERSION_1
+#include <gst/interfaces/xoverlay.h>
+#else
+#include <gst/video/videooverlay.h>
+#endif
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include <mm_error.h>
+//#include <mm_attrs.h>
+//#include <mm_attrs_private.h>
+#include <mm_debug.h>
+
+#include "mm_player_ini.h"
+#include "mm_player_attrs.h"
+#include "mm_player_capture.h"
+#endif
+#include <gst/app/gstappsrc.h>
+
+#include "mm_player_priv.h"
+#include "mm_player_priv_internal.h"
+#include "mm_player_priv_locl_func.h"
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE                                                                                       |
+|                                                                                                                                                                                      |
+========================================================================================== */
+
+/*---------------------------------------------------------------------------
+|    GLOBAL CONSTANT DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    IMPORTED VARIABLE DECLARATIONS:                                                                           |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    IMPORTED FUNCTION DECLARATIONS:                                                                           |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL #defines:                                                                                                           |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL CONSTANT DEFINITIONS:                                                                                       |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL DATA TYPE DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS:                                                                                       |
+---------------------------------------------------------------------------*/
+/* video capture callback*/
+gulong ahs_appsrc_cb_probe_id = 0;
+
+/*---------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                |
+---------------------------------------------------------------------------*/
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  FUNCTION DEFINITIONS                                                                                                                                                |
+|                                                                                                                                                                                      |
+========================================================================================== */
+
+gboolean
+__mmplayer_gst_callback(GstBus *bus, GstMessage *msg, gpointer data) // @
+{
+       mm_player_t* player = (mm_player_t*) data;
+       gboolean ret = TRUE;
+       static gboolean async_done = FALSE;
+
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( msg && GST_IS_MESSAGE(msg), FALSE );
+
+#ifdef GST_API_VERSION_1
+       const GstStructure *structure;
+       structure = gst_message_get_structure (msg);
+#endif
+
+       switch ( GST_MESSAGE_TYPE( msg ) )
+       {
+               case GST_MESSAGE_UNKNOWN:
+                       debug_warning("unknown message received\n");
+               break;
+
+               case GST_MESSAGE_EOS:
+               {
+                       MMHandleType attrs = 0;
+                       gint count = 0;
+
+                       debug_log("GST_MESSAGE_EOS received\n");
+
+                       /* 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) )
+                       {
+                               debug_warning("EOS received on non-playing state. ignoring it\n");
+                               break;
+                       }
+
+                       if ( (player->audio_stream_cb) && (player->is_sound_extraction) )
+                       {
+                               GstPad *pad = NULL;
+
+                               pad = gst_element_get_static_pad (player->pipeline->audiobin[MMPLAYER_A_SINK].gst, "sink");
+
+                               debug_error("release audio callback\n");
+
+                               /* release audio callback */
+#ifdef GST_API_VERSION_1
+                               gst_pad_remove_probe (pad, player->audio_cb_probe_id);
+#else
+                               gst_pad_remove_buffer_probe (pad, player->audio_cb_probe_id);
+#endif
+                               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;
+
+                       }
+
+                       /* rewind if repeat count is greater then zero */
+                       /* get play count */
+                       attrs = MMPLAYER_GET_ATTRS(player);
+
+                       if ( attrs )
+                       {
+                               gboolean smooth_repeat = FALSE;
+
+                               mm_attrs_get_int_by_name(attrs, "profile_play_count", &count);
+                               mm_attrs_get_int_by_name(attrs, "profile_smooth_repeat", &smooth_repeat);
+
+                               debug_log("remaining play count: %d, playback rate: %f\n", count, player->playback_rate);
+
+                               if ( count > 1 || count == -1 || player->playback_rate < 0.0 ) /* default value is 1 */
+                               {
+                                       if ( smooth_repeat )
+                                       {
+                                               debug_log("smooth repeat enabled. seeking operation will be excuted in new thread\n");
+
+                                               g_cond_signal( player->repeat_thread_cond );
+
+                                               break;
+                                       }
+                                       else
+                                       {
+                                               gint ret_value = 0;
+
+                                               if ( player->section_repeat )
+                                               {
+                                                       ret_value = _mmplayer_activate_section_repeat((MMHandleType)player, player->section_repeat_start, player->section_repeat_end);
+                                               }
+                                               else
+                                               {
+
+                                                       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 );
+                                                       }
+
+                                                       ret_value = __gst_set_position( player, MM_PLAYER_POS_FORMAT_TIME, 0, TRUE);
+
+                                                       /* initialize */
+                                                       player->sent_bos = FALSE;
+                                               }
+
+                                               if ( MM_ERROR_NONE != ret_value )
+                                               {
+                                                       debug_error("failed to set position to zero for rewind\n");
+                                               }
+                                               else
+                                               {
+                                                       if ( count > 1 )
+                                                       {
+                                                               /* we successeded to rewind. update play count and then wait for next EOS */
+                                                               count--;
+
+                                                               mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
+
+                                                               if ( mmf_attrs_commit ( attrs ) )
+                                                                       debug_error("failed to commit attrs\n");
+                                                       }
+                                               }
+
+                                               break;
+                                       }
+                               }
+                       }
+
+                       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-status-eos" );
+
+                       /* post eos message to application */
+                       __mmplayer_post_delayed_eos( player, PLAYER_INI()->eos_delay );
+
+                       /* reset last position */
+                       player->last_position = 0;
+               }
+               break;
+
+               case GST_MESSAGE_ERROR:
+               {
+                       GError *error = NULL;
+                       gchar* debug = NULL;
+                       gchar *msg_src_element = 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 );
+
+                       msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( msg->src ) );
+#ifdef GST_API_VERSION_1
+                       if ( gst_structure_has_name ( structure, "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 );
+
+                               /* dump state of all element */
+                               __mmplayer_dump_pipeline_state( player );
+
+                       }
+#else
+                       if ( gst_structure_has_name ( msg->structure, "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 );
+
+                               /* dump state of all element */
+                               __mmplayer_dump_pipeline_state( player );
+
+                       }
+
+#endif
+
+
+                       if (MMPLAYER_IS_HTTP_PD(player))
+                       {
+                               _mmplayer_unrealize_pd_downloader ((MMHandleType)player);
+                       }
+
+                       MMPLAYER_FREEIF( debug );
+                       g_error_free( error );
+               }
+               break;
+
+               case GST_MESSAGE_WARNING:
+               {
+                       char* debug = NULL;
+                       GError* error = NULL;
+
+                       gst_message_parse_warning(msg, &error, &debug);
+
+                       debug_warning("warning : %s\n", error->message);
+                       debug_warning("debug : %s\n", debug);
+
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_WARNING, NULL );
+
+                       MMPLAYER_FREEIF( debug );
+                       g_error_free( error );
+               }
+               break;
+
+               case GST_MESSAGE_INFO:                          debug_log("GST_MESSAGE_STATE_DIRTY\n"); break;
+
+               case GST_MESSAGE_TAG:
+               {
+                       debug_log("GST_MESSAGE_TAG\n");
+                       if ( ! __mmplayer_gst_extract_tag_from_msg( player, msg ) )
+                       {
+                               debug_warning("failed to extract tags from gstmessage\n");
+                       }
+               }
+               break;
+
+               case GST_MESSAGE_BUFFERING:
+               {
+                       MMMessageParamType msg_param = {0, };
+                       gboolean update_buffering_percent = TRUE;
+
+                       if ( !MMPLAYER_IS_STREAMING(player) || (player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS) ) // pure hlsdemux case, don't consider buffering of msl currently
+                               break;
+
+                       __mm_player_streaming_buffering (player->streamer, msg);
+
+                       __mmplayer_handle_buffering_message ( player );
+
+                       update_buffering_percent = (player->pipeline_is_constructed || MMPLAYER_IS_RTSP_STREAMING(player) );
+                       if (update_buffering_percent)
+                       {
+                               msg_param.connection.buffering = player->streamer->buffering_percent;
+                               MMPLAYER_POST_MSG ( player, MM_MESSAGE_BUFFERING, &msg_param );
+                       }
+               }
+               break;
+
+               case GST_MESSAGE_STATE_CHANGED:
+               {
+                       MMPlayerGstElement *mainbin;
+                       const GValue *voldstate, *vnewstate, *vpending;
+                       GstState oldstate, newstate, pending;
+
+                       if ( ! ( player->pipeline && player->pipeline->mainbin ) )
+                       {
+                               debug_error("player pipeline handle is null");
+                               break;
+                       }
+
+                       mainbin = player->pipeline->mainbin;
+
+                       /* we only handle messages from pipeline */
+                       if( msg->src != (GstObject *)mainbin[MMPLAYER_M_PIPE].gst )
+                               break;
+
+                       /* get state info from msg */
+#ifdef GST_API_VERSION_1
+                       voldstate = gst_structure_get_value (structure, "old-state");
+                       vnewstate = gst_structure_get_value (structure, "new-state");
+                       vpending = gst_structure_get_value (structure, "pending-state");
+#else
+                       voldstate = gst_structure_get_value (msg->structure, "old-state");
+                       vnewstate = gst_structure_get_value (msg->structure, "new-state");
+                       vpending = gst_structure_get_value (msg->structure, "pending-state");
+#endif
+
+                       oldstate = (GstState)voldstate->data[0].v_int;
+                       newstate = (GstState)vnewstate->data[0].v_int;
+                       pending = (GstState)vpending->data[0].v_int;
+
+                       debug_log("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 ) );
+
+                       if (oldstate == newstate)
+                       {
+                               debug_warning("pipeline reports state transition to old state");
+                               break;
+                       }
+
+                       switch(newstate)
+                       {
+                               case GST_STATE_VOID_PENDING:
+                               break;
+
+                               case GST_STATE_NULL:
+                               break;
+
+                               case GST_STATE_READY:
+                               break;
+
+                               case GST_STATE_PAUSED:
+                               {
+                                       gboolean prepare_async = FALSE;
+
+                                       if ( ! player->audio_cb_probe_id && player->is_sound_extraction )
+                                               __mmplayer_configure_audio_callback(player);
+
+                                       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);
+                                               debug_log("checking prepare mode for async transition - %d", prepare_async);
+                                       }
+
+                                       if ( MMPLAYER_IS_STREAMING(player) || prepare_async )
+                                       {
+                                               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PAUSED );
+
+                                               if (player->streamer)
+                                               {
+                                                       __mm_player_streaming_set_content_bitrate(player->streamer,
+                                                               player->total_maximum_bitrate, player->total_bitrate);
+                                               }
+                                       }
+                               }
+                               break;
+
+                               case GST_STATE_PLAYING:
+                               {
+                                       if (player->doing_seek && async_done)
+                                       {
+                                               player->doing_seek = FALSE;
+                                               async_done = FALSE;
+                                               MMPLAYER_POST_MSG ( player, MM_MESSAGE_SEEK_COMPLETED, NULL );
+                                       }
+
+                                       if ( MMPLAYER_IS_STREAMING(player) ) // managed prepare async case when buffering is completed
+                                       {
+                                               // pending state should be reset oyherwise, it's still playing even though it's resumed after bufferging.
+                                               MMPLAYER_SET_STATE ( player, MM_PLAYER_STATE_PLAYING);
+                                       }
+                               }
+                               break;
+
+                               default:
+                               break;
+                       }
+               }
+               break;
+
+               case GST_MESSAGE_STATE_DIRTY:           debug_log("GST_MESSAGE_STATE_DIRTY\n"); break;
+               case GST_MESSAGE_STEP_DONE:                     debug_log("GST_MESSAGE_STEP_DONE\n"); break;
+               case GST_MESSAGE_CLOCK_PROVIDE:         debug_log("GST_MESSAGE_CLOCK_PROVIDE\n"); break;
+
+               case GST_MESSAGE_CLOCK_LOST:
+                       {
+                               GstClock *clock = NULL;
+                               gst_message_parse_clock_lost (msg, &clock);
+                               debug_log("GST_MESSAGE_CLOCK_LOST : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
+                               g_print ("GST_MESSAGE_CLOCK_LOST : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
+
+                               if (PLAYER_INI()->provide_clock)
+                               {
+                                       debug_log ("Provide clock is TRUE, do pause->resume\n");
+                                       __gst_pause(player, FALSE);
+                                       __gst_resume(player, FALSE);
+                               }
+                       }
+                       break;
+
+               case GST_MESSAGE_NEW_CLOCK:
+                       {
+                               GstClock *clock = NULL;
+                               gst_message_parse_new_clock (msg, &clock);
+                               debug_log("GST_MESSAGE_NEW_CLOCK : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
+                       }
+                       break;
+
+               case GST_MESSAGE_STRUCTURE_CHANGE:      debug_log("GST_MESSAGE_STRUCTURE_CHANGE\n"); break;
+               case GST_MESSAGE_STREAM_STATUS:         debug_log("GST_MESSAGE_STREAM_STATUS\n"); break;
+               case GST_MESSAGE_APPLICATION:           debug_log("GST_MESSAGE_APPLICATION\n"); break;
+
+               case GST_MESSAGE_ELEMENT:
+               {
+                       debug_log("GST_MESSAGE_ELEMENT\n");
+               }
+               break;
+
+               case GST_MESSAGE_SEGMENT_START:         debug_log("GST_MESSAGE_SEGMENT_START\n"); break;
+               case GST_MESSAGE_SEGMENT_DONE:          debug_log("GST_MESSAGE_SEGMENT_DONE\n"); break;
+
+               case GST_MESSAGE_DURATION:
+               {
+                       debug_log("GST_MESSAGE_DURATION\n");
+                       ret = __mmplayer_gst_handle_duration(player, msg);
+                       if (!ret)
+                       {
+                               debug_warning("failed to update duration");
+                       }
+               }
+
+               break;
+
+
+               case GST_MESSAGE_LATENCY:                               debug_log("GST_MESSAGE_LATENCY\n"); break;
+               case GST_MESSAGE_ASYNC_START:           debug_log("GST_MESSAGE_ASYNC_DONE : %s\n", gst_element_get_name(GST_MESSAGE_SRC(msg))); break;
+
+               case GST_MESSAGE_ASYNC_DONE:
+               {
+                       debug_log("GST_MESSAGE_ASYNC_DONE : %s\n", gst_element_get_name(GST_MESSAGE_SRC(msg)));
+
+                       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;
+                               }
+                       }
+               }
+               break;
+
+               case GST_MESSAGE_REQUEST_STATE:         debug_log("GST_MESSAGE_REQUEST_STATE\n"); break;
+               case GST_MESSAGE_STEP_START:            debug_log("GST_MESSAGE_STEP_START\n"); break;
+               case GST_MESSAGE_QOS:                                   debug_log("GST_MESSAGE_QOS\n"); break;
+               case GST_MESSAGE_PROGRESS:                      debug_log("GST_MESSAGE_PROGRESS\n"); break;
+               case GST_MESSAGE_ANY:                           debug_log("GST_MESSAGE_ANY\n"); break;
+
+               default:
+                       debug_warning("unhandled message\n");
+               break;
+       }
+
+       /* FIXIT : this cause so many warnings/errors from glib/gstreamer. we should not call it since
+        * gst_element_post_message api takes ownership of the message.
+        */
+       //gst_message_unref( msg );
+
+       return ret;
+}
+
+gboolean
+__mmplayer_gst_handle_duration(mm_player_t* player, GstMessage* msg)
+{
+       GstFormat format;
+       gint64 bytes = 0;
+
+       debug_fenter();
+
+       return_val_if_fail(player, FALSE);
+       return_val_if_fail(msg, FALSE);
+
+       gst_message_parse_duration (msg, &format, &bytes);
+
+       if (MMPLAYER_IS_HTTP_STREAMING(player) && format == GST_FORMAT_BYTES )
+       {
+               debug_log("data total size of http content: %lld", bytes);
+               player->http_content_size = bytes;
+       }
+       else if (format == GST_FORMAT_TIME)
+       {
+               /* handling audio clip which has vbr. means duration is keep changing */
+               _mmplayer_update_content_attrs (player, ATTR_DURATION );
+       }
+       else
+       {
+               debug_warning("duration is neither BYTES or TIME");
+               return FALSE;
+       }
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+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)\
+       {\
+               debug_log ( "update tag string : %s\n", string); \
+               mm_attrs_set_string_by_name(attribute, playertag, string); \
+               g_free(string);\
+               string = NULL;\
+       }\
+}
+
+#ifdef GST_API_VERSION_1
+#define MMPLAYER_UPDATE_TAG_IMAGE(gsttag, attribute, playertag) \
+value = gst_tag_list_get_value_index(tag_list, gsttag, index); \
+if (value) \
+{\
+       GstMapInfo info; \
+       gst_buffer_map (buffer, &info, GST_MAP_WRITE); \
+       buffer = gst_value_get_buffer (value); \
+       debug_log ( "update album cover data : %p, size : %d\n", info.data, gst_buffer_get_size(buffer)); \
+       player->album_art = (gchar *)g_malloc(gst_buffer_get_size(buffer)); \
+       if (player->album_art); \
+       { \
+               memcpy(player->album_art, info.data, gst_buffer_get_size(buffer)); \
+               mm_attrs_set_data_by_name(attribute, playertag, (void *)player->album_art, gst_buffer_get_size(buffer)); \
+       } \
+gst_buffer_unmap (buffer, &info); \
+}
+#else
+#define MMPLAYER_UPDATE_TAG_IMAGE(gsttag, attribute, playertag) \
+value = gst_tag_list_get_value_index(tag_list, gsttag, index); \
+if (value) \
+{\
+       buffer = gst_value_get_buffer (value); \
+       debug_log ( "update album cover data : %p, size : %d\n", GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); \
+       player->album_art = (gchar *)g_malloc(GST_BUFFER_SIZE(buffer)); \
+       if (player->album_art); \
+       { \
+               memcpy(player->album_art, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); \
+               mm_attrs_set_data_by_name(attribute, playertag, (void *)player->album_art, GST_BUFFER_SIZE(buffer)); \
+       } \
+}
+#endif
+
+#define MMPLAYER_UPDATE_TAG_UINT(gsttag, attribute, playertag) \
+if (gst_tag_list_get_uint(tag_list, gsttag, &v_uint))\
+{\
+       if(v_uint)\
+       {\
+               if(gsttag==GST_TAG_BITRATE)\
+               {\
+                       if (player->updated_bitrate_count == 0) \
+                               mm_attrs_set_int_by_name(attribute, "content_audio_bitrate", v_uint); \
+                       if (player->updated_bitrate_count<MM_PLAYER_STREAM_COUNT_MAX) \
+                       {\
+                               player->bitrate[player->updated_bitrate_count] = v_uint;\
+                               player->total_bitrate += player->bitrate[player->updated_maximum_bitrate_count]; \
+                               player->updated_bitrate_count++; \
+                               mm_attrs_set_int_by_name(attribute, playertag, player->total_bitrate);\
+                               debug_log ( "update bitrate %d[bps] of stream #%d.\n", v_uint, player->updated_bitrate_count);\
+                       }\
+               }\
+               else if (gsttag==GST_TAG_MAXIMUM_BITRATE)\
+               {\
+                       if (player->updated_maximum_bitrate_count<MM_PLAYER_STREAM_COUNT_MAX) \
+                       {\
+                               player->maximum_bitrate[player->updated_maximum_bitrate_count] = v_uint;\
+                               player->total_maximum_bitrate += player->maximum_bitrate[player->updated_maximum_bitrate_count]; \
+                               player->updated_maximum_bitrate_count++; \
+                               mm_attrs_set_int_by_name(attribute, playertag, player->total_maximum_bitrate); \
+                               debug_log ( "update maximum bitrate %d[bps] of stream #%d\n", v_uint, player->updated_maximum_bitrate_count);\
+                       }\
+               }\
+               else\
+               {\
+                       mm_attrs_set_int_by_name(attribute, playertag, v_uint); \
+               }\
+               v_uint = 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);\
+               debug_log ( "metainfo year : %s\n", string);\
+               MMPLAYER_FREEIF(string);\
+               g_date_free(date);\
+       }\
+}
+
+#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;
+
+       MMHandleType attrs = 0;
+
+       char *string = NULL;
+       guint v_uint = 0;
+       GDate *date = NULL;
+       /* album cover */
+       GstBuffer *buffer = NULL;
+       gint index = 0;
+       const GValue *value;
+
+       /* currently not used. but those are needed for above macro */
+       //guint64 v_uint64 = 0;
+       //gdouble v_double = 0;
+
+       return_val_if_fail( player && msg, FALSE );
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+
+       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_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_IMAGE(GST_TAG_IMAGE, attrs, "tag_album_cover");
+       /* 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, ?, ?); */
+
+       if ( mmf_attrs_commit ( attrs ) )
+               debug_error("failed to commit.\n");
+
+       gst_tag_list_free(tag_list);
+
+       return TRUE;
+}
+
+void
+__mmplayer_gst_rtp_no_more_pads (GstElement *element,  gpointer data)  // @
+{
+       mm_player_t* player = (mm_player_t*) data;
+
+       debug_fenter();
+
+       /* 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 mo 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 )
+       {
+               debug_log("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;
+               }
+       }
+
+       /* create dot before error-return. for debugging */
+       MMPLAYER_GENERATE_DOT_IF_ENABLED ( player, "pipeline-no-more-pad" );
+
+       /* NOTE : if rtspsrc goes to PLAYING before adding it's src pads, a/v sink elements will
+        * not goes to PLAYING. they will just remain in PAUSED state. simply we are giving
+        * PLAYING state again.
+        */
+       __mmplayer_gst_set_state(player,
+               player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PLAYING, TRUE, 5000 );
+
+       player->no_more_pad = TRUE;
+
+       debug_fleave();
+}
+
+gboolean
+__mmplayer_gst_remove_fakesink(mm_player_t* player, MMPlayerGstElement* fakesink) // @
+{
+       GstElement* parent = NULL;
+
+       return_val_if_fail(player && player->pipeline && fakesink, FALSE);
+
+       /* lock */
+       g_mutex_lock( player->fsink_lock );
+
+       if ( ! fakesink->gst )
+       {
+               goto ERROR;
+       }
+
+       /* get parent of fakesink */
+       parent = (GstElement*)gst_object_get_parent( (GstObject*)fakesink->gst );
+       if ( ! parent )
+       {
+               debug_log("fakesink already removed\n");
+               goto ERROR;
+       }
+
+       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) )
+       {
+               debug_error("fakesink state change failure!\n");
+
+               /* FIXIT : should I return here? or try to proceed to next? */
+               /* return FALSE; */
+       }
+
+       /* remove fakesink from it's parent */
+       if ( ! gst_bin_remove( GST_BIN( parent ), fakesink->gst ) )
+       {
+               debug_error("failed to remove fakesink\n");
+
+               gst_object_unref( parent );
+
+               goto ERROR;
+       }
+
+       gst_object_unref( parent );
+
+       debug_log("state-holder removed\n");
+
+       gst_element_set_locked_state( fakesink->gst, FALSE );
+
+       g_mutex_unlock( player->fsink_lock );
+       return TRUE;
+
+ERROR:
+       if ( fakesink->gst )
+       {
+               gst_element_set_locked_state( fakesink->gst, FALSE );
+       }
+
+       g_mutex_unlock( player->fsink_lock );
+       return FALSE;
+}
+
+void
+__mmplayer_gst_rtp_dynamic_pad (GstElement *element, GstPad *pad, gpointer data) // @
+{
+       GstPad *sinkpad = NULL;
+       GstCaps* caps = NULL;
+       GstElement* new_element = NULL;
+
+       mm_player_t* player = (mm_player_t*) data;
+
+       debug_fenter();
+
+       return_if_fail( element && pad );
+       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++;
+       debug_log("stream count inc : %d\n", player->num_dynamic_pad);
+
+       /* perform autoplugging if dump is disabled */
+       if ( PLAYER_INI()->rtsp_do_typefinding )
+       {
+               /* create typefind */
+               new_element = gst_element_factory_make( "typefind", NULL );
+               if ( ! new_element )
+               {
+                       debug_error("failed to create typefind\n");
+                       goto ERROR;
+               }
+
+               MMPLAYER_SIGNAL_CONNECT(        player,
+                                                                       G_OBJECT(new_element),
+                                                                       "have-type",
+                                                                       G_CALLBACK(__mmplayer_typefind_have_type),
+                                                                       (gpointer)player);
+
+               /* FIXIT : try to remove it */
+               player->have_dynamic_pad = FALSE;
+       }
+       else  /* NOTE : use pad's caps directely. if enabled. what I am assuming is there's no elemnt has dynamic pad */
+       {
+               debug_log("using pad caps to autopluging instead of doing typefind\n");
+#ifdef GST_API_VERSION_1
+               caps = gst_pad_get_current_caps( pad );
+#else
+               caps = gst_pad_get_caps( pad );
+#endif
+
+               MMPLAYER_CHECK_NULL( caps );
+
+               /* clear  previous result*/
+               player->have_dynamic_pad = FALSE;
+
+               if ( ! __mmplayer_try_to_plug( player, pad, caps ) )
+               {
+                       debug_error("failed to autoplug for caps : %s\n", gst_caps_to_string( caps ) );
+                       goto ERROR;
+               }
+
+               /* check if there's dynamic pad*/
+               if( player->have_dynamic_pad )
+               {
+                       debug_error("using pad caps assums there's no dynamic pad !\n");
+                       debug_error("try with enalbing rtsp_do_typefinding\n");
+                       goto ERROR;
+               }
+
+               gst_caps_unref( caps );
+               caps = NULL;
+       }
+
+       /* excute new_element if created*/
+       if ( new_element )
+       {
+               debug_log("adding new element to pipeline\n");
+
+               /* set state to READY before add to bin */
+               MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_READY );
+
+               /* add new element to the pipeline */
+               if ( FALSE == gst_bin_add( GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst), new_element)  )
+               {
+                       debug_error("failed to add autoplug element to bin\n");
+                       goto ERROR;
+               }
+
+               /* get pad from element */
+               sinkpad = gst_element_get_static_pad ( GST_ELEMENT(new_element), "sink" );
+               if ( !sinkpad )
+               {
+                       debug_error("failed to get sinkpad from autoplug element\n");
+                       goto ERROR;
+               }
+
+               /* link it */
+               if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
+               {
+                       debug_error("failed to link autoplug element\n");
+                       goto ERROR;
+               }
+
+               gst_object_unref (sinkpad);
+               sinkpad = NULL;
+
+               /* run. setting PLAYING here since streamming source is live source */
+               MMPLAYER_ELEMENT_SET_STATE( new_element, GST_STATE_PLAYING );
+       }
+
+       debug_fleave();
+
+       return;
+
+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));
+
+       if ( sinkpad )
+               gst_object_unref(GST_OBJECT(sinkpad));
+
+       if ( caps )
+               gst_object_unref(GST_OBJECT(caps));
+
+       /* 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
+        */
+}
+
+void
+__mmplayer_gst_decode_callback(GstElement *decodebin, GstPad *pad, gboolean last, gpointer data) // @
+{
+       mm_player_t* player = NULL;
+       MMHandleType attrs = 0;
+       GstElement* pipeline = NULL;
+       GstCaps* caps = NULL;
+       GstStructure* str = NULL;
+       const gchar* name = NULL;
+       GstPad* sinkpad = NULL;
+       GstElement* sinkbin = NULL;
+
+       /* check handles */
+       player = (mm_player_t*) data;
+
+       return_if_fail( decodebin && pad );
+       return_if_fail(player && player->pipeline && player->pipeline->mainbin);
+
+       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute\n");
+               goto ERROR;
+       }
+
+       /* get mimetype from caps */
+#ifdef GST_API_VERSION_1
+       caps = gst_pad_get_current_caps( pad );
+#else
+       caps = gst_pad_get_caps( pad );
+#endif
+       if ( !caps )
+       {
+               debug_error("cannot get caps from pad.\n");
+               goto ERROR;
+       }
+
+       str = gst_caps_get_structure( caps, 0 );
+       if ( ! str )
+       {
+               debug_error("cannot get structure from capse.\n");
+               goto ERROR;
+       }
+
+       name = gst_structure_get_name(str);
+       if ( ! name )
+       {
+               debug_error("cannot get mimetype from structure.\n");
+               goto ERROR;
+       }
+
+       debug_log("detected mimetype : %s\n", name);
+
+       if (strstr(name, "audio"))
+       {
+               if (player->pipeline->audiobin == NULL)
+               {
+                       __ta__("__mmplayer_gst_create_audio_pipeline",
+                               if (MM_ERROR_NONE !=  __mmplayer_gst_create_audio_pipeline(player))
+                               {
+                                       debug_error("failed to create audiobin. continuing without audio\n");
+                                       goto ERROR;
+                               }
+                       )
+
+                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
+                       debug_log("creating audiosink bin success\n");
+               }
+               else
+               {
+                       sinkbin = player->pipeline->audiobin[MMPLAYER_A_BIN].gst;
+                       debug_log("re-using audiobin\n");
+               }
+
+               /* FIXIT : track number shouldn't be hardcoded */
+               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 )
+               {
+                       debug_error("failed to get pad from sinkbin\n");
+                       goto ERROR;
+               }
+       }
+       else if (strstr(name, "video"))
+       {
+               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);
+
+                       if (surface_type == MM_DISPLAY_SURFACE_NULL)
+                       {
+                               debug_log("not make videobin because it dose not want\n");
+                               goto ERROR;
+                       }
+
+                       __ta__("__mmplayer_gst_create_video_pipeline",
+                       if (MM_ERROR_NONE !=  __mmplayer_gst_create_video_pipeline(player, caps, surface_type) )
+                       {
+                               debug_error("failed to create videobin. continuing without video\n");
+                               goto ERROR;
+                       }
+                       )
+
+                       sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
+                       debug_log("creating videosink bin success\n");
+               }
+               else
+               {
+                       sinkbin = player->pipeline->videobin[MMPLAYER_V_BIN].gst;
+                       debug_log("re-using videobin\n");
+               }
+
+               /* FIXIT : track number shouldn't be hardcoded */
+               mm_attrs_set_int_by_name(attrs, "content_video_track_num", 1);
+               player->videosink_linked  = 1;
+
+               sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "sink" );
+               if ( !sinkpad )
+               {
+                       debug_error("failed to get pad from sinkbin\n");
+                       goto ERROR;
+               }
+       }
+       else if (strstr(name, "text"))
+       {
+               if (player->pipeline->textbin == NULL)
+               {
+                       __ta__("__mmplayer_gst_create_text_pipeline",
+                               if (MM_ERROR_NONE !=  __mmplayer_gst_create_text_pipeline(player))
+                               {
+                                       debug_error("failed to create textbin. continuing without text\n");
+                                       goto ERROR;
+                               }
+                       )
+
+                       sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
+                       debug_log("creating textink bin success\n");
+               }
+               else
+               {
+                       sinkbin = player->pipeline->textbin[MMPLAYER_T_BIN].gst;
+                       debug_log("re-using textbin\n");
+               }
+
+                       /* FIXIT : track number shouldn't be hardcoded */
+                       mm_attrs_set_int_by_name(attrs, "content_text_track_num", 1);
+
+                       player->textsink_linked  = 1;
+                       debug_msg("player->textsink_linked set to 1\n");
+
+               sinkpad = gst_element_get_static_pad( GST_ELEMENT(sinkbin), "text_sink" );
+               if ( !sinkpad )
+               {
+                       debug_error("failed to get pad from sinkbin\n");
+                       goto ERROR;
+               }
+       }
+       else
+       {
+               debug_warning("unknown type of elementary stream! ignoring it...\n");
+               goto ERROR;
+       }
+
+       if ( sinkbin )
+       {
+               /* warm up */
+               if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state( sinkbin, GST_STATE_READY ) )
+               {
+                       debug_error("failed to set state(READY) to sinkbin\n");
+                       goto ERROR;
+               }
+
+               /* add */
+               if ( FALSE == gst_bin_add( GST_BIN(pipeline), sinkbin ) )
+               {
+                       debug_error("failed to add sinkbin to pipeline\n");
+                       goto ERROR;
+               }
+
+               /* link */
+               if ( GST_PAD_LINK_OK != GST_PAD_LINK(pad, sinkpad) )
+               {
+                       debug_error("failed to get pad from sinkbin\n");
+                       goto ERROR;
+               }
+
+               /* run */
+               if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state( sinkbin, GST_STATE_PAUSED ) )
+               {
+                       debug_error("failed to set state(PLAYING) to sinkbin\n");
+                       goto ERROR;
+               }
+
+               gst_object_unref( sinkpad );
+               sinkpad = NULL;
+       }
+
+       debug_log("linking sink bin success\n");
+
+       /* 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 */
+       player->num_dynamic_pad--;
+
+       debug_log("stream count dec : %d (num of dynamic pad)\n", player->num_dynamic_pad);
+
+       if ( ( player->no_more_pad ) && ( player->num_dynamic_pad == 0 ) )
+       {
+               __mmplayer_pipeline_complete( NULL, player );
+       }
+
+ERROR:
+       if ( caps )
+               gst_caps_unref( caps );
+
+       if ( sinkpad )
+               gst_object_unref(GST_OBJECT(sinkpad));
+
+       /* flusing out new attributes */
+       if (  mmf_attrs_commit ( attrs ) )
+       {
+               debug_error("failed to comit attributes\n");
+       }
+
+       return;
+}
+
+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;
+
+       debug_fenter();
+
+       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 ( GST_ELEMENT_LINK(GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst)) )
+                       {
+                               debug_log("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
+                       {
+                               debug_log("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;
+       }
+
+       debug_fleave();
+
+       return successful_link_count;
+}
+
+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;
+
+       debug_fenter();
+
+       return_val_if_fail(element_bucket, 0);
+       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)) )
+                       {
+                               debug_log("__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 ++;
+               }
+       }
+
+       debug_fleave();
+
+       return successful_add_count;
+}
+
+/**
+ * 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
+ */
+#define MMPLAYER_CREATEONLY_ELEMENT(x_bin, x_id, x_factory, x_name) \
+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 )\
+{\
+       debug_critical("failed to create %s \n", x_factory);\
+       goto ERROR;\
+}\
+
+#define MMPLAYER_CREATE_ELEMENT_ADD_BIN(x_bin, x_id, x_factory, x_name, y_bin) \
+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 )\
+{\
+       debug_critical("failed to create %s \n", x_factory);\
+       goto ERROR;\
+}\
+if( !gst_bin_add(GST_BIN(y_bin), GST_ELEMENT(x_bin[x_id].gst)))\
+{\
+       debug_log("__mmplayer_gst_element_link_bucket : Adding element [%s]  to bin [%s] failed\n",\
+               GST_ELEMENT_NAME(GST_ELEMENT(x_bin[x_id].gst)),\
+               GST_ELEMENT_NAME(GST_ELEMENT(y_bin) ) );\
+       goto ERROR;\
+}\
+
+/* macro for code readability. just for sinkbin-creation functions */
+#define MMPLAYER_CREATE_ELEMENT(x_bin, x_id, x_factory, x_name, x_add_bucket) \
+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 )\
+       {\
+               debug_critical("failed to create %s \n", x_factory);\
+               goto ERROR;\
+       }\
+       if ( x_add_bucket )\
+               element_bucket = g_list_append(element_bucket, &x_bin[x_id]);\
+} while(0);
+
+/**
+  * AUDIO PIPELINE
+  * - Local playback   : audioconvert !volume ! capsfilter ! audioeq ! audiosink
+  * - Streaming                : audioconvert !volume ! audiosink
+  * - PCM extraction   : audioconvert ! audioresample ! capsfilter ! fakesink
+  */
+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;
+       char *device_name = NULL;
+       gboolean link_audio_sink_now = TRUE;
+       int i =0;
+
+       debug_fenter();
+
+       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 )
+       {
+               debug_error("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 )
+       {
+               debug_critical("failed to create audiobin\n");
+               goto ERROR;
+       }
+
+       /* take it */
+       player->pipeline->audiobin = audiobin;
+
+       player->is_sound_extraction = __mmplayer_can_extract_pcm(player);
+
+       /* Adding audiotp plugin for reverse trickplay feature */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_TP, "audiotp", "audiotrickplay", TRUE);
+
+       /* converter */
+       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CONV, "audioconvert", "audioconverter", TRUE);
+
+       if ( ! player->is_sound_extraction )
+       {
+               GstCaps* caps = NULL;
+               gint channels = 0;
+
+               /* for logical volume control */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_VOL, "volume", "volume", TRUE);
+               g_object_set(G_OBJECT (audiobin[MMPLAYER_A_VOL].gst), "volume", player->sound.volume, NULL);
+
+               if (player->sound.mute)
+               {
+                       debug_log("mute enabled\n");
+                       g_object_set(G_OBJECT (audiobin[MMPLAYER_A_VOL].gst), "mute", player->sound.mute, NULL);
+               }
+
+               /*capsfilter */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_CAPS_DEFAULT, "capsfilter", "audiocapsfilter", TRUE);
+
+               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 );
+
+               /* chech if multi-chennels */
+               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")))
+                       {
+#ifdef GST_API_VERSION_1
+                               if ((caps = gst_pad_get_current_caps(srcpad)))
+                               {
+                                       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);
+                               }
+#else
+                               if ((caps = gst_pad_get_caps(srcpad)))
+                               {
+                                       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);
+                               }
+#endif
+                               gst_object_unref(srcpad);
+                       }
+               }
+
+               /* audio effect element. if audio effect is enabled */
+               if ( channels <= 2 && (PLAYER_INI()->use_audio_effect_preset || PLAYER_INI()->use_audio_effect_custom) )
+               {
+                       MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_FILTER, PLAYER_INI()->name_of_audio_effect, "audiofilter", TRUE);
+               }
+
+               /* create audio sink */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, PLAYER_INI()->name_of_audiosink,
+                       "audiosink", link_audio_sink_now);
+
+               /* sync on */
+               if (MMPLAYER_IS_RTSP_STREAMING(player))
+                       g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", FALSE, NULL);   /* sync off */
+               else
+                       g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", TRUE, NULL);    /* sync on */
+
+               /* qos on */
+               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "qos", TRUE, NULL);     /* qos on */
+
+               /* FIXIT : using system clock. isn't there another way? */
+               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "provide-clock", PLAYER_INI()->provide_clock,  NULL);
+
+               __mmplayer_add_sink( player, audiobin[MMPLAYER_A_SINK].gst );
+
+                       if(player->audio_buffer_cb)
+                       {
+                               g_object_set(audiobin[MMPLAYER_A_SINK].gst, "audio-handle", player->audio_buffer_cb_user_param, NULL);
+                               g_object_set(audiobin[MMPLAYER_A_SINK].gst, "audio-callback", player->audio_buffer_cb, NULL);
+                       }
+
+               if ( g_strrstr(PLAYER_INI()->name_of_audiosink, "avsysaudiosink") )
+               {
+                       gint volume_type = 0;
+                       gint audio_route = 0;
+                       gint sound_priority = FALSE;
+                       gint is_spk_out_only = 0;
+                       gint latency_mode = 0;
+
+                       /* set volume table
+                        * It should be set after player creation through attribute.
+                        * But, it can not be changed during playing.
+                        */
+                       mm_attrs_get_int_by_name(attrs, "sound_volume_type", &volume_type);
+                       mm_attrs_get_int_by_name(attrs, "sound_route", &audio_route);
+                       mm_attrs_get_int_by_name(attrs, "sound_priority", &sound_priority);
+                       mm_attrs_get_int_by_name(attrs, "sound_spk_out_only", &is_spk_out_only);
+                       mm_attrs_get_int_by_name(attrs, "audio_latency_mode", &latency_mode);
+
+                       /* hook sound_type if emergency case */
+                       if ( player->sm.event == ASM_EVENT_EMERGENCY)
+                       {
+                               debug_log ("This is emergency session, hook sound_type from [%d] to [%d]\n", volume_type, MM_SOUND_VOLUME_TYPE_EMERGENCY);
+                               volume_type = MM_SOUND_VOLUME_TYPE_EMERGENCY;
+                       }
+
+                       g_object_set(audiobin[MMPLAYER_A_SINK].gst,
+                                       "volumetype", volume_type,
+                                       "audio-route", audio_route,
+                                       "priority", sound_priority,
+                                       "user-route", is_spk_out_only,
+                                       "latency", latency_mode,
+                                       NULL);
+
+                       debug_log("audiosink property status...volume type:%d, route:%d, priority=%d, user-route=%d, latency=%d\n",
+                               volume_type, audio_route, sound_priority, is_spk_out_only, latency_mode);
+               }
+
+               /* Antishock can be enabled when player is resumed by soundCM.
+                * But, it's not used in MMS, setting and etc.
+                * Because, player start seems like late.
+                */
+               __mmplayer_set_antishock( player , FALSE );
+       }
+       else // pcm extraction only and no sound output
+       {
+               int dst_samplerate = 0;
+               int dst_channels = 0;
+               int dst_depth = 0;
+               char *caps_type = NULL;
+               GstCaps* caps = NULL;
+
+               /* resampler */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_RESAMPLER, "audioresample", "resampler", TRUE);
+
+               /* 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", "audiocapsfilter", TRUE);
+
+               caps = gst_caps_new_simple ("audio/x-raw-int",
+                                               "rate", G_TYPE_INT, dst_samplerate,
+                                               "channels", G_TYPE_INT, dst_channels,
+                                               "depth", G_TYPE_INT, dst_depth,
+                                               NULL);
+
+               caps_type = gst_caps_to_string(caps);
+               debug_log("resampler new caps : %s\n", caps_type);
+
+               g_object_set (GST_ELEMENT(audiobin[MMPLAYER_A_CAPS_DEFAULT].gst), "caps", caps, NULL );
+
+               /* clean */
+               gst_caps_unref( caps );
+               MMPLAYER_FREEIF( caps_type );
+
+               /* fake sink */
+               MMPLAYER_CREATE_ELEMENT(audiobin, MMPLAYER_A_SINK, "fakesink", "fakesink", TRUE);
+
+               /* set sync */
+               g_object_set (G_OBJECT (audiobin[MMPLAYER_A_SINK].gst), "sync", FALSE, NULL);
+
+               __mmplayer_add_sink( player, audiobin[MMPLAYER_A_SINK].gst );
+       }
+
+       /* adding created elements to bin */
+       debug_log("adding created elements to bin\n");
+       if( !__mmplayer_gst_element_add_bucket_to_bin( GST_BIN(audiobin[MMPLAYER_A_BIN].gst), element_bucket ))
+       {
+               debug_error("failed to add elements\n");
+               goto ERROR;
+       }
+
+       /* linking elements in the bucket by added order. */
+       debug_log("Linking elements in the bucket by added order.\n");
+       if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
+       {
+               debug_error("failed to link elements\n");
+               goto ERROR;
+       }
+
+               /* get first element's sinkpad for creating ghostpad */
+               first_element = (MMPlayerGstElement *)element_bucket->data;
+
+               pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
+       if ( ! pad )
+       {
+               debug_error("failed to get pad from first element of audiobin\n");
+               goto ERROR;
+       }
+
+       ghostpad = gst_ghost_pad_new("sink", pad);
+       if ( ! ghostpad )
+       {
+               debug_error("failed to create ghostpad\n");
+               goto ERROR;
+       }
+
+       if ( FALSE == gst_element_add_pad(audiobin[MMPLAYER_A_BIN].gst, ghostpad) )
+       {
+               debug_error("failed to add ghostpad to audiobin\n");
+               goto ERROR;
+       }
+
+       gst_object_unref(pad);
+
+       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_PRESET )
+               {
+                       if (!_mmplayer_audio_effect_preset_apply(player, player->audio_effect_info.preset))
+                       {
+                               debug_msg("apply audio effect(preset:%d) setting success\n",player->audio_effect_info.preset);
+                       }
+               }
+               else if ( player->audio_effect_info.effect_type == MM_AUDIO_EFFECT_TYPE_CUSTOM )
+               {
+                       if (!_mmplayer_audio_effect_custom_apply(player))
+                       {
+                               debug_msg("apply audio effect(custom) setting success\n");
+                       }
+               }
+       }
+
+       /* done. free allocated variables */
+       MMPLAYER_FREEIF( device_name );
+       g_list_free(element_bucket);
+
+       mm_attrs_set_int_by_name(attrs, "content_audio_found", TRUE);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+
+ERROR:
+
+       debug_log("ERROR : releasing audiobin\n");
+
+       MMPLAYER_FREEIF( device_name );
+
+       if ( pad )
+               gst_object_unref(GST_OBJECT(pad));
+
+       if ( ghostpad )
+               gst_object_unref(GST_OBJECT(ghostpad));
+
+       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;
+}
+
+/**
+ * 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
+  * - x surface (arm/x86) : videoflip ! xvimagesink
+  * - evas surface  (arm) : fimcconvert ! evasimagesink
+  * - evas surface  (x86) : videoconvertor ! videoflip ! evasimagesink
+  */
+int
+__mmplayer_gst_create_video_pipeline(mm_player_t* player, GstCaps* caps, MMDisplaySurfaceType surface_type)
+{
+       GstPad *pad = NULL;
+       MMHandleType attrs;
+       GList*element_bucket = NULL;
+       MMPlayerGstElement* first_element = NULL;
+       MMPlayerGstElement* videobin = NULL;
+       gchar* vconv_factory = NULL;
+       gchar *videosink_element = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       /* alloc handles */
+       videobin = (MMPlayerGstElement*)g_malloc0(sizeof(MMPlayerGstElement) * MMPLAYER_V_NUM);
+       if ( !videobin )
+       {
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;
+       }
+
+       player->pipeline->videobin = videobin;
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       /* 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 )
+       {
+               debug_critical("failed to create videobin");
+               goto ERROR;
+       }
+
+       if( player->use_video_stream ) // video stream callback, so send raw video data to application
+       {
+               GstStructure *str = NULL;
+               gint ret = 0;
+
+               debug_log("using memsink\n");
+
+               /* first, create colorspace convert */
+               if (player->is_nv12_tiled)
+               {
+                       vconv_factory = "fimcconvert";
+               }
+               else // get video converter from player ini file
+               {
+                       if (strlen(PLAYER_INI()->name_of_video_converter) > 0)
+                       {
+                               vconv_factory = PLAYER_INI()->name_of_video_converter;
+                       }
+               }
+
+               if (vconv_factory)
+               {
+                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CONV, vconv_factory, "video converter", TRUE);
+               }
+
+               if ( !player->is_nv12_tiled)
+               {
+                       gint width = 0;         //width of video
+                       gint height = 0;                //height of video
+                       GstCaps* video_caps = NULL;
+
+                       /* rotator, scaler and capsfilter */
+            if (strncmp(PLAYER_INI()->videosink_element_x, "vaapisink", strlen("vaapisink"))){
+                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_FLIP, "videoflip", "video rotator", TRUE);
+                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SCALE, "videoscale", "video scaler", TRUE);
+                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CAPS, "capsfilter", "videocapsfilter", TRUE);
+            }
+
+                       /* get video stream caps parsed by demuxer */
+                       str = gst_caps_get_structure (player->v_stream_caps, 0);
+                       if ( !str )
+                       {
+                               debug_error("cannot get structure");
+                               goto ERROR;
+                       }
+
+                       mm_attrs_get_int_by_name(attrs, "display_width", &width);
+                       mm_attrs_get_int_by_name(attrs, "display_height", &height);
+                       if (!width || !height) {
+                               /* we set width/height of original media's size  to capsfilter for scaling video */
+                               ret = gst_structure_get_int (str, "width", &width);
+                               if ( !ret )
+                               {
+                                       debug_error("cannot get width");
+                                       goto ERROR;
+                               }
+
+                               ret = gst_structure_get_int(str, "height", &height);
+                               if ( !ret )
+                               {
+                                       debug_error("cannot get height");
+                                       goto ERROR;
+                               }
+                       }
+
+                       video_caps = gst_caps_new_simple( "video/x-raw-rgb",
+                                                                                       "width", G_TYPE_INT, width,
+                                                                                       "height", G_TYPE_INT, height,
+                                                                                       NULL);
+
+                       g_object_set (GST_ELEMENT(videobin[MMPLAYER_V_CAPS].gst), "caps", video_caps, NULL );
+
+                       gst_caps_unref( video_caps );
+               }
+
+               /* finally, create video sink. output will be BGRA8888. */
+               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, "avsysmemsink", "videosink", TRUE);
+
+               MMPLAYER_SIGNAL_CONNECT( player,
+                                                                        videobin[MMPLAYER_V_SINK].gst,
+                                                                        "video-stream",
+                                                                        G_CALLBACK(__mmplayer_videostream_cb),
+                                                                        player );
+       }
+       else // render video data using sink plugin like xvimagesink
+       {
+               debug_log("using videosink");
+
+               /* set video converter */
+               if (strlen(PLAYER_INI()->name_of_video_converter) > 0)
+               {
+                       vconv_factory = PLAYER_INI()->name_of_video_converter;
+
+                       if ( (player->is_nv12_tiled && (surface_type == MM_DISPLAY_SURFACE_EVAS) &&
+                               !strcmp(PLAYER_INI()->videosink_element_evas, "evasimagesink") ) )
+                       {
+                               vconv_factory = "fimcconvert";
+                       }
+                       else if (player->is_nv12_tiled)
+                       {
+                               vconv_factory = NULL;
+                       }
+
+                       if (vconv_factory)
+                       {
+                               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_CONV, vconv_factory, "video converter", TRUE);
+                               debug_log("using video converter: %s", vconv_factory);
+                       }
+               }
+
+        if (strncmp(PLAYER_INI()->videosink_element_x,"vaapisink", strlen("vaapisink"))){
+               /* set video rotator */
+               if ( !player->is_nv12_tiled )
+                       MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_FLIP, "videoflip", "video rotator", TRUE);
+
+               /* videoscaler */
+               #if !defined(__arm__)
+               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SCALE, "videoscale", "videoscaler", TRUE);
+               #endif
+        }
+
+               /* set video sink */
+               switch (surface_type)
+               {
+               case MM_DISPLAY_SURFACE_X:
+                       if (strlen(PLAYER_INI()->videosink_element_x) > 0)
+                               videosink_element = PLAYER_INI()->videosink_element_x;
+                       else
+                               goto ERROR;
+                       break;
+               case MM_DISPLAY_SURFACE_EVAS:
+                       if (strlen(PLAYER_INI()->videosink_element_evas) > 0)
+                               videosink_element = PLAYER_INI()->videosink_element_evas;
+                       else
+                               goto ERROR;
+                       break;
+               case MM_DISPLAY_SURFACE_X_EXT:
+               {
+                       void *pixmap_id_cb = NULL;
+                       mm_attrs_get_data_by_name(attrs, "display_overlay", &pixmap_id_cb);
+                       if (pixmap_id_cb) /* this is used for the videoTextue(canvasTexture) overlay */
+                       {
+                               videosink_element = PLAYER_INI()->videosink_element_x;
+                       }
+                       else
+                       {
+                               debug_error("something wrong.. callback function for getting pixmap id is null");
+                               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;
+               default:
+                       debug_error("unidentified surface type");
+                       goto ERROR;
+               }
+
+               MMPLAYER_CREATE_ELEMENT(videobin, MMPLAYER_V_SINK, videosink_element, videosink_element, TRUE);
+               debug_log("selected videosink name: %s", videosink_element);
+
+               /* connect signal handlers for sink plug-in */
+               switch (surface_type) {
+               case MM_DISPLAY_SURFACE_X_EXT:
+                       MMPLAYER_SIGNAL_CONNECT( player,
+                                                                       player->pipeline->videobin[MMPLAYER_V_SINK].gst,
+                                                                       "frame-render-error",
+                                                                       G_CALLBACK(__mmplayer_videoframe_render_error_cb),
+                                                                       player );
+                       debug_log("videoTexture usage, connect a signal handler for pixmap rendering error");
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if ( _mmplayer_update_video_param(player) != MM_ERROR_NONE)
+               goto ERROR;
+
+       /* qos on */
+       g_object_set (G_OBJECT (videobin[MMPLAYER_V_SINK].gst), "qos", TRUE, NULL);
+
+       /* store it as it's sink element */
+       __mmplayer_add_sink( player, videobin[MMPLAYER_V_SINK].gst );
+
+       /* adding created elements to bin */
+       if( ! __mmplayer_gst_element_add_bucket_to_bin(GST_BIN(videobin[MMPLAYER_V_BIN].gst), element_bucket) )
+       {
+               debug_error("failed to add elements\n");
+               goto ERROR;
+       }
+
+       /* Linking elements in the bucket by added order */
+       if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
+       {
+               debug_error("failed to link elements\n");
+               goto ERROR;
+       }
+
+       /* get first element's sinkpad for creating ghostpad */
+       first_element = (MMPlayerGstElement *)element_bucket->data;
+       if ( !first_element )
+       {
+               debug_error("failed to get first element from bucket\n");
+               goto ERROR;
+       }
+
+       pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
+       if ( !pad )
+       {
+               debug_error("failed to get pad from first element\n");
+               goto ERROR;
+       }
+
+       /* create ghostpad */
+       if (FALSE == gst_element_add_pad(videobin[MMPLAYER_V_BIN].gst, gst_ghost_pad_new("sink", pad)))
+       {
+               debug_error("failed to add ghostpad to videobin\n");
+               goto ERROR;
+       }
+       gst_object_unref(pad);
+
+       /* done. free allocated variables */
+       g_list_free(element_bucket);
+
+       mm_attrs_set_int_by_name(attrs, "content_video_found", TRUE);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+
+ERROR:
+       debug_error("ERROR : releasing videobin\n");
+
+       g_list_free( element_bucket );
+
+       if (pad)
+               gst_object_unref(GST_OBJECT(pad));
+
+       /* release videobin with it's childs */
+       if ( videobin[MMPLAYER_V_BIN].gst )
+       {
+               gst_object_unref(GST_OBJECT(videobin[MMPLAYER_V_BIN].gst));
+       }
+
+
+       MMPLAYER_FREEIF( videobin );
+
+       player->pipeline->videobin = NULL;
+
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+int __mmplayer_gst_create_text_pipeline(mm_player_t* player)
+{
+       MMPlayerGstElement* first_element = NULL;
+       MMPlayerGstElement* textbin = NULL;
+       GList* element_bucket = NULL;
+       GstPad *pad = NULL;
+       GstPad *ghostpad = NULL;
+       gint i = 0;
+
+       debug_fenter();
+
+       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 )
+       {
+               debug_error("failed to allocate memory for textbin\n");
+               return MM_ERROR_PLAYER_NO_FREE_SPACE;
+       }
+
+       /* 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 )
+       {
+               debug_critical("failed to create textbin\n");
+               goto ERROR;
+       }
+
+       /* take it */
+       player->pipeline->textbin = textbin;
+
+       /* fakesink */
+       if (player->use_textoverlay)
+       {
+               debug_log ("use textoverlay for displaying \n");
+
+               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_TEXT_QUEUE, "queue", "text_t_queue", textbin[MMPLAYER_T_BIN].gst);
+
+               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_VIDEO_QUEUE, "queue", "text_v_queue", textbin[MMPLAYER_T_BIN].gst);
+
+               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_VIDEO_CONVERTER, "fimcconvert", "text_v_converter", textbin[MMPLAYER_T_BIN].gst);
+
+               MMPLAYER_CREATE_ELEMENT_ADD_BIN(textbin, MMPLAYER_T_OVERLAY, "textoverlay", "text_overlay", textbin[MMPLAYER_T_BIN].gst);
+
+               if (!gst_element_link_pads (textbin[MMPLAYER_T_VIDEO_QUEUE].gst, "src", textbin[MMPLAYER_T_VIDEO_CONVERTER].gst, "sink"))
+               {
+                       debug_error("failed to link queue and converter\n");
+                       goto ERROR;
+               }
+
+               if (!gst_element_link_pads (textbin[MMPLAYER_T_VIDEO_CONVERTER].gst, "src", textbin[MMPLAYER_T_OVERLAY].gst, "video_sink"))
+               {
+                       debug_error("failed to link queue and textoverlay\n");
+                       goto ERROR;
+               }
+
+               if (!gst_element_link_pads (textbin[MMPLAYER_T_TEXT_QUEUE].gst, "src", textbin[MMPLAYER_T_OVERLAY].gst, "text_sink"))
+               {
+                       debug_error("failed to link queue and textoverlay\n");
+                       goto ERROR;
+               }
+
+       }
+       else
+       {
+               debug_log ("use subtitle message for displaying \n");
+
+               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_TEXT_QUEUE, "queue", "text_queue", TRUE);
+
+               MMPLAYER_CREATE_ELEMENT(textbin, MMPLAYER_T_SINK, "fakesink", "text_sink", TRUE);
+
+               g_object_set (G_OBJECT (textbin[MMPLAYER_T_SINK].gst), "sync", TRUE, NULL);
+               g_object_set (G_OBJECT (textbin[MMPLAYER_T_SINK].gst), "async", FALSE, NULL);
+               g_object_set (G_OBJECT (textbin[MMPLAYER_T_SINK].gst), "signal-handoffs", TRUE, NULL);
+
+               MMPLAYER_SIGNAL_CONNECT( player,
+                                                               G_OBJECT(textbin[MMPLAYER_T_SINK].gst),
+                                                               "handoff",
+                                                               G_CALLBACK(__mmplayer_update_subtitle),
+                                                               (gpointer)player );
+
+               if (!player->play_subtitle)
+               {
+                       debug_log ("add textbin sink as sink element of whole pipeline.\n");
+                       __mmplayer_add_sink (player, GST_ELEMENT(textbin[MMPLAYER_T_SINK].gst));
+               }
+
+               /* adding created elements to bin */
+               debug_log("adding created elements to bin\n");
+               if( !__mmplayer_gst_element_add_bucket_to_bin( GST_BIN(textbin[MMPLAYER_T_BIN].gst), element_bucket ))
+               {
+                       debug_error("failed to add elements\n");
+                       goto ERROR;
+               }
+
+               /* linking elements in the bucket by added order. */
+               debug_log("Linking elements in the bucket by added order.\n");
+               if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
+               {
+                       debug_error("failed to link elements\n");
+                       goto ERROR;
+               }
+
+               /* done. free allocated variables */
+               g_list_free(element_bucket);
+       }
+
+       if (textbin[MMPLAYER_T_TEXT_QUEUE].gst)
+       {
+               pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_TEXT_QUEUE].gst), "sink");
+               if (!pad)
+               {
+                       debug_error("failed to get text pad of textbin\n");
+                       goto ERROR;
+               }
+
+               ghostpad = gst_ghost_pad_new("text_sink", pad);
+               if (!ghostpad)
+               {
+                       debug_error("failed to create ghostpad of textbin\n");
+                       goto ERROR;
+               }
+
+               if ( FALSE == gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad) )
+               {
+                       debug_error("failed to add ghostpad to textbin\n");
+                       goto ERROR;
+               }
+       }
+
+       if (textbin[MMPLAYER_T_VIDEO_QUEUE].gst)
+       {
+               pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_VIDEO_QUEUE].gst), "sink");
+               if (!pad)
+               {
+                       debug_error("failed to get video pad of textbin\n");
+                       goto ERROR;
+               }
+
+               ghostpad = gst_ghost_pad_new("video_sink", pad);
+               if (!ghostpad)
+               {
+                       debug_error("failed to create ghostpad of textbin\n");
+                       goto ERROR;
+               }
+
+               if (!gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad))
+               {
+                       debug_error("failed to add ghostpad to textbin\n");
+                       goto ERROR;
+               }
+       }
+
+       if (textbin[MMPLAYER_T_OVERLAY].gst)
+       {
+               pad = gst_element_get_static_pad(GST_ELEMENT(textbin[MMPLAYER_T_OVERLAY].gst), "src");
+               if (!pad)
+               {
+                       debug_error("failed to get src pad of textbin\n");
+                       goto ERROR;
+               }
+
+               ghostpad = gst_ghost_pad_new("src", pad);
+               if (!ghostpad)
+               {
+                       debug_error("failed to create ghostpad of textbin\n");
+                       goto ERROR;
+               }
+
+               if (!gst_element_add_pad(textbin[MMPLAYER_T_BIN].gst, ghostpad))
+               {
+                       debug_error("failed to add ghostpad to textbin\n");
+                       goto ERROR;
+               }
+       }
+
+       gst_object_unref(pad);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+
+ERROR:
+
+       debug_log("ERROR : releasing textbin\n");
+
+       if ( pad )
+               gst_object_unref(GST_OBJECT(pad));
+
+       if ( ghostpad )
+               gst_object_unref(GST_OBJECT(ghostpad));
+
+       g_list_free( element_bucket );
+
+
+       /* 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 ( !parent )
+                       {
+                               gst_object_unref(GST_OBJECT(textbin[i].gst));
+                               textbin[i].gst = NULL;
+                       }
+                       else
+                       {
+                               gst_object_unref(GST_OBJECT(parent));
+                       }
+               }
+       }
+
+       /* release textbin with it's childs */
+       if ( textbin[MMPLAYER_T_BIN].gst )
+       {
+               gst_object_unref(GST_OBJECT(textbin[MMPLAYER_T_BIN].gst));
+       }
+
+       MMPLAYER_FREEIF( textbin );
+
+       player->pipeline->textbin = NULL;
+
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+int
+__mmplayer_gst_create_subtitle_src(mm_player_t* player)
+{
+       MMPlayerGstElement* mainbin = NULL;
+       MMHandleType attrs = 0;
+       GstElement * pipeline = NULL;
+       GstElement *subsrc = NULL;
+       GstElement *subparse = NULL;
+       GstPad *sinkpad = NULL;
+       gchar *subtitle_uri =NULL;
+       gchar *charset = NULL;
+
+       debug_fenter();
+
+       /* get mainbin */
+       return_val_if_fail ( player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       pipeline = player->pipeline->mainbin[MMPLAYER_M_PIPE].gst;
+       mainbin = player->pipeline->mainbin;
+
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute\n");
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       mm_attrs_get_string_by_name ( attrs, "subtitle_uri", &subtitle_uri );
+       if ( !subtitle_uri || strlen(subtitle_uri) < 1)
+       {
+               debug_error("subtitle uri is not proper filepath.\n");
+               return MM_ERROR_PLAYER_INVALID_URI;
+       }
+       debug_log("subtitle file path is [%s].\n", subtitle_uri);
+
+
+       /* create the subtitle source */
+       subsrc = gst_element_factory_make("filesrc", "subtitle_source");
+       if ( !subsrc )
+       {
+               debug_error ( "failed to create filesrc element\n" );
+               goto ERROR;
+       }
+       g_object_set(G_OBJECT (subsrc), "location", subtitle_uri, NULL);
+
+       mainbin[MMPLAYER_M_SUBSRC].id = MMPLAYER_M_SUBSRC;
+       mainbin[MMPLAYER_M_SUBSRC].gst = subsrc;
+
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subsrc))
+       {
+               debug_warning("failed to add queue\n");
+               goto ERROR;
+       }
+
+       /* subparse */
+       subparse = gst_element_factory_make("subparse", "subtitle_parser");
+       if ( !subparse )
+       {
+               debug_error ( "failed to create subparse element\n" );
+               goto ERROR;
+       }
+
+       charset = util_get_charset(subtitle_uri);
+       if (charset)
+       {
+               debug_log ("detected charset is %s\n", charset );
+               g_object_set (G_OBJECT (subparse), "subtitle-encoding", charset, NULL);
+       }
+
+       mainbin[MMPLAYER_M_SUBPARSE].id = MMPLAYER_M_SUBPARSE;
+       mainbin[MMPLAYER_M_SUBPARSE].gst = subparse;
+
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), subparse))
+       {
+               debug_warning("failed to add subparse\n");
+               goto ERROR;
+       }
+
+       if (!gst_element_link_pads (subsrc, "src", subparse, "sink"))
+       {
+               debug_warning("failed to link subsrc and subparse\n");
+               goto ERROR;
+       }
+
+       player->play_subtitle = TRUE;
+       debug_log ("play subtitle using subtitle file\n");
+
+       if (MM_ERROR_NONE !=  __mmplayer_gst_create_text_pipeline(player))
+       {
+               debug_error("failed to create textbin. continuing without text\n");
+               goto ERROR;
+       }
+
+       if (!gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), GST_ELEMENT(player->pipeline->textbin[MMPLAYER_T_BIN].gst)))
+       {
+               debug_warning("failed to add textbin\n");
+               goto ERROR;
+       }
+
+       if (!gst_element_link_pads (subparse, "src", player->pipeline->textbin[MMPLAYER_T_BIN].gst, "text_sink"))
+       {
+               debug_warning("failed to link subparse and textbin\n");
+               goto ERROR;
+       }
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+
+
+ERROR:
+       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
+ */
+int
+__mmplayer_gst_create_pipeline(mm_player_t* player) // @
+{
+       GstBus  *bus = NULL;
+       MMPlayerGstElement *mainbin = NULL;
+       MMHandleType attrs = 0;
+       GstElement* element = NULL;
+       GList* element_bucket = NULL;
+       gboolean need_state_holder = TRUE;
+       gint i = 0;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       /* get profile attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+       {
+               debug_error("cannot get content attribute\n");
+               goto INIT_ERROR;
+       }
+
+       /* create pipeline handles */
+       if ( player->pipeline )
+       {
+               debug_warning("pipeline should be released before create new one\n");
+               goto INIT_ERROR;
+       }
+
+       player->pipeline = (MMPlayerGstPipelineInfo*) g_malloc0( sizeof(MMPlayerGstPipelineInfo) );
+       if (player->pipeline == NULL)
+               goto INIT_ERROR;
+
+       memset( player->pipeline, 0, sizeof(MMPlayerGstPipelineInfo) );
+
+
+       /* create mainbin */
+       mainbin = (MMPlayerGstElement*) g_malloc0( sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM );
+       if (mainbin == NULL)
+               goto INIT_ERROR;
+
+       memset( mainbin, 0, sizeof(MMPlayerGstElement) * MMPLAYER_M_NUM);
+
+
+       /* 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 )
+       {
+               debug_error("failed to create pipeline\n");
+               goto INIT_ERROR;
+       }
+
+
+       /* create source element */
+       switch ( player->profile.uri_type )
+       {
+               /* rtsp streamming */
+               case MM_PLAYER_URI_TYPE_URL_RTSP:
+               {
+                       gint network_bandwidth;
+                       gchar *user_agent, *wap_profile;
+
+                       element = gst_element_factory_make(PLAYER_INI()->name_of_rtspsrc, "streaming_source");
+
+                       if ( !element )
+                       {
+                               debug_critical("failed to create streaming source element\n");
+                               break;
+                       }
+
+                       debug_log("using streamming source [%s].\n", PLAYER_INI()->name_of_rtspsrc);
+
+                       /* make it zero */
+                       network_bandwidth = 0;
+                       user_agent = wap_profile = NULL;
+
+                       /* get attribute */
+                       mm_attrs_get_string_by_name ( attrs, "streaming_user_agent", &user_agent );
+                       mm_attrs_get_string_by_name ( attrs,"streaming_wap_profile", &wap_profile );
+                       mm_attrs_get_int_by_name ( attrs, "streaming_network_bandwidth", &network_bandwidth );
+
+                       debug_log("setting streaming source ----------------\n");
+                       debug_log("user_agent : %s\n", user_agent);
+                       debug_log("wap_profile : %s\n", wap_profile);
+                       debug_log("network_bandwidth : %d\n", network_bandwidth);
+                       debug_log("buffering time : %d\n", PLAYER_INI()->rtsp_buffering_time);
+                       debug_log("rebuffering time : %d\n", PLAYER_INI()->rtsp_rebuffering_time);
+                       debug_log("-----------------------------------------\n");
+
+                       /* setting property to streaming source */
+                       g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
+                       g_object_set(G_OBJECT(element), "bandwidth", network_bandwidth, NULL);
+                       g_object_set(G_OBJECT(element), "buffering_time", PLAYER_INI()->rtsp_buffering_time, NULL);
+                       g_object_set(G_OBJECT(element), "rebuffering_time", PLAYER_INI()->rtsp_rebuffering_time, NULL);
+                       if ( user_agent )
+                               g_object_set(G_OBJECT(element), "user_agent", user_agent, NULL);
+                       if ( wap_profile )
+                               g_object_set(G_OBJECT(element), "wap_profile", wap_profile, NULL);
+
+                       MMPLAYER_SIGNAL_CONNECT ( player, G_OBJECT(element), "pad-added",
+                               G_CALLBACK (__mmplayer_gst_rtp_dynamic_pad), player );
+                       MMPLAYER_SIGNAL_CONNECT ( player, G_OBJECT(element), "no-more-pads",
+                               G_CALLBACK (__mmplayer_gst_rtp_no_more_pads), player );
+
+                       player->no_more_pad = FALSE;
+                       player->num_dynamic_pad = 0;
+
+                       /* NOTE : we cannot determine it yet. this filed will be filled by
+                        * _mmplayer_update_content_attrs() after START.
+                        */
+                       player->streaming_type = STREAMING_SERVICE_NONE;
+               }
+               break;
+
+               /* http streaming*/
+               case MM_PLAYER_URI_TYPE_URL_HTTP:
+               {
+                       gchar *user_agent, *proxy, *cookies, **cookie_list;
+                       user_agent = proxy = cookies = NULL;
+                       cookie_list = NULL;
+                       gint mode = MM_PLAYER_PD_MODE_NONE;
+
+                       mm_attrs_get_int_by_name ( attrs, "pd_mode", &mode );
+
+                       player->pd_mode = mode;
+
+                       debug_log("http playback, PD mode : %d\n", player->pd_mode);
+
+                       if ( ! MMPLAYER_IS_HTTP_PD(player) )
+                       {
+                               element = gst_element_factory_make(PLAYER_INI()->name_of_httpsrc, "http_streaming_source");
+                               if ( !element )
+                               {
+                                       debug_critical("failed to create http streaming source element[%s].\n", PLAYER_INI()->name_of_httpsrc);
+                                       break;
+                               }
+                               debug_log("using http streamming source [%s].\n", PLAYER_INI()->name_of_httpsrc);
+
+                               /* get attribute */
+                               mm_attrs_get_string_by_name ( attrs, "streaming_cookie", &cookies );
+                               mm_attrs_get_string_by_name ( attrs, "streaming_user_agent", &user_agent );
+                               mm_attrs_get_string_by_name ( attrs, "streaming_proxy", &proxy );
+
+                               /* get attribute */
+                               debug_log("setting http streaming source ----------------\n");
+                               debug_log("location : %s\n", player->profile.uri);
+                               debug_log("cookies : %s\n", cookies);
+                               debug_log("proxy : %s\n", proxy);
+                               debug_log("user_agent :  %s\n",  user_agent);
+                               debug_log("timeout : %d\n",  PLAYER_INI()->http_timeout);
+                               debug_log("-----------------------------------------\n");
+
+                               /* setting property to streaming source */
+                               g_object_set(G_OBJECT(element), "location", player->profile.uri, NULL);
+                               g_object_set(G_OBJECT(element), "timeout", PLAYER_INI()->http_timeout, NULL);
+                               /* check if prosy is vailid or not */
+                               if ( util_check_valid_url ( proxy ) )
+                                       g_object_set(G_OBJECT(element), "proxy", proxy, 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);
+                       }
+                       else // progressive download
+                       {
+                               if (player->pd_mode == MM_PLAYER_PD_MODE_URI)
+                               {
+                                       gchar *path = NULL;
+
+                                       mm_attrs_get_string_by_name ( attrs, "pd_location", &path );
+
+                                       MMPLAYER_FREEIF(player->pd_file_save_path);
+
+                                       debug_log("PD Location : %s\n", path);
+
+                                       if ( path )
+                                       {
+                                               player->pd_file_save_path = g_strdup(path);
+                                       }
+                                       else
+                                       {
+                                               debug_error("can't find pd location so, it should be set \n");
+                                               return MM_ERROR_PLAYER_FILE_NOT_FOUND;
+                                       }
+                               }
+
+                               element = gst_element_factory_make("pdpushsrc", "PD pushsrc");
+                               if ( !element )
+                               {
+                                       debug_critical("failed to create PD push source element[%s].\n", "pdpushsrc");
+                                       break;
+                               }
+
+                               g_object_set(G_OBJECT(element), "location", player->pd_file_save_path, NULL);
+                       }
+
+                       player->streaming_type = STREAMING_SERVICE_NONE;
+               }
+               break;
+
+               /* file source */
+               case MM_PLAYER_URI_TYPE_FILE:
+               {
+                       char* drmsrc = PLAYER_INI()->name_of_drmsrc;
+
+                       debug_log("using [%s] for 'file://' handler.\n", drmsrc);
+
+                       element = gst_element_factory_make(drmsrc, "source");
+                       if ( !element )
+                       {
+                               debug_critical("failed to create %s\n", drmsrc);
+                               break;
+                       }
+
+                       g_object_set(G_OBJECT(element), "location", (player->profile.uri)+7, NULL);     /* uri+7 -> remove "file:// */
+                       //g_object_set(G_OBJECT(element), "use-mmap", TRUE, NULL);
+               }
+               break;
+
+               /* appsrc */
+               case MM_PLAYER_URI_TYPE_BUFF:
+               {
+                       guint64 stream_type = GST_APP_STREAM_TYPE_STREAM;
+
+                       debug_log("mem src is selected\n");
+
+                       element = gst_element_factory_make("appsrc", "buff-source");
+                       if ( !element )
+                       {
+                               debug_critical("failed to create appsrc element\n");
+                               break;
+                       }
+
+                       g_object_set( element, "stream-type", stream_type, NULL );
+                       //g_object_set( element, "size", player->mem_buf.len, NULL );
+                       //g_object_set( element, "blocksize", (guint64)20480, NULL );
+
+                       MMPLAYER_SIGNAL_CONNECT( player, element, "seek-data",
+                               G_CALLBACK(__gst_appsrc_seek_data), player);
+                       MMPLAYER_SIGNAL_CONNECT( player, element, "need-data",
+                               G_CALLBACK(__gst_appsrc_feed_data), player);
+                       MMPLAYER_SIGNAL_CONNECT( player, element, "enough-data",
+                               G_CALLBACK(__gst_appsrc_enough_data), player);
+               }
+               break;
+
+               /* appsrc */
+               case MM_PLAYER_URI_TYPE_MEM:
+               {
+                       guint64 stream_type = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
+
+                       debug_log("mem src is selected\n");
+
+                       element = gst_element_factory_make("appsrc", "mem-source");
+                       if ( !element )
+                       {
+                               debug_critical("failed to create appsrc element\n");
+                               break;
+                       }
+
+                       g_object_set( element, "stream-type", stream_type, NULL );
+                       g_object_set( element, "size", player->mem_buf.len, NULL );
+                       g_object_set( element, "blocksize", (guint64)20480, NULL );
+
+                       MMPLAYER_SIGNAL_CONNECT( player, element, "seek-data",
+                               G_CALLBACK(__gst_appsrc_seek_data_mem), &player->mem_buf );
+                       MMPLAYER_SIGNAL_CONNECT( player, element, "need-data",
+                               G_CALLBACK(__gst_appsrc_feed_data_mem), &player->mem_buf );
+               }
+               break;
+               case MM_PLAYER_URI_TYPE_URL:
+               break;
+
+               case MM_PLAYER_URI_TYPE_TEMP:
+               break;
+
+               case MM_PLAYER_URI_TYPE_NONE:
+               default:
+               break;
+       }
+
+       /* check source element is OK */
+       if ( ! element )
+       {
+               debug_critical("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 = __mm_player_streaming_create();
+               __mm_player_streaming_initialize(player->streamer);
+       }
+
+       if ( MMPLAYER_IS_HTTP_PD(player) )
+       {
+              debug_log ("Picked queue2 element....\n");
+               element = gst_element_factory_make("queue2", "hls_stream_buffer");
+               if ( !element )
+               {
+                       debug_critical ( "failed to create http streaming buffer element\n" );
+                       goto INIT_ERROR;
+               }
+
+               /* take it */
+               mainbin[MMPLAYER_M_S_BUFFER].id = MMPLAYER_M_S_BUFFER;
+               mainbin[MMPLAYER_M_S_BUFFER].gst = element;
+               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_S_BUFFER]);
+
+               __mm_player_streaming_set_buffer(player->streamer,
+                               element,
+                               TRUE,
+                               PLAYER_INI()->http_max_size_bytes,
+                               1.0,
+                               PLAYER_INI()->http_buffering_limit,
+                               PLAYER_INI()->http_buffering_time,
+                               FALSE,
+                               NULL,
+                               0);
+       }
+
+       /* create autoplugging element if src element is not a streamming src */
+       if ( player->profile.uri_type != MM_PLAYER_URI_TYPE_URL_RTSP )
+       {
+               element = NULL;
+
+               if( PLAYER_INI()->use_decodebin )
+               {
+                       /* create decodebin */
+                       element = gst_element_factory_make("decodebin", "decodebin");
+
+                       g_object_set(G_OBJECT(element), "async-handling", TRUE, NULL);
+
+                       /* set signal handler */
+                       MMPLAYER_SIGNAL_CONNECT( player, G_OBJECT(element), "new-decoded-pad",
+                                       G_CALLBACK(__mmplayer_gst_decode_callback), player);
+
+                       /* we don't need state holder, bcz decodebin is doing well by itself */
+                       need_state_holder = FALSE;
+               }
+               else
+               {
+                       element = gst_element_factory_make("typefind", "typefinder");
+                       MMPLAYER_SIGNAL_CONNECT( player, element, "have-type",
+                               G_CALLBACK(__mmplayer_typefind_have_type), (gpointer)player );
+               }
+
+               /* check autoplug element is OK */
+               if ( ! element )
+               {
+                       debug_critical("can not create autoplug element\n");
+                       goto INIT_ERROR;
+               }
+
+               mainbin[MMPLAYER_M_AUTOPLUG].id = MMPLAYER_M_AUTOPLUG;
+               mainbin[MMPLAYER_M_AUTOPLUG].gst = element;
+
+               element_bucket = g_list_append(element_bucket, &mainbin[MMPLAYER_M_AUTOPLUG]);
+       }
+
+
+       /* add elements to pipeline */
+       if( !__mmplayer_gst_element_add_bucket_to_bin(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst), element_bucket))
+       {
+               debug_error("Failed to add elements to pipeline\n");
+               goto INIT_ERROR;
+       }
+
+
+       /* linking elements in the bucket by added order. */
+       if ( __mmplayer_gst_element_link_bucket(element_bucket) == -1 )
+       {
+               debug_error("Failed to link some elements\n");
+               goto INIT_ERROR;
+       }
+
+
+       /* 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)
+               {
+                       debug_error ("fakesink element could not be created\n");
+                       goto INIT_ERROR;
+               }
+#ifdef GST_API_VERSION_1
+               GST_OBJECT_FLAG_UNSET (mainbin[MMPLAYER_M_SRC_FAKESINK].gst, GST_ELEMENT_FLAG_SINK);
+#else
+               GST_OBJECT_FLAG_UNSET (mainbin[MMPLAYER_M_SRC_FAKESINK].gst, GST_ELEMENT_IS_SINK);
+#endif
+
+               /* take ownership of fakesink. we are reusing it */
+               gst_object_ref( mainbin[MMPLAYER_M_SRC_FAKESINK].gst );
+
+               /* add */
+               if ( FALSE == gst_bin_add(GST_BIN(mainbin[MMPLAYER_M_PIPE].gst),
+                       mainbin[MMPLAYER_M_SRC_FAKESINK].gst) )
+               {
+                       debug_error("failed to add fakesink to bin\n");
+                       goto INIT_ERROR;
+               }
+       }
+
+       /* now we have completed mainbin. take it */
+       player->pipeline->mainbin = mainbin;
+
+       /* connect bus callback */
+       bus = gst_pipeline_get_bus(GST_PIPELINE(mainbin[MMPLAYER_M_PIPE].gst));
+       if ( !bus )
+       {
+               debug_error ("cannot get bus from pipeline.\n");
+               goto INIT_ERROR;
+       }
+       player->bus_watcher = gst_bus_add_watch(bus, (GstBusFunc)__mmplayer_gst_callback, player);
+
+       /* Note : check whether subtitle atrribute uri is set. If uri is set, then tyr to play subtitle file */
+       if ( __mmplayer_check_subtitle ( player ) )
+       {
+               if ( MM_ERROR_NONE != __mmplayer_gst_create_subtitle_src(player) )
+                       debug_error("fail to create subtitle src\n")
+       }
+
+       /* set sync handler to get tag synchronously */
+#ifdef GST_API_VERSION_1
+       gst_bus_set_sync_handler(bus, __mmplayer_bus_sync_callback, player, NULL);
+#else
+       gst_bus_set_sync_handler(bus, __mmplayer_bus_sync_callback, player);
+#endif
+       /* finished */
+       gst_object_unref(GST_OBJECT(bus));
+       g_list_free(element_bucket);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+
+INIT_ERROR:
+
+       __mmplayer_gst_destroy_pipeline(player);
+       g_list_free(element_bucket);
+
+       /* 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));
+                       }
+               }
+       }
+
+       /* release pipeline with it's childs */
+       if ( mainbin[MMPLAYER_M_PIPE].gst )
+       {
+               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
+       }
+
+       MMPLAYER_FREEIF( player->pipeline );
+       MMPLAYER_FREEIF( mainbin );
+
+       return MM_ERROR_PLAYER_INTERNAL;
+}
+
+int
+__mmplayer_gst_destroy_pipeline(mm_player_t* player) // @
+{
+       gint timeout = 0;
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_INVALID_HANDLE );
+
+       /* cleanup stuffs */
+       MMPLAYER_FREEIF(player->type);
+       player->have_dynamic_pad = FALSE;
+       player->no_more_pad = FALSE;
+       player->num_dynamic_pad = 0;
+
+       if (player->v_stream_caps)
+       {
+               gst_caps_unref(player->v_stream_caps);
+               player->v_stream_caps = NULL;
+       }
+
+       if (ahs_appsrc_cb_probe_id )
+       {
+               GstPad *pad = NULL;
+               pad = gst_element_get_static_pad(player->pipeline->mainbin[MMPLAYER_M_SRC].gst, "src" );
+
+#ifdef GST_API_VERSION_1
+               gst_pad_remove_probe (pad, ahs_appsrc_cb_probe_id);
+#else
+               gst_pad_remove_buffer_probe (pad, ahs_appsrc_cb_probe_id);
+#endif
+               gst_object_unref(pad);
+               pad = NULL;
+               ahs_appsrc_cb_probe_id = 0;
+       }
+
+       if ( player->sink_elements )
+               g_list_free ( player->sink_elements );
+       player->sink_elements = NULL;
+
+       /* 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_delayed_eos( 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 );
+
+               /* disconnecting bus watch */
+               if ( player->bus_watcher )
+                       g_source_remove( 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));
+
+#ifdef GST_API_VERSION_1
+                       gst_bus_set_sync_handler (bus, NULL, NULL, NULL);
+#else
+                       gst_bus_set_sync_handler (bus, NULL, NULL);
+#endif
+                       gst_object_unref(bus);
+
+                       debug_log("pipeline status before set state to NULL\n");
+                       __mmplayer_dump_pipeline_state( player );
+
+                       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 )
+                       {
+                               debug_error("fail to change state to NULL\n");
+                               return MM_ERROR_PLAYER_INTERNAL;
+                       }
+
+                       debug_log("pipeline status before unrefering pipeline\n");
+                       __mmplayer_dump_pipeline_state( player );
+
+                       gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_PIPE].gst));
+
+                       /* free fakesink */
+                       if ( mainbin[MMPLAYER_M_SRC_FAKESINK].gst )
+                               gst_object_unref(GST_OBJECT(mainbin[MMPLAYER_M_SRC_FAKESINK].gst));
+
+                       /* free avsysaudiosink
+                          avsysaudiosink should be unref when destory pipeline just after start play with BT.
+                          Because audiosink is created but never added to bin, and therefore it will not be unref when pipeline is destroyed.
+                       */
+                       MMPLAYER_FREEIF( audiobin );
+                       MMPLAYER_FREEIF( videobin );
+                       MMPLAYER_FREEIF( textbin );
+                       MMPLAYER_FREEIF( mainbin );
+               }
+
+               if ( tag_list )
+                       gst_tag_list_free(tag_list);
+
+               MMPLAYER_FREEIF( player->pipeline );
+       }
+
+       player->pipeline_is_constructed = FALSE;
+
+       debug_fleave();
+
+       return ret;
+}
+
diff --git a/src/mm_player_priv_internal.c b/src/mm_player_priv_internal.c
new file mode 100755 (executable)
index 0000000..c75b6a9
--- /dev/null
@@ -0,0 +1,1201 @@
+/*
+ * libmm-player
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, Heechul Jeon <heechul.jeon@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  INCLUDE FILES                                                                                                                                                       |
+|                                                                                                                                                                                      |
+========================================================================================== */
+#include "mm_player_priv.h"
+#include "mm_player_priv_internal.h"
+#include "mm_player_priv_locl_func.h"
+
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE                                                                                       |
+|                                                                                                                                                                                      |
+========================================================================================== */
+
+/*---------------------------------------------------------------------------
+|    GLOBAL CONSTANT DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    IMPORTED VARIABLE DECLARATIONS:                                                                           |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    IMPORTED FUNCTION DECLARATIONS:                                                                           |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL #defines:                                                                                                           |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL CONSTANT DEFINITIONS:                                                                                       |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL DATA TYPE DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    GLOBAL VARIABLE DEFINITIONS:                                                                                      |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL VARIABLE DEFINITIONS:                                                                                       |
+---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+|    LOCAL FUNCTION PROTOTYPES:                                                                                                |
+---------------------------------------------------------------------------*/
+
+/*===========================================================================================
+|                                                                                                                                                                                      |
+|  FUNCTION DEFINITIONS                                                                                                                                                |
+|                                                                                                                                                                                      |
+========================================================================================== */
+/* NOTE : be careful with calling this api. please refer to below glib comment
+ * glib comment : Note that there is a bug in GObject that makes this function much
+ * less useful than it might seem otherwise. Once gobject is disposed, the callback
+ * will no longer be called, but, the signal handler is not currently disconnected.
+ * If the instance is itself being freed at the same time than this doesn't matter,
+ * since the signal will automatically be removed, but if instance persists,
+ * then the signal handler will leak. You should not remove the signal yourself
+ * because in a future versions of GObject, the handler will automatically be
+ * disconnected.
+ *
+ * It's possible to work around this problem in a way that will continue to work
+ * with future versions of GObject by checking that the signal handler is still
+ * connected before disconnected it:
+ *
+ *     if (g_signal_handler_is_connected (instance, id))
+ *       g_signal_handler_disconnect (instance, id);
+ */
+void
+__mmplayer_release_signal_connection(mm_player_t* player)
+{
+       GList* sig_list = player->signals;
+       MMPlayerSignalItem* item = NULL;
+
+       debug_fenter();
+
+       return_if_fail( player );
+
+       for ( ; sig_list; sig_list = sig_list->next )
+       {
+               item = sig_list->data;
+
+               if ( item && item->obj && GST_IS_ELEMENT(item->obj) )
+               {
+                       debug_log("checking signal connection : [%lud] from [%s]\n", item->sig, GST_OBJECT_NAME( item->obj ));
+
+                       if ( g_signal_handler_is_connected ( item->obj, item->sig ) )
+                       {
+                               debug_log("signal disconnecting : [%lud] from [%s]\n", item->sig, GST_OBJECT_NAME( item->obj ));
+                               g_signal_handler_disconnect ( item->obj, item->sig );
+                       }
+               }
+
+               MMPLAYER_FREEIF( item );
+
+       }
+       g_list_free ( player->signals );
+       player->signals = NULL;
+
+       debug_fleave();
+
+       return;
+}
+
+gboolean
+__mmplayer_dump_pipeline_state( mm_player_t* player )
+{
+       GstIterator*iter = NULL;
+       gboolean done = FALSE;
+
+       GstElement *item = NULL;
+       GstElementFactory *factory = NULL;
+
+       GstState state = GST_STATE_VOID_PENDING;
+       GstState pending = GST_STATE_VOID_PENDING;
+       GstClockTime time = 200*GST_MSECOND;
+
+       debug_fenter();
+
+       return_val_if_fail ( player &&
+               player->pipeline &&
+               player->pipeline->mainbin,
+               FALSE );
+
+       iter = gst_bin_iterate_recurse(GST_BIN(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst) );
+
+       if ( iter != NULL )
+       {
+               while (!done) {
+                        switch ( gst_iterator_next (iter, (gpointer)&item) )
+                        {
+                          case GST_ITERATOR_OK:
+                               gst_element_get_state(GST_ELEMENT (item),&state, &pending,time);
+
+                               factory = gst_element_get_factory (item) ;
+                               if (!factory)
+                               {
+                                        debug_error("%s:%s : From:%s To:%s   refcount : %d\n", GST_OBJECT_NAME(factory) , GST_ELEMENT_NAME(item) ,
+                                               gst_element_state_get_name(state), gst_element_state_get_name(pending) , GST_OBJECT_REFCOUNT_VALUE(item));
+                               }
+                                gst_object_unref (item);
+                                break;
+                          case GST_ITERATOR_RESYNC:
+                                gst_iterator_resync (iter);
+                                break;
+                          case GST_ITERATOR_ERROR:
+                                done = TRUE;
+                                break;
+                          case GST_ITERATOR_DONE:
+                                done = TRUE;
+                                break;
+                        }
+               }
+       }
+
+       item = GST_ELEMENT(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst);
+
+       gst_element_get_state(GST_ELEMENT (item),&state, &pending,time);
+
+       factory = gst_element_get_factory (item) ;
+
+       if (!factory)
+       {
+               debug_error("%s:%s : From:%s To:%s  refcount : %d\n",
+                       GST_OBJECT_NAME(factory),
+                       GST_ELEMENT_NAME(item),
+                       gst_element_state_get_name(state),
+                       gst_element_state_get_name(pending),
+                       GST_OBJECT_REFCOUNT_VALUE(item) );
+       }
+
+       if ( iter )
+               gst_iterator_free (iter);
+
+       debug_fleave();
+
+       return FALSE;
+}
+
+int
+__mmplayer_gst_set_state (mm_player_t* player, GstElement * element,  GstState state, gboolean async, gint timeout) // @
+{
+       GstState element_state = GST_STATE_VOID_PENDING;
+       GstState element_pending_state = GST_STATE_VOID_PENDING;
+       GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail ( element, MM_ERROR_INVALID_ARGUMENT );
+
+       debug_log("setting [%s] element state to : %d\n", GST_ELEMENT_NAME(element),  state);
+
+       /* set state */
+       ret = gst_element_set_state(element, state);
+
+       if ( ret == GST_STATE_CHANGE_FAILURE )
+       {
+               debug_error("failed to set  [%s] state to [%d]\n", GST_ELEMENT_NAME(element), state);
+
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state( player );
+
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       /* return here so state transition to be done in async mode */
+       if ( async )
+       {
+               debug_log("async state transition. not waiting for state complete.\n");
+               return MM_ERROR_NONE;
+       }
+
+       /* wait for state transition */
+       ret = gst_element_get_state( element, &element_state, &element_pending_state, timeout * GST_SECOND );
+
+       if ( ret == GST_STATE_CHANGE_FAILURE || ( state != element_state ) )
+       {
+               debug_error("failed to change [%s] element state to [%s] within %d sec\n",
+                       GST_ELEMENT_NAME(element),
+                       gst_element_state_get_name(state), timeout );
+
+               debug_error(" [%s] state : %s   pending : %s \n",
+                       GST_ELEMENT_NAME(element),
+                       gst_element_state_get_name(element_state),
+                       gst_element_state_get_name(element_pending_state) );
+
+               /* dump state of all element */
+               __mmplayer_dump_pipeline_state( player );
+
+               return MM_ERROR_PLAYER_INTERNAL;
+       }
+
+       debug_log("[%s] element state has changed to %s \n",
+               GST_ELEMENT_NAME(element),
+               gst_element_state_get_name(element_state));
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+gboolean
+__mmplayer_check_subtitle( mm_player_t* player )
+{
+       MMHandleType attrs = 0;
+       char *subtitle_uri = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail( player, FALSE );
+
+       /* get subtitle attribute */
+       attrs = MMPLAYER_GET_ATTRS(player);
+       if ( !attrs )
+               return FALSE;
+
+       mm_attrs_get_string_by_name(attrs, "subtitle_uri", &subtitle_uri);
+       if ( !subtitle_uri || !strlen(subtitle_uri))
+               return FALSE;
+
+       debug_log ("subtite uri is %s[%d]\n", subtitle_uri, strlen(subtitle_uri));
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+/* 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().
+ * 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)
+{
+       MMMessageParamType msg_param;
+       memset (&msg_param, 0, sizeof(MMMessageParamType));
+       gboolean post_msg_direct = FALSE;
+
+       debug_fenter();
+
+       return_val_if_fail(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
+
+       debug_log("not_supported_codec = 0x%02x, can_support_codec = 0x%02x\n",
+                       player->not_supported_codec, player->can_support_codec);
+
+       if( player->not_found_demuxer )
+       {
+               msg_param.code = MM_ERROR_PLAYER_CODEC_NOT_FOUND;
+               msg_param.data = g_strdup_printf("%s", player->unlinked_demuxer_mime);
+
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+               MMPLAYER_FREEIF(msg_param.data);
+
+               return MM_ERROR_NONE;
+       }
+
+       if (player->not_supported_codec)
+       {
+               if ( player->can_support_codec ) // There is one codec to play
+               {
+                       post_msg_direct = TRUE;
+               }
+               else
+               {
+                       if ( player->pipeline->audiobin ) // Some content has only PCM data in container.
+                               post_msg_direct = TRUE;
+               }
+
+               if ( post_msg_direct )
+               {
+                       MMMessageParamType msg_param;
+                       memset (&msg_param, 0, sizeof(MMMessageParamType));
+
+                       if ( player->not_supported_codec ==  MISSING_PLUGIN_AUDIO )
+                       {
+                               debug_warning("not found AUDIO codec, posting error code to application.\n");
+
+                               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 )
+                       {
+                               debug_warning("not found VIDEO codec, posting error code to application.\n");
+
+                               msg_param.code = MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
+                               msg_param.data = g_strdup_printf("%s", player->unlinked_video_mime);
+                       }
+
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+
+                       MMPLAYER_FREEIF(msg_param.data);
+
+                       return MM_ERROR_NONE;
+               }
+               else // no any supported codec case
+               {
+                       debug_warning("not found any codec, posting error code to application.\n");
+
+                       if ( player->not_supported_codec ==  MISSING_PLUGIN_AUDIO )
+                       {
+                               msg_param.code = MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
+                               msg_param.data = g_strdup_printf("%s", player->unlinked_audio_mime);
+                       }
+                       else
+                       {
+                               msg_param.code = MM_ERROR_PLAYER_CODEC_NOT_FOUND;
+                               msg_param.data = g_strdup_printf("%s, %s", player->unlinked_video_mime, player->unlinked_audio_mime);
+                       }
+
+                       MMPLAYER_POST_MSG( player, MM_MESSAGE_ERROR, &msg_param );
+
+                       MMPLAYER_FREEIF(msg_param.data);
+               }
+       }
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+gboolean
+__mmplayer_link_decoder( mm_player_t* player, GstPad *srcpad)
+{
+       const gchar* name = NULL;
+       GstStructure* str = NULL;
+       GstCaps* srccaps = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail( player, FALSE );
+       return_val_if_fail ( srcpad, FALSE );
+
+       /* to check any of the decoder (video/audio) need to be linked  to parser*/
+#ifdef GST_API_VERSION_1
+       srccaps = gst_pad_get_current_caps( srcpad );
+#else
+       srccaps = gst_pad_get_caps( srcpad );
+#endif
+       if ( !srccaps )
+               goto ERROR;
+
+       str = gst_caps_get_structure( srccaps, 0 );
+       if ( ! str )
+               goto ERROR;
+
+       name = gst_structure_get_name(str);
+       if ( ! name )
+               goto ERROR;
+
+       if (strstr(name, "video"))
+       {
+               if(player->videodec_linked)
+               {
+                   debug_msg("Video decoder already linked\n");
+                       return FALSE;
+               }
+       }
+       if (strstr(name, "audio"))
+       {
+               if(player->audiodec_linked)
+               {
+                   debug_msg("Audio decoder already linked\n");
+                       return FALSE;
+               }
+       }
+
+       gst_caps_unref( srccaps );
+
+       debug_fleave();
+
+       return TRUE;
+
+ERROR:
+       if ( srccaps )
+               gst_caps_unref( srccaps );
+
+       return FALSE;
+}
+
+gboolean
+__mmplayer_link_sink( mm_player_t* player , GstPad *srcpad)
+{
+       const gchar* name = NULL;
+       GstStructure* str = NULL;
+       GstCaps* srccaps = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( srcpad, FALSE );
+
+       /* to check any of the decoder (video/audio) need to be linked  to parser*/
+#ifdef GST_API_VERSION_1
+       srccaps = gst_pad_get_current_caps( srcpad );
+#else
+       srccaps = gst_pad_get_caps( srcpad );
+#endif
+       if ( !srccaps )
+               goto ERROR;
+
+       str = gst_caps_get_structure( srccaps, 0 );
+       if ( ! str )
+               goto ERROR;
+
+       name = gst_structure_get_name(str);
+       if ( ! name )
+               goto ERROR;
+
+       if (strstr(name, "video"))
+       {
+               if(player->videosink_linked)
+               {
+                       debug_msg("Video Sink already linked\n");
+                       return FALSE;
+               }
+       }
+       if (strstr(name, "audio"))
+       {
+               if(player->audiosink_linked)
+               {
+                       debug_msg("Audio Sink already linked\n");
+                       return FALSE;
+               }
+       }
+       if (strstr(name, "text"))
+       {
+               if(player->textsink_linked)
+               {
+                       debug_msg("Text Sink already linked\n");
+                       return FALSE;
+               }
+       }
+
+       gst_caps_unref( srccaps );
+
+       debug_fleave();
+
+       return TRUE;
+       //return (!player->videosink_linked || !player->audiosink_linked);
+
+ERROR:
+       if ( srccaps )
+               gst_caps_unref( srccaps );
+
+       return FALSE;
+}
+
+gint
+__gst_handle_core_error( mm_player_t* player, int code )
+{
+       gint trans_err = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       switch ( code )
+       {
+               case GST_CORE_ERROR_STATE_CHANGE:
+               case GST_CORE_ERROR_MISSING_PLUGIN:
+               case GST_CORE_ERROR_SEEK:
+               case GST_CORE_ERROR_NOT_IMPLEMENTED:
+               case GST_CORE_ERROR_FAILED:
+               case GST_CORE_ERROR_TOO_LAZY:
+               case GST_CORE_ERROR_PAD:
+               case GST_CORE_ERROR_THREAD:
+               case GST_CORE_ERROR_NEGOTIATION:
+               case GST_CORE_ERROR_EVENT:
+               case GST_CORE_ERROR_CAPS:
+               case GST_CORE_ERROR_TAG:
+               case GST_CORE_ERROR_CLOCK:
+               case GST_CORE_ERROR_DISABLED:
+               default:
+                       trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
+               break;
+       }
+
+       debug_fleave();
+
+       return trans_err;
+}
+
+gint
+__gst_handle_library_error( mm_player_t* player, int code )
+{
+       gint trans_err = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       switch ( code )
+       {
+               case GST_LIBRARY_ERROR_FAILED:
+               case GST_LIBRARY_ERROR_TOO_LAZY:
+               case GST_LIBRARY_ERROR_INIT:
+               case GST_LIBRARY_ERROR_SHUTDOWN:
+               case GST_LIBRARY_ERROR_SETTINGS:
+               case GST_LIBRARY_ERROR_ENCODE:
+               default:
+                       trans_err =  MM_ERROR_PLAYER_INVALID_STREAM;
+               break;
+       }
+
+       debug_fleave();
+
+       return trans_err;
+}
+
+gint
+__gst_handle_resource_error( mm_player_t* player, int code )
+{
+       gint trans_err = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+
+       switch ( code )
+       {
+               case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
+                       trans_err = MM_ERROR_PLAYER_NO_FREE_SPACE;
+                       break;
+               case GST_RESOURCE_ERROR_NOT_FOUND:
+               case GST_RESOURCE_ERROR_OPEN_READ:
+                       if ( MMPLAYER_IS_HTTP_STREAMING(player) || MMPLAYER_IS_HTTP_LIVE_STREAMING ( player )
+                               || MMPLAYER_IS_RTSP_STREAMING(player))
+                       {
+                               trans_err = MM_ERROR_PLAYER_STREAMING_CONNECTION_FAIL;
+                               break;
+                       }
+               case GST_RESOURCE_ERROR_READ:
+                       if ( MMPLAYER_IS_HTTP_STREAMING(player) ||  MMPLAYER_IS_HTTP_LIVE_STREAMING ( player )
+                               || MMPLAYER_IS_RTSP_STREAMING(player))
+                       {
+                               trans_err = MM_ERROR_PLAYER_STREAMING_FAIL;
+                               break;
+                       }
+               case GST_RESOURCE_ERROR_WRITE:
+               case GST_RESOURCE_ERROR_FAILED:
+                       trans_err = MM_ERROR_PLAYER_INTERNAL;
+                       break;
+
+               case GST_RESOURCE_ERROR_SEEK:
+               case GST_RESOURCE_ERROR_TOO_LAZY:
+               case GST_RESOURCE_ERROR_BUSY:
+               case GST_RESOURCE_ERROR_OPEN_WRITE:
+               case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
+               case GST_RESOURCE_ERROR_CLOSE:
+               case GST_RESOURCE_ERROR_SYNC:
+               case GST_RESOURCE_ERROR_SETTINGS:
+               default:
+                       trans_err = MM_ERROR_PLAYER_FILE_NOT_FOUND;
+               break;
+       }
+
+       debug_fleave();
+
+       return trans_err;
+}
+
+gint
+__gst_handle_stream_error( mm_player_t* player, GError* error, GstMessage * message )
+{
+       gint trans_err = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       return_val_if_fail( player, MM_ERROR_PLAYER_NOT_INITIALIZED );
+       return_val_if_fail( error, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( message, MM_ERROR_INVALID_ARGUMENT );
+
+       switch ( error->code )
+       {
+               case GST_STREAM_ERROR_FAILED:
+               case GST_STREAM_ERROR_TYPE_NOT_FOUND:
+               case GST_STREAM_ERROR_DECODE:
+               case GST_STREAM_ERROR_WRONG_TYPE:
+               case GST_STREAM_ERROR_DECRYPT:
+               case GST_STREAM_ERROR_DECRYPT_NOKEY:
+                        trans_err = __gst_transform_gsterror( player, message, error );
+               break;
+
+               case GST_STREAM_ERROR_CODEC_NOT_FOUND:
+               case GST_STREAM_ERROR_NOT_IMPLEMENTED:
+               case GST_STREAM_ERROR_TOO_LAZY:
+               case GST_STREAM_ERROR_ENCODE:
+               case GST_STREAM_ERROR_DEMUX:
+               case GST_STREAM_ERROR_MUX:
+               case GST_STREAM_ERROR_FORMAT:
+               default:
+                       trans_err = MM_ERROR_PLAYER_INVALID_STREAM;
+               break;
+       }
+
+       debug_fleave();
+
+       return trans_err;
+}
+
+/* NOTE : decide gstreamer state whether there is some playable track or not. */
+gint
+__gst_transform_gsterror( mm_player_t* player, GstMessage * message, GError* error )
+{
+       gchar *src_element_name = NULL;
+       GstElement *src_element = NULL;
+       GstElementFactory *factory = NULL;
+       const gchar* klass = NULL;
+
+       debug_fenter();
+
+       /* FIXIT */
+       return_val_if_fail ( message, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( message->src, MM_ERROR_INVALID_ARGUMENT );
+       return_val_if_fail ( error, MM_ERROR_INVALID_ARGUMENT );
+
+       src_element = GST_ELEMENT_CAST(message->src);
+       if ( !src_element )
+               goto INTERNAL_ERROR;
+
+       src_element_name = GST_ELEMENT_NAME(src_element);
+       if ( !src_element_name )
+               goto INTERNAL_ERROR;
+
+       factory = gst_element_get_factory(src_element);
+       if ( !factory )
+               goto INTERNAL_ERROR;
+
+       klass = gst_element_factory_get_klass(factory);
+       if ( !klass )
+               goto INTERNAL_ERROR;
+
+       debug_log("error code=%d, msg=%s, src element=%s, class=%s\n",
+                       error->code, error->message, src_element_name, klass);
+
+       switch ( error->code )
+       {
+               case GST_STREAM_ERROR_DECODE:
+               {
+                       /* Demuxer can't parse one track because it's corrupted.
+                        * So, the decoder for it is not linked.
+                        * But, it has one playable track.
+                        */
+                       if ( g_strrstr(klass, "Demux") )
+                       {
+                               if ( player->can_support_codec == FOUND_PLUGIN_VIDEO )
+                               {
+                                       return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
+                               }
+                               else if ( player->can_support_codec == FOUND_PLUGIN_AUDIO )
+                               {
+                                       return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
+                               }
+                               else
+                               {
+                                       if ( player->pipeline->audiobin ) // PCM
+                                       {
+                                               return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
+                                       }
+                                       else
+                                       {
+                                               goto CODEC_NOT_FOUND;
+                                       }
+                               }
+                       }
+                       return MM_ERROR_PLAYER_INVALID_STREAM;
+               }
+               break;
+
+               case GST_STREAM_ERROR_WRONG_TYPE:
+               {
+                       return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
+               }
+               break;
+
+               case GST_STREAM_ERROR_FAILED:
+               {
+                       /* Decoder Custom Message */
+                       if ( strstr(error->message, "ongoing") )
+                       {
+                               if ( strncasecmp(klass, "audio", 5) )
+                               {
+                                       if ( ( player->can_support_codec & FOUND_PLUGIN_VIDEO ) )
+                                       {
+                                               debug_log("Video can keep playing.\n");
+                                               return MM_ERROR_PLAYER_AUDIO_CODEC_NOT_FOUND;
+                                       }
+                                       else
+                                       {
+                                               goto CODEC_NOT_FOUND;
+                                       }
+
+                               }
+                               else if ( strncasecmp(klass, "video", 5) )
+                               {
+                                       if ( ( player->can_support_codec & FOUND_PLUGIN_AUDIO ) )
+                                       {
+                                               debug_log("Audio can keep playing.\n");
+                                               return MM_ERROR_PLAYER_VIDEO_CODEC_NOT_FOUND;
+                                       }
+                                       else
+                                       {
+                                               goto CODEC_NOT_FOUND;
+                                       }
+                               }
+                       }
+                       return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
+               }
+               break;
+
+               case GST_STREAM_ERROR_TYPE_NOT_FOUND:
+                       return MM_ERROR_PLAYER_NOT_SUPPORTED_FORMAT;
+               break;
+
+               case GST_STREAM_ERROR_DECRYPT:
+               case GST_STREAM_ERROR_DECRYPT_NOKEY:
+               {
+                       debug_error("decryption error, [%s] failed, reason : [%s]\n", src_element_name, error->message);
+
+                       if ( strstr(error->message, "rights expired") )
+                       {
+                               return MM_ERROR_PLAYER_DRM_EXPIRED;
+                       }
+                       else if ( strstr(error->message, "no rights") )
+                       {
+                               return MM_ERROR_PLAYER_DRM_NO_LICENSE;
+                       }
+                       else if ( strstr(error->message, "has future rights") )
+                       {
+                               return MM_ERROR_PLAYER_DRM_FUTURE_USE;
+                       }
+                       else if ( strstr(error->message, "opl violation") )
+                       {
+                               return MM_ERROR_PLAYER_DRM_OUTPUT_PROTECTION;
+                       }
+                       return MM_ERROR_PLAYER_DRM_NOT_AUTHORIZED;
+               }
+               break;
+
+               default:
+               break;
+       }
+
+       debug_fleave();
+
+       return MM_ERROR_PLAYER_INVALID_STREAM;
+
+INTERNAL_ERROR:
+       return MM_ERROR_PLAYER_INTERNAL;
+
+CODEC_NOT_FOUND:
+       debug_log("not found any available codec. Player should be destroyed.\n");
+       return MM_ERROR_PLAYER_CODEC_NOT_FOUND;
+}
+
+static void
+__mmplayer_post_delayed_eos( mm_player_t* player, int delay_in_ms )
+{
+       debug_fenter();
+
+       return_if_fail( player );
+
+       /* cancel if existing */
+       __mmplayer_cancel_delayed_eos( player );
+
+
+       /* post now if delay is zero */
+       if ( delay_in_ms == 0 || player->is_sound_extraction)
+       {
+               debug_log("eos delay is zero. posting EOS now\n");
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_END_OF_STREAM, NULL );
+
+               if ( player->is_sound_extraction )
+                       __mmplayer_cancel_delayed_eos(player);
+
+               return;
+       }
+
+       /* init new timeout */
+       /* NOTE : consider give high priority to this timer */
+
+       debug_log("posting EOS message after [%d] msec\n", delay_in_ms);
+       player->eos_timer = g_timeout_add( delay_in_ms,
+               __mmplayer_eos_timer_cb, player );
+
+
+       /* check timer is valid. if not, send EOS now */
+       if ( player->eos_timer == 0 )
+       {
+               debug_warning("creating timer for delayed EOS has failed. sending EOS now\n");
+               MMPLAYER_POST_MSG( player, MM_MESSAGE_END_OF_STREAM, NULL );
+       }
+
+       debug_fleave();
+}
+
+gboolean
+__mmplayer_handle_gst_error ( mm_player_t* player, GstMessage * message, GError* error )
+{
+       MMMessageParamType msg_param;
+       gchar *msg_src_element;
+
+       debug_fenter();
+
+       return_val_if_fail( player, FALSE );
+       return_val_if_fail( error, FALSE );
+
+       /* NOTE : do somthing necessary inside of __gst_handle_XXX_error. not here */
+
+       memset (&msg_param, 0, sizeof(MMMessageParamType));
+
+       if ( error->domain == GST_CORE_ERROR )
+       {
+               msg_param.code = __gst_handle_core_error( player, error->code );
+       }
+       else if ( error->domain == GST_LIBRARY_ERROR )
+       {
+               msg_param.code = __gst_handle_library_error( player, error->code );
+       }
+       else if ( error->domain == GST_RESOURCE_ERROR )
+       {
+               msg_param.code = __gst_handle_resource_error( player, error->code );
+       }
+       else if ( error->domain == GST_STREAM_ERROR )
+       {
+               msg_param.code = __gst_handle_stream_error( player, error, message );
+       }
+       else
+       {
+               debug_warning("This error domain is not defined.\n");
+
+               /* we treat system error as an internal error */
+               msg_param.code = MM_ERROR_PLAYER_INVALID_STREAM;
+       }
+
+       if ( message->src )
+       {
+               msg_src_element = GST_ELEMENT_NAME( GST_ELEMENT_CAST( message->src ) );
+
+               msg_param.data = (void *) error->message;
+
+               debug_error("-Msg src : [%s]    Domain : [%s]   Error : [%s]  Code : [%d] is tranlated to error code : [0x%x]\n",
+                       msg_src_element, g_quark_to_string (error->domain), error->message, error->code, msg_param.code);
+       }
+
+       /* 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
+       {
+               debug_log("skip error post because it's sent already.\n");
+       }
+
+       debug_fleave();
+
+       return TRUE;
+}
+
+gboolean
+__mmplayer_handle_streaming_error  ( mm_player_t* player, GstMessage * message )
+{
+       debug_log("\n");
+       MMMessageParamType msg_param;
+       gchar *msg_src_element = NULL;
+       GstStructure *s = NULL;
+       guint error_id = 0;
+       gchar *error_string = NULL;
+
+       debug_fenter();
+
+       return_val_if_fail ( player, FALSE );
+       return_val_if_fail ( message, FALSE );
+
+       s = malloc( sizeof(GstStructure) );
+       memcpy ( s, gst_message_get_structure ( message ), sizeof(GstStructure));
+
+       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:
+                       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 ) );
+
+               debug_error("-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
+       {
+               debug_log("skip error post because it's sent already.\n");
+       }
+
+       debug_fleave();
+
+       return TRUE;
+
+}
+
+void
+__mmplayer_add_sink( mm_player_t* player, GstElement* sink )
+{
+       debug_fenter();
+
+       return_if_fail ( player );
+       return_if_fail ( sink );
+
+       player->sink_elements =
+               g_list_append(player->sink_elements, sink);
+
+       debug_fleave();
+}
+
+void
+__mmplayer_del_sink( mm_player_t* player, GstElement* sink )
+{
+       debug_fenter();
+
+       return_if_fail ( player );
+       return_if_fail ( sink );
+
+       player->sink_elements =
+                       g_list_remove(player->sink_elements, sink);
+
+       debug_fleave();
+}
+
+gboolean
+__is_rtsp_streaming ( mm_player_t* player )
+{
+       return_val_if_fail ( player, FALSE );
+
+       return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_RTSP ) ? TRUE : FALSE;
+}
+
+gboolean
+__is_http_streaming ( mm_player_t* player )
+{
+       return_val_if_fail ( player, FALSE );
+
+       return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_URL_HTTP ) ? TRUE : FALSE;
+}
+
+gboolean
+__is_streaming ( mm_player_t* player )
+{
+       return_val_if_fail ( player, FALSE );
+
+       return ( __is_rtsp_streaming ( player ) || __is_http_streaming ( player ) || __is_http_live_streaming ( player )) ? TRUE : FALSE;
+}
+
+gboolean
+__is_live_streaming ( mm_player_t* player )
+{
+       return_val_if_fail ( player, FALSE );
+
+       return ( __is_rtsp_streaming ( player ) && player->streaming_type == STREAMING_SERVICE_LIVE ) ? TRUE : FALSE;
+}
+
+gboolean
+__is_http_live_streaming( mm_player_t* player )
+{
+       return_val_if_fail( player, FALSE );
+
+       return ( player->profile.uri_type == MM_PLAYER_URI_TYPE_HLS ) ? TRUE : FALSE;
+}
+
+gboolean
+__is_http_progressive_down(mm_player_t* player)
+{
+       return_val_if_fail( player, FALSE );
+
+       return ((player->pd_mode) ? TRUE:FALSE);
+}
+
old mode 100644 (file)
new mode 100755 (executable)
index 3f76b87..77eb83f
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, Heechul Jeon <heechul.jeon@samsung.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
old mode 100644 (file)
new mode 100755 (executable)
index 778049f..eae640d
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, Heechul Jeon <heechul.jeon@samsung.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -111,7 +111,7 @@ bool util_remove_file_backup(const char *backup_path)
 int util_is_midi_type_by_mem(void *mem, int size)
 {
        debug_log("\n");
-       
+
        const char *p = (const char *)mem;
 
        if (size < DETECTION_PREFIX_SIZE)
@@ -155,7 +155,7 @@ int util_is_midi_type_by_mem(void *mem, int size)
 int util_is_midi_type_by_file(const char *file_path)
 {
        debug_log("\n");
-       
+
        struct stat file_attrib;
        FILE *fp = NULL;
        char prefix[DETECTION_PREFIX_SIZE] = {0,};
@@ -184,7 +184,7 @@ int util_is_midi_type_by_file(const char *file_path)
                fclose(fp);
                return FALSE;
        }
-       
+
        size = fread(prefix, sizeof(char), DETECTION_PREFIX_SIZE, fp);
 
        fclose(fp);
@@ -192,20 +192,20 @@ int util_is_midi_type_by_file(const char *file_path)
        return util_is_midi_type_by_mem(prefix, size);
 }
 
-/* messages are treated as warnings bcz those code should not be checked in. 
- * and no error handling will supported for same manner. 
+/* messages are treated as warnings bcz those code should not be checked in.
+ * and no error handling will supported for same manner.
  */
-gboolean 
+gboolean
 __util_gst_pad_probe(GstPad *pad, GstBuffer *buffer, gpointer u_data)
 {
        gint flag = (gint) u_data;
        GstElement* parent = NULL;
        gboolean ret = TRUE;
-       
+
        /* show name as default */
        parent = (GstElement*)gst_object_get_parent(GST_OBJECT(pad));
        debug_warning("PAD PROBE : %s:%s\n", GST_ELEMENT_NAME(parent), GST_PAD_NAME(pad));
-       
+
        /* show time stamp */
        if ( flag & MM_PROBE_TIMESTAMP )
        {
@@ -242,7 +242,7 @@ __util_gst_pad_probe(GstPad *pad, GstBuffer *buffer, gpointer u_data)
                debug_warning("dropping\n");
                ret = FALSE;
        }
-               
+
        /* show clock time */
        if ( flag & MM_PROBE_CLOCK_TIME )
        {
@@ -264,7 +264,7 @@ __util_gst_pad_probe(GstPad *pad, GstBuffer *buffer, gpointer u_data)
        return ret;
 }
 
-char** 
+char**
 util_get_cookie_list ( const char *cookies )
 {
        char **cookie_list = NULL;
@@ -308,7 +308,7 @@ bool util_check_valid_url ( const char *proxy )
 {
        struct in_addr proxy_addr;
        bool ret = TRUE;
-       
+
        return_val_if_fail ( proxy, FALSE );
        return_val_if_fail ( strlen(proxy), FALSE );
 
@@ -317,19 +317,19 @@ bool util_check_valid_url ( const char *proxy )
                debug_warning("invalid proxy is set. \n");
                ret = FALSE;
        }
-          
+
        return ret;
 }
 
 /* check the given path is indicating sdp file */
-bool 
+bool
 util_is_sdp_file ( const char *path )
 {
        gboolean ret = FALSE;
        gchar* uri = NULL;
-       
+
        debug_fenter();
-       
+
        return_val_if_fail ( path, FALSE );
 
        uri = g_ascii_strdown ( path, -1 );
@@ -365,7 +365,7 @@ util_is_sdp_file ( const char *path )
        return ret;
 }
 
-int64_t 
+int64_t
 util_get_time ( void )
 {
        struct timeval tv;
@@ -373,16 +373,16 @@ util_get_time ( void )
        return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
 }
 
-int 
+int
 util_get_rank_increase ( const char *factory_class )
 {
        gint rank_pri_inc = 20;
        gint rank_sec_inc = 10;
        gint ret = 0;
 
-       if ( g_strrstr(factory_class,"Dsp") ) 
+       if ( g_strrstr(factory_class,"Dsp") )
                ret = rank_pri_inc;
-       else if ( g_strrstr(factory_class,"HW") ) 
+       else if ( g_strrstr(factory_class,"HW") )
                ret = rank_pri_inc;
        else if ( g_strrstr(factory_class,"Arm") )
                ret = rank_sec_inc;
@@ -390,7 +390,7 @@ util_get_rank_increase ( const char *factory_class )
        return ret;
 }
 
-int 
+int
 util_factory_rank_compare(GstPluginFeature *f1, GstPluginFeature *f2) // @
 {
        const gchar *klass;