Merge the latest code. 43/40043/1 accepted/tizen/common/20150605.071903 accepted/tizen/mobile/20150605.091818 accepted/tizen/tv/20150605.091753 accepted/tizen/wearable/20150605.091803 submit/tizen/20150601.053227 submit/tizen/20150603.045552 submit/tizen/20150604.020049
authorSangkyu Park <sk1122.park@samsung.com>
Thu, 28 May 2015 05:42:19 +0000 (14:42 +0900)
committerSangkyu Park <sk1122.park@samsung.com>
Thu, 28 May 2015 05:42:43 +0000 (14:42 +0900)
Change-Id: If8fbeb549636f04da865ccf00e025911f8c9bf76
Signed-off-by: Sangkyu Park <sk1122.park@samsung.com>
14 files changed:
common/include/mm_wfd_sink_dlog.h [new file with mode: 0755]
common/include/mm_wfd_sink_ini.h
common/mm_wfd_sink_ini.c
config/mmfw_wfd_sink.ini
configure.ac
packaging/libmm-wfd.spec
sink/include/mm_wfd_sink.h
sink/include/mm_wfd_sink_manager.h
sink/include/mm_wfd_sink_priv.h
sink/include/mm_wfd_sink_util.h
sink/mm_wfd_sink.c
sink/mm_wfd_sink_manager.c
sink/mm_wfd_sink_priv.c
sink/mm_wfd_sink_util.c

diff --git a/common/include/mm_wfd_sink_dlog.h b/common/include/mm_wfd_sink_dlog.h
new file mode 100755 (executable)
index 0000000..d9e2f99
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* 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_WFD_SINK_DLOG_H__
+#define __MM_WFD_SINK_DLOG_H__
+
+#include <dlog.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "MM_WFD_SINK"
+
+#define wfd_sink_debug(fmt, arg...) do { \
+                       LOGD(""fmt"", ##arg);     \
+               } while (0)
+
+#define wfd_sink_info(fmt, arg...) do { \
+                       LOGI(""fmt"", ##arg);     \
+               } while (0)
+
+#define wfd_sink_error(fmt, arg...) do { \
+                       LOGE(""fmt"", ##arg);     \
+               } while (0)
+
+#define wfd_sink_warning(fmt, arg...) do { \
+                       LOGW(""fmt"", ##arg);     \
+               } while (0)
+
+#define wfd_sink_debug_fenter() do { \
+                       LOGD("<Enter>");     \
+               } while (0)
+
+#define wfd_sink_debug_fleave() do { \
+                       LOGD("<Leave>");     \
+               } while (0)
+
+#define wfd_sink_error_fenter() do { \
+                       LOGE("NO-ERROR : <Enter>");     \
+               } while (0)
+
+#define wfd_sink_error_fleave() do { \
+                       LOGE("NO-ERROR : <Leave>");     \
+               } while (0)
+
+#define wfd_sink_sucure_info(fmt, arg...) do { \
+                       SECURE_LOGI(""fmt"", ##arg);     \
+               } while (0)
+
+#define wfd_sink_return_if_fail(expr)  \
+               if(!(expr)) {   \
+                       wfd_sink_error("failed [%s]\n", #expr); \
+                       return; \
+               }
+
+#define wfd_sink_return_val_if_fail(expr, val) \
+               if (!(expr)) {  \
+                       wfd_sink_error("failed [%s]\n", #expr); \
+                       return val; \
+               }
+
+#define wfd_sink_assert_not_reached() \
+       { \
+               wfd_sink_error("assert_not_reached()"); \
+               assert(0); \
+       }
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MM_WFD_SINK_DLOG_H__ */
+
index 557fa0f..66c6ce8 100755 (executable)
@@ -63,6 +63,9 @@ typedef struct __mm_wfd_sink_ini
        gboolean enable_asm;
        gint jitter_buffer_latency;
        gint video_sink_max_lateness;
+       gint sink_ts_offset;
+       gboolean audio_sink_async;
+       gboolean video_sink_async;
        gboolean enable_retransmission;
        gboolean enable_reset_basetime;
        gboolean enable_ts_data_dump;
@@ -121,10 +124,13 @@ typedef struct __mm_wfd_sink_ini
 #define DEFAULT_STATE_CHANGE_TIMEOUT 5 /* sec */
 #define DEFAULT_SET_DEBUG_PROPERTY     TRUE
 #define DEFAULT_ENABLE_ASM     FALSE
-#define DEFAULT_JITTER_BUFFER_LATENCY 33 /* msec */
+#define DEFAULT_JITTER_BUFFER_LATENCY 10 /* msec */
 #define DEFAULT_ENABLE_RETRANSMISSION  TRUE
 #define DEFAULT_ENABLE_RESET_BASETIME  TRUE
 #define DEFAULT_VIDEO_SINK_MAX_LATENESS 20000000 /* nsec */
+#define DEFAULT_SINK_TS_OFFSET 150000000 /* nsec */
+#define DEFAULT_AUDIO_SINK_ASYNC FALSE
+#define DEFAULT_VIDEO_SINK_ASYNC FALSE
 #define DEFAULT_ENABLE_TS_DATA_DUMP            FALSE
 #define DEFAULT_ENABLE_WFDRTSPSRC_PAD_PROBE FALSE
 
@@ -147,7 +153,7 @@ typedef struct __mm_wfd_sink_ini
 #define DEFAULT_NAME_OF_VIDEO_SINK ""
 
 /* Audio */
-#define DEFAULT_AUDIO_CODEC WFD_AUDIO_LPCM | WFD_AUDIO_AAC | WFD_AUDIO_AC3
+#define DEFAULT_AUDIO_CODEC WFD_AUDIO_LPCM | WFD_AUDIO_AAC
 #define DEFAULT_AUDIO_LATENCY 0x0
 #define DEFAULT_AUDIO_CHANNELS WFD_CHANNEL_2
 #define DEFAULT_AUDIO_SAMP_FREQUENCY WFD_FREQ_44100 | WFD_FREQ_48000
@@ -167,7 +173,7 @@ typedef struct __mm_wfd_sink_ini
 #define DEFAULT_VIDEO_PROFILE WFD_H264_BASE_PROFILE
 #define DEFAULT_VIDEO_LEVEL WFD_H264_LEVEL_3_2
 #define DEFAULT_VIDEO_LATENCY 0x0
-#define DEFAULT_VIDEO_VERTICAL_RESOLUTION 1200
+#define DEFAULT_VIDEO_VERTICAL_RESOLUTION 1080
 #define DEFAULT_VIDEO_HORIZONTAL_RESOLUTION 1920
 #define DEFAULT_VIDEO_MIN_SLICESIZE 0
 #define DEFAULT_VIDEO_SLICE_ENC_PARAM 200
@@ -183,7 +189,7 @@ typedef struct __mm_wfd_sink_ini
 [general]\n\
 ; parameters for initializing gstreamer\n\
 ; DEFAULT SET (--gst-debug=2,*wfd*:5)\n\
-gstparam1 = --gst-debug=2,*wfd*:5\n\
+gstparam1 = --gst-debug=2,*wfd*:5,*wfdtsdemux:1,*wfdrtpbuffer:1\n\
 gstparam2 =\n\
 gstparam3 =\n\
 gstparam4 =\n\
@@ -212,7 +218,7 @@ set debug property = yes\n\
 enable asm = no\n\
 \n\
 ; 0: default value set by wfdrtspsrc element, other: user define value.\n\
-jitter buffer latency=33\n\
+jitter buffer latency=10\n\
 \n\
 ; for retransmission request enable = yes, disable = no\n\
 enable retransmission = yes\n\
@@ -223,6 +229,15 @@ enable reset basetime = yes\n\
 ; Maximum number of nanoseconds that a buffer can be late before it is dropped by videosink (-1 unlimited)\n\
 video sink max lateness=20000000\n\
 \n\
+; nanoseconds to be added to buffertimestamp by sink elements\n\
+sink ts offset=150000000\n\
+\n\
+; if no, go asynchronously to PAUSED without preroll \n\
+audio sink async=no\n\
+\n\
+; if no, go asynchronously to PAUSED without preroll \n\
+video sink async=no\n\
+\n\
 \n\
 \n\
 [pipeline]\n\
@@ -281,7 +296,7 @@ video native resolution = 0x20\n\
 \n\
 video cea support=0x194ab\n\
 \n\
-video vesa support=0x15555555\n\
+video vesa support=0x5555555\n\
 \n\
 video hh support=0x555\n\
 \n\
@@ -293,7 +308,7 @@ video level=0x2\n\
 \n\
 video latency=0x0\n\
 \n\
-video vertical resolution=1200\n\
+video vertical resolution=1080\n\
 \n\
 video horizontal resolution=1920\n\
 \n\
index 9bf3261..63d68d4 100755 (executable)
@@ -24,9 +24,9 @@
 #include <glib/gstdio.h>
 #include <stdlib.h>
 #include <iniparser.h>
-#include <mm_debug.h>
 #include <mm_error.h>
 #include "mm_wfd_sink_ini.h"
+#include "mm_wfd_sink_dlog.h"
 
 static gboolean loaded = FALSE;
 
@@ -92,7 +92,7 @@ mm_wfd_sink_ini_load (mm_wfd_sink_ini_t* ini)
 {
        dictionary * dict = NULL;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
 
        __mm_wfd_sink_ini_check_status();
@@ -104,10 +104,10 @@ mm_wfd_sink_ini_load (mm_wfd_sink_ini_t* ini)
        if ( !dict )
        {
 #ifdef MM_WFD_SINK_DEFAULT_INI
-               debug_log("No inifile found. create default ini file.\n");
+               wfd_sink_debug("No inifile found. create default ini file.\n");
                if ( FALSE == __generate_sink_default_ini() )
                {
-                       debug_error("Creating default ini file failed. Use default values.\n");
+                       wfd_sink_error("Creating default ini file failed. Use default values.\n");
                }
                else
                {
@@ -115,7 +115,7 @@ mm_wfd_sink_ini_load (mm_wfd_sink_ini_t* ini)
                        dict = iniparser_load (MM_WFD_SINK_INI_DEFAULT_PATH);
                }
 #else
-               debug_error("No ini file found. \n");
+               wfd_sink_error("No ini file found. \n");
 
                return MM_ERROR_FILE_NOT_FOUND;
 #endif
@@ -141,6 +141,9 @@ mm_wfd_sink_ini_load (mm_wfd_sink_ini_t* ini)
                ini->enable_retransmission = iniparser_getboolean(dict, "general:enable retransmission", DEFAULT_ENABLE_RETRANSMISSION);
                ini->enable_reset_basetime = iniparser_getboolean(dict, "general:enable reset basetime", DEFAULT_ENABLE_RESET_BASETIME);
                ini->video_sink_max_lateness = iniparser_getint(dict, "general:video sink max lateness", DEFAULT_VIDEO_SINK_MAX_LATENESS);
+               ini->sink_ts_offset = iniparser_getint(dict, "general:sink ts offset", DEFAULT_SINK_TS_OFFSET);
+               ini->audio_sink_async = iniparser_getboolean(dict, "general:audio sink async", DEFAULT_AUDIO_SINK_ASYNC);
+               ini->video_sink_async = iniparser_getboolean(dict, "general:video sink async", DEFAULT_VIDEO_SINK_ASYNC);
                ini->enable_ts_data_dump = iniparser_getboolean(dict, "general:enable ts data dump", DEFAULT_ENABLE_TS_DATA_DUMP);
                ini->enable_wfdrtspsrc_pad_probe = iniparser_getboolean(dict, "general:enable wfdrtspsrc pad probe", DEFAULT_ENABLE_WFDRTSPSRC_PAD_PROBE);
 
@@ -189,7 +192,7 @@ mm_wfd_sink_ini_load (mm_wfd_sink_ini_t* ini)
        }
        else /* if dict is not available just fill the structure with default value */
        {
-               debug_error("failed to load ini. using hardcoded default\n");
+               wfd_sink_error("failed to load ini. using hardcoded default\n");
 
                /* general */
                strncpy( ini->gst_param[0], DEFAULT_GST_PARAM, WFD_SINK_INI_MAX_STRLEN - 1 );
@@ -206,6 +209,7 @@ mm_wfd_sink_ini_load (mm_wfd_sink_ini_t* ini)
                ini->enable_retransmission =  DEFAULT_ENABLE_RETRANSMISSION;
                ini->enable_reset_basetime =  DEFAULT_ENABLE_RESET_BASETIME;
                ini->video_sink_max_lateness = DEFAULT_VIDEO_SINK_MAX_LATENESS;
+               ini->sink_ts_offset = DEFAULT_SINK_TS_OFFSET;
                ini->enable_ts_data_dump = DEFAULT_ENABLE_TS_DATA_DUMP;
                ini->enable_wfdrtspsrc_pad_probe = DEFAULT_ENABLE_WFDRTSPSRC_PAD_PROBE;
 
@@ -257,78 +261,84 @@ mm_wfd_sink_ini_load (mm_wfd_sink_ini_t* ini)
 
 
        /* dump structure */
-       debug_log("W-Fi Display Sink Initial Settings -----------------------------------\n");
+       wfd_sink_debug("W-Fi Display Sink Initial Settings -----------------------------------\n");
 
        /* general */
-       debug_log("gst_param1 : %s\n", ini->gst_param[0]);
-       debug_log("gst_param2 : %s\n", ini->gst_param[1]);
-       debug_log("gst_param3 : %s\n", ini->gst_param[2]);
-       debug_log("gst_param4 : %s\n", ini->gst_param[3]);
-       debug_log("gst_param5 : %s\n", ini->gst_param[4]);
-       debug_log("generate_dot : %d\n", ini->generate_dot);
+       wfd_sink_debug("gst_param1 : %s\n", ini->gst_param[0]);
+       wfd_sink_debug("gst_param2 : %s\n", ini->gst_param[1]);
+       wfd_sink_debug("gst_param3 : %s\n", ini->gst_param[2]);
+       wfd_sink_debug("gst_param4 : %s\n", ini->gst_param[3]);
+       wfd_sink_debug("gst_param5 : %s\n", ini->gst_param[4]);
+       wfd_sink_debug("generate_dot : %d\n", ini->generate_dot);
        if (ini->generate_dot == TRUE)
        {
-               debug_log("generate_dot is TRUE, dot file will be stored into /tmp/\n");
+               wfd_sink_debug("generate_dot is TRUE, dot file will be stored into /tmp/\n");
                g_setenv ("GST_DEBUG_DUMP_DOT_DIR", "/tmp/", FALSE);
        }
-       debug_log("enable_pad_probe : %d\n", ini->enable_pad_probe);
-       debug_log("state_change_timeout(sec) : %d\n", ini->state_change_timeout);
-       debug_log("set_debug_property : %d\n", ini->set_debug_property);
-       debug_log("enable_asm : %d\n", ini->enable_asm);
-       debug_log("jitter_buffer_latency(msec) : %d\n", ini->jitter_buffer_latency);
-       debug_log("enable_retransmission : %d\n", ini->enable_retransmission);
-       debug_log("enable_reset_basetime : %d\n", ini->enable_reset_basetime);
-       debug_log("video_sink_max_lateness(nsec) : %d\n", ini->video_sink_max_lateness);
-       debug_log("enable_ts_data_dump : %d\n", ini->enable_ts_data_dump);
-       debug_log("enable_wfdrtspsrc_pad_probe : %d\n", ini->enable_wfdrtspsrc_pad_probe);
+       wfd_sink_debug("enable_pad_probe : %d\n", ini->enable_pad_probe);
+       wfd_sink_debug("state_change_timeout(sec) : %d\n", ini->state_change_timeout);
+       wfd_sink_debug("set_debug_property : %d\n", ini->set_debug_property);
+       wfd_sink_debug("enable_asm : %d\n", ini->enable_asm);
+       wfd_sink_debug("jitter_buffer_latency(msec) : %d\n", ini->jitter_buffer_latency);
+       wfd_sink_debug("enable_retransmission : %d\n", ini->enable_retransmission);
+       wfd_sink_debug("enable_reset_basetime : %d\n", ini->enable_reset_basetime);
+       wfd_sink_debug("video_sink_max_lateness(nsec) : %d\n", ini->video_sink_max_lateness);
+       wfd_sink_debug("sink_ts_offset(nsec) : %d\n", ini->sink_ts_offset);
+       wfd_sink_debug("audio_sink_async : %d\n", ini->audio_sink_async);
+       wfd_sink_debug("video_sink_async : %d\n", ini->video_sink_async);
+       wfd_sink_debug("enable_ts_data_dump : %d\n", ini->enable_ts_data_dump);
+       wfd_sink_debug("enable_wfdrtspsrc_pad_probe : %d\n", ini->enable_wfdrtspsrc_pad_probe);
 
        /* pipeline */
-       debug_log("name_of_tsdemux : %s\n", ini->name_of_tsdemux);
-       debug_log("name_of_audio_hdcp : %s\n", ini->name_of_audio_hdcp);
-       debug_log("name_of_aac_parser : %s\n", ini->name_of_aac_parser);
-       debug_log("name_of_aac_decoder : %s\n", ini->name_of_aac_decoder);
-       debug_log("name_of_ac3_parser : %s\n", ini->name_of_ac3_parser);
-       debug_log("name_of_ac3_decoder : %s\n", ini->name_of_ac3_decoder);
-       debug_log("name_of_lpcm_converter : %s\n", ini->name_of_lpcm_converter);
-       debug_log("name_of_lpcm_filter : %s\n", ini->name_of_lpcm_filter);
-       debug_log("name_of_audio_resampler : %s\n", ini->name_of_audio_resampler);
-       debug_log("name_of_audio_volume : %s\n", ini->name_of_audio_volume);
-       debug_log("name_of_audio_sink : %s\n", ini->name_of_audio_sink);
-       debug_log("name_of_video_hdcp : %s\n", ini->name_of_video_hdcp);
-       debug_log("name_of_video_parser : %s\n", ini->name_of_video_parser);
-       debug_log("name_of_video_decoder : %s\n", ini->name_of_video_decoder);
-       debug_log("name_of_video_sink : %s\n", ini->name_of_video_sink);
+       wfd_sink_debug("name_of_tsdemux : %s\n", ini->name_of_tsdemux);
+       wfd_sink_debug("name_of_audio_hdcp : %s\n", ini->name_of_audio_hdcp);
+       wfd_sink_debug("name_of_aac_parser : %s\n", ini->name_of_aac_parser);
+       wfd_sink_debug("name_of_aac_decoder : %s\n", ini->name_of_aac_decoder);
+       wfd_sink_debug("name_of_ac3_parser : %s\n", ini->name_of_ac3_parser);
+       wfd_sink_debug("name_of_ac3_decoder : %s\n", ini->name_of_ac3_decoder);
+       wfd_sink_debug("name_of_lpcm_converter : %s\n", ini->name_of_lpcm_converter);
+       wfd_sink_debug("name_of_lpcm_filter : %s\n", ini->name_of_lpcm_filter);
+       wfd_sink_debug("name_of_audio_resampler : %s\n", ini->name_of_audio_resampler);
+       wfd_sink_debug("name_of_audio_volume : %s\n", ini->name_of_audio_volume);
+#ifdef ENABLE_WFD_VD_FEATURES
+       wfd_sink_debug("name_of_audio_splitter : %s\n", ini->name_of_audio_splitter);
+#endif
+       wfd_sink_debug("name_of_audio_sink : %s\n", ini->name_of_audio_sink);
+       wfd_sink_debug("name_of_video_hdcp : %s\n", ini->name_of_video_hdcp);
+       wfd_sink_debug("name_of_video_parser : %s\n", ini->name_of_video_parser);
+       wfd_sink_debug("name_of_video_decoder : %s\n", ini->name_of_video_decoder);
+       wfd_sink_debug("name_of_video_sink : %s\n", ini->name_of_video_sink);
 
        /* audio parameter*/
-       debug_log("audio_codec : %x\n", ini->audio_codec);
-       debug_log("audio_latency : %d\n", ini->audio_latency);
-       debug_log("audio_channel : %x\n", ini->audio_channel);
-       debug_log("audio_sampling_frequency : %x\n", ini->audio_sampling_frequency);
+       wfd_sink_debug("audio_codec : %x\n", ini->audio_codec);
+       wfd_sink_debug("audio_latency : %d\n", ini->audio_latency);
+       wfd_sink_debug("audio_channel : %x\n", ini->audio_channel);
+       wfd_sink_debug("audio_sampling_frequency : %x\n", ini->audio_sampling_frequency);
 
        /* video parameter*/
-       debug_log("video_codec : %x\n", ini->video_codec);
-       debug_log("video_native_resolution : %x\n", ini->video_native_resolution);
-       debug_log("video_cea_support : %x\n", ini->video_cea_support);
-       debug_log("video_vesa_support : %x\n", ini->video_vesa_support);
-       debug_log("video_hh_support : %x\n", ini->video_hh_support);
-       debug_log("video_profile : %x\n", ini->video_profile);
-       debug_log("video_level : %x\n", ini->video_level);
-       debug_log("video_latency : %d\n", ini->video_latency);
-       debug_log("video_vertical_resolution : %d\n", ini->video_vertical_resolution);
-       debug_log("video_horizontal_resolution : %d\n", ini->video_horizontal_resolution);
-       debug_log("video_minimum_slicing : %d\n", ini->video_minimum_slicing);
-       debug_log("video_slice_enc_param : %d\n", ini->video_slice_enc_param);
-       debug_log("video_framerate_control_support : %d\n", ini->video_framerate_control_support);
+       wfd_sink_debug("video_codec : %x\n", ini->video_codec);
+       wfd_sink_debug("video_native_resolution : %x\n", ini->video_native_resolution);
+       wfd_sink_debug("video_cea_support : %x\n", ini->video_cea_support);
+       wfd_sink_debug("video_vesa_support : %x\n", ini->video_vesa_support);
+       wfd_sink_debug("video_hh_support : %x\n", ini->video_hh_support);
+       wfd_sink_debug("video_profile : %x\n", ini->video_profile);
+       wfd_sink_debug("video_level : %x\n", ini->video_level);
+       wfd_sink_debug("video_latency : %d\n", ini->video_latency);
+       wfd_sink_debug("video_vertical_resolution : %d\n", ini->video_vertical_resolution);
+       wfd_sink_debug("video_horizontal_resolution : %d\n", ini->video_horizontal_resolution);
+       wfd_sink_debug("video_minimum_slicing : %d\n", ini->video_minimum_slicing);
+       wfd_sink_debug("video_slice_enc_param : %d\n", ini->video_slice_enc_param);
+       wfd_sink_debug("video_framerate_control_support : %d\n", ini->video_framerate_control_support);
 
        /* hdcp parameter*/
-       debug_log("hdcp_content_protection : %x\n", ini->hdcp_content_protection);
-       debug_log("hdcp_port_no : %d\n", ini->hdcp_port_no);
+       wfd_sink_debug("hdcp_content_protection : %x\n", ini->hdcp_content_protection);
+       wfd_sink_debug("hdcp_port_no : %d\n", ini->hdcp_port_no);
 
-       debug_log("---------------------------------------------------\n");
+       wfd_sink_debug("---------------------------------------------------\n");
 
        loaded = TRUE;
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 }
@@ -339,32 +349,32 @@ void __mm_wfd_sink_ini_check_status (void)
 {
        struct stat ini_buff;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
        if ( g_stat(MM_WFD_SINK_INI_DEFAULT_PATH, &ini_buff) < 0 )
        {
-               debug_error("failed to get mmfw_wfd_sink ini status\n");
+               wfd_sink_error("failed to get mmfw_wfd_sink ini status\n");
        }
        else
        {
                if ( ini_buff.st_size < 5 )
                {
-                       debug_error("mmfw_wfd_sink.ini file size=%d, Corrupted! So, Removed\n", (int)ini_buff.st_size);
+                       wfd_sink_error("mmfw_wfd_sink.ini file size=%d, Corrupted! So, Removed\n", (int)ini_buff.st_size);
                        g_remove( MM_WFD_SINK_INI_DEFAULT_PATH );
                }
        }
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 }
 
 int
 mm_wfd_sink_ini_unload (mm_wfd_sink_ini_t* ini)
 {
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
        loaded = FALSE;
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 }
index c1a4443..ab60b02 100755 (executable)
@@ -1,7 +1,7 @@
 [general]
 ; parameters for initializing gstreamer
-; DEFAULT SET (--gst-debug=*wfd*:5)
-gstparam1 = --gst-debug=*wfd*:5
+; DEFAULT SET (--gst-debug=2,*wfd*:5)
+gstparam1 = --gst-debug=2,*wfd*:5,*wfdtsdemux:1,*wfdrtpbuffer:1
 gstparam2 =
 gstparam3 =
 gstparam4 =
@@ -27,20 +27,28 @@ state change timeout = 5; sec
 set debug property = yes
 
 ; for asm function enable = yes, disable = no
-enable asm = yes
+enable asm = no
 
 ; 0: default value set by wfdrtspsrc element, other: user define value.
-jitter buffer latency=33
+jitter buffer latency=10
 
 ; for retransmission request enable = yes, disable = no
 enable retransmission = yes
 
 ; for reset basetime, enable = yes, disable = no
-enable reset basetime = no
+enable reset basetime = yes
 
 ; Maximum number of nanoseconds that a buffer can be late before it is dropped by videosink (-1 unlimited)
 video sink max lateness=20000000
 
+; nanoseconds to be added to buffertimestamp by sink elements
+sink ts offset=150000000
+
+; if no, go asynchronously to PAUSED without preroll
+audio sink async=no
+
+; if no, go asynchronously to PAUSED without preroll
+video sink async=no
 
 
 [pipeline]
@@ -66,7 +74,7 @@ audio sink element = pulsesink
 
 video parser element = h264parse
 
-video decoder element = avdec_h264
+video decoder element = omxh264dec;avdec_h264
 
 video sink element = xvimagesink
 
@@ -95,7 +103,7 @@ video native resolution = 0x20
 
 video cea support=0x194ab
 
-video vesa support=0x15555555
+video vesa support=0x5555555
 
 video hh support=0x555
 
@@ -107,7 +115,7 @@ video level=0x2
 
 video latency=0x0
 
-video vertical resolution=1200
+video vertical resolution=1080
 
 video horizontal resolution=1920
 
index eb27a81..7f3d033 100755 (executable)
@@ -81,6 +81,10 @@ PKG_CHECK_MODULES(MM_WFD_COMMON, mm-scmirroring-common)
 AC_SUBST(MM_WFD_COMMON_CFLAGS)
 AC_SUBST(MM_WFD_COMMON_LIBS)
 
+PKG_CHECK_MODULES(DLOG, dlog)
+AC_SUBST(DLOG_CFLAGS)
+AC_SUBST(DLOG_LIBS)
+
 # for testsuite
 
 AC_ARG_ENABLE(sdk, AC_HELP_STRING([--enable-sdk], [sdk build]),
index 2c3fe79..400bd1f 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-wfd
 Summary:    Multimedia Framework Wifi-Display Library
-Version:    0.2.140
+Version:    0.2.162
 Release:    0
 Group:      System/Libraries
 License:    Apache License 2.0
@@ -13,10 +13,10 @@ BuildRequires: pkgconfig(gstreamer-plugins-base-1.0)
 BuildRequires: pkgconfig(gstreamer-video-1.0)
 BuildRequires: pkgconfig(gstreamer-app-1.0)
 BuildRequires: pkgconfig(iniparser)
-BuildRequires: pkgconfig(wifi-direct)
 BuildRequires: pkgconfig(capi-network-wifi-direct)
 BuildRequires: pkgconfig(mm-scmirroring-common)
 BuildRequires: kernel-headers
+BuildRequires: pkgconfig(dlog)
 
 BuildRoot:  %{_tmppath}/%{name}-%{version}-build
 
index 5997998..9e1ee59 100755 (executable)
 #include <mm_types.h>
 
 /**
- *  * Enumerations of wifi-display state.
+ *  * Enumerations of wifi-display sink state.
  *   */
 typedef enum {
-       MM_WFD_SINK_STATE_NULL,                 /**< wifi-display is created */
-       MM_WFD_SINK_STATE_READY,                /**< wifi-display is ready to connect  */
-       MM_WFD_SINK_STATE_PLAYING,              /**< wifi-display is now playing  */
-       MM_WFD_SINK_STATE_PAUSED,                /**< wifi-display is connected */
-       MM_WFD_SINK_STATE_TEARDOWN,     /**< wifi-display is disconnected */
-       MM_WFD_SINK_STATE_NONE,                 /**< wifi-display is not created */
-       MM_WFD_SINK_STATE_NUM,                  /**< Number of wifi-display states */
-} MMWfdSinkStateType;
+       MM_WFD_SINK_STATE_NONE,                         /**< wifi-display is not created */
+       MM_WFD_SINK_STATE_NULL,                         /**< wifi-display is created */
+       MM_WFD_SINK_STATE_PREPARED,                     /**< wifi-display is prepared */
+       MM_WFD_SINK_STATE_CONNECTED,             /**< wifi-display is connected */
+       MM_WFD_SINK_STATE_PLAYING,                      /**< wifi-display is now playing  */
+       MM_WFD_SINK_STATE_PAUSED,                       /**< wifi-display is now paused  */
+       MM_WFD_SINK_STATE_DISCONNECTED, /**< wifi-display is disconnected */
+       MM_WFD_SINK_STATE_NUM,                          /**< Number of wifi-display states */
+} MMWFDSinkStateType;
 
-typedef void (*MMWFDMessageCallback)(MMWfdSinkStateType type, void *user_data);
+typedef void (*MMWFDMessageCallback)(int error_type, MMWFDSinkStateType state_type, void *user_data);
 
 /**
  * This function creates a wi-fi display sink object. \n
@@ -65,7 +66,7 @@ typedef void (*MMWFDMessageCallback)(MMWfdSinkStateType type, void *user_data);
  * @code
 if (mm_wfd_sink_create(&g_wfd_sink) != MM_ERROR_NONE)
 {
-       debug_error("failed to create wi-fi display sink\n");
+       wfd_sink_error("failed to create wi-fi display sink\n");
 }
 
 mm_wfd_sink_set_message_callback(g_wfd_sink, msg_callback, (void*)g_wfd_sink);
@@ -83,17 +84,17 @@ int mm_wfd_sink_create(MMHandleType *wfd_sink);
  *                     Please refer 'mm_error.h' to know it in detail.
  * @pre                MM_WFD_SINK_STATE_NULL
  * @post               MM_WFD_SINK_STATE_READY
- * @see                mm_wfd_sink_unrealize
+ * @see                mm_wfd_sink_unprepare
  * @remark     None
  * @par Example
  * @code
-if (mm_wfd_sink_realize(&g_wfd_sink) != MM_ERROR_NONE)
+if (mm_wfd_sink_prepare(&g_wfd_sink) != MM_ERROR_NONE)
 {
-       debug_error("failed to realize wi-fi display sink\n");
+       wfd_sink_error("failed to realize wi-fi display sink\n");
 }
  * @endcode
  */
-int mm_wfd_sink_realize(MMHandleType wfd_sink);
+int mm_wfd_sink_prepare(MMHandleType wfd_sink);
 
 /**
  * This function connect wi-fi display source using uri. \n
@@ -111,7 +112,7 @@ int mm_wfd_sink_realize(MMHandleType wfd_sink);
  * @code
 if (mm_wfd_sink_connect(g_wfd_sink, g_uri) != MM_ERROR_NONE)
 {
-       debug_error("failed to connect to wi-fi display source\n");
+       wfd_sink_error("failed to connect to wi-fi display source\n");
 }
  * @endcode
  */
@@ -128,13 +129,13 @@ int mm_wfd_sink_connect(MMHandleType wfd_sink, const char *uri);
  *
  * @pre                wi-fi display sink state may be MM_WFD_SINK_STATE_PAUSED.
  * @post               wi-fi display sink state will be MM_WFD_SINK_STATE_PLAYING.
- * @see                mm_wfd_sink_stop
+ * @see                mm_wfd_sink_disconnect
  * @remark     None
  * @par Example
  * @code
 if (mm_wfd_sink_start(g_wfd_sink) != MM_ERROR_NONE)
 {
-       debug_error("failed to start wi-fi display sink\n");
+       wfd_sink_error("failed to start wi-fi display sink\n");
 }
  * @endcode
  */
@@ -153,13 +154,13 @@ int mm_wfd_sink_start(MMHandleType wfd_sink);
  * @remark     None
  * @par Example
  * @code
-if (mm_wfd_sink_stop(g_wfd_sink) != MM_ERROR_NONE)
+if (mm_wfd_sink_disconnect(g_wfd_sink) != MM_ERROR_NONE)
 {
-       debug_error("failed to stop wi-fi display sink\n");
+       wfd_sink_error("failed to stop wi-fi display sink\n");
 }
  * @endcode
  */
-int mm_wfd_sink_stop(MMHandleType wfd_sink);
+int mm_wfd_sink_disconnect(MMHandleType wfd_sink);
 
 /**
  * This function trys to destroy gstreamer pipeline. \n
@@ -171,17 +172,17 @@ int mm_wfd_sink_stop(MMHandleType wfd_sink);
  * @pre                wi-fi display sink state may be MM_WFD_SINK_STATE_READY.
  *                     But, it can be called in any state.
  * @post               MM_WFD_SINK_STATE_NULL
- * @see                mm_wfd_sink_realize
+ * @see                mm_wfd_sink_prepare
  * @remark     None
  * @par Example
  * @code
-if (mm_wfd_sink_unrealize(&g_wfd_sink) != MM_ERROR_NONE)
+if (mm_wfd_sink_unprepare(&g_wfd_sink) != MM_ERROR_NONE)
 {
-       debug_error("failed to unrealize wi-fi display sink\n");
+       wfd_sink_error("failed to unrealize wi-fi display sink\n");
 }
  * @endcode
  */
-int mm_wfd_sink_unrealize(MMHandleType wfd_sink);
+int mm_wfd_sink_unprepare(MMHandleType wfd_sink);
 
 /**
  * This function releases wi-fi display sink object and all resources which were created by mm_wfd_sink_create(). \n
@@ -201,7 +202,7 @@ int mm_wfd_sink_unrealize(MMHandleType wfd_sink);
  * @code
 if (mm_wfd_sink_destroy(g_wfd_sink) != MM_ERROR_NONE)
 {
-       debug_error("failed to destroy wi-fi display sink\n");
+       wfd_sink_error("failed to destroy wi-fi display sink\n");
 }
  * @endcode
  */
@@ -221,9 +222,9 @@ int mm_wfd_sink_destroy(MMHandleType wfd_sink);
  * @par Example
  * @code
 
-int msg_callback( MMWfdSinkStateType type, void *user_data)
+int msg_callback(int error_type, MMWFDSinkStateType state_type, void *user_data)
 {
-       switch (type)
+       switch (state_type)
        {
                case MM_WFD_SINK_STATE_NULL:
                        //do something
@@ -272,7 +273,7 @@ int mm_wfd_sink_set_attribute(MMHandleType wfd_sink,  char **err_attr_name, cons
  * @code
 if (mm_wfd_sink_get_resource(g_wfd_sink) != MM_ERROR_NONE)
 {
-       debug_error("failed to get resources for wi-fi display sink\n");
+       wfd_sink_error("failed to get resources for wi-fi display sink\n");
 }
  * @endcode
  */
@@ -291,7 +292,7 @@ int mm_wfd_sink_get_resource(MMHandleType wfd_sink);
  * @code
 if (mm_wfd_sink_set_display_surface_type(g_wfd_sink, g_display_surface_type) != MM_ERROR_NONE)
 {
-       debug_error("failed to set display surface type for wi-fi display sink\n");
+       wfd_sink_error("failed to set display surface type for wi-fi display sink\n");
 }
  * @endcode
  */
@@ -310,7 +311,7 @@ int mm_wfd_sink_set_display_surface_type(MMHandleType wfd_sink, gint display_sur
  * @code
 if (mm_wfd_sink_set_display_overlay(g_wfd_sink, g_display_overlay) != MM_ERROR_NONE)
 {
-       debug_error("failed to set display overlay for wi-fi display sink\n");
+       wfd_sink_error("failed to set display overlay for wi-fi display sink\n");
 }
  * @endcode
  */
@@ -329,7 +330,7 @@ int mm_wfd_sink_set_display_overlay(MMHandleType wfd_sink, void *display_overlay
  * @code
 if (mm_wfd_sink_set_display_method(g_wfd_sink, g_display_method) != MM_ERROR_NONE)
 {
-       debug_error("failed to set display method for wi-fi display sink\n");
+       wfd_sink_error("failed to set display method for wi-fi display sink\n");
 }
  * @endcode
  */
@@ -348,7 +349,7 @@ int mm_wfd_sink_set_display_method(MMHandleType wfd_sink, gint display_method);
  * @code
 if (mm_wfd_sink_set_display_visible(g_wfd_sink, g_display_visible) != MM_ERROR_NONE)
 {
-       debug_error("failed to set display visible for wi-fi display sink\n");
+       wfd_sink_error("failed to set display visible for wi-fi display sink\n");
 }
  * @endcode
  */
@@ -370,7 +371,7 @@ gint g_width=0, g_height=0;
 
 if (mm_wfd_sink_get_video_resolution(g_wfd_sink, &g_width, &g_height) != MM_ERROR_NONE)
 {
-       debug_error("failed to get video resolution.\n");
+       wfd_sink_error("failed to get video resolution.\n");
 }
  * @endcode
  */
@@ -391,7 +392,7 @@ gint g_framerate=0;
 
 if (mm_wfd_sink_get_video_framerate(g_wfd_sink, &g_framerate) != MM_ERROR_NONE)
 {
-       debug_error("failed to get video framerate.\n");
+       wfd_sink_error("failed to get video framerate.\n");
 }
  * @endcode
  */
index d9c8966..b6eb9d0 100755 (executable)
        extern "C" {
 #endif
 
-#define WFD_SINK_MANAGER_LOCK(wfd_sink)   (g_mutex_lock ((wfd_sink)->manager_thread_mutex))
-#define WFD_SINK_MANAGER_UNLOCK(wfd_sink) (g_mutex_unlock ((wfd_sink)->manager_thread_mutex))
+#define WFD_SINK_MANAGER_LOCK(wfd_sink) \
+do{\
+       if (wfd_sink)\
+       {\
+               g_mutex_lock (&((wfd_sink)->manager_thread_mutex));\
+       }\
+} while(0);
+
+#define WFD_SINK_MANAGER_UNLOCK(wfd_sink) \
+do{\
+       if (wfd_sink)\
+       {\
+               g_mutex_unlock (&((wfd_sink)->manager_thread_mutex));\
+       }\
+} while(0);
+
 #define WFD_SINK_MANAGER_WAIT_CMD(wfd_sink) \
 do{\
-       debug_log ("manager thread is waiting for command signal\n");\
-       g_cond_wait ((wfd_sink)->manager_thread_cond, (wfd_sink)->manager_thread_mutex); \
+       wfd_sink_debug ("manager thread is waiting for command signal\n");\
+       wfd_sink->waiting_cmd = TRUE; \
+       g_cond_wait (&((wfd_sink)->manager_thread_cond), &((wfd_sink)->manager_thread_mutex)); \
+       wfd_sink->waiting_cmd = FALSE; \
 } while(0);
+
 #define WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink, cmd) \
 do{\
-       wfd_sink->manager_thread_cmd |= cmd;\
-       debug_log ("send command signal to manager thread with %x command\n", wfd_sink->manager_thread_cmd);\
-       g_cond_signal ((wfd_sink)->manager_thread_cond);\
+       if (wfd_sink->manager_thread_cmd != WFD_SINK_MANAGER_CMD_EXIT)\
+       {\
+               wfd_sink->manager_thread_cmd |= cmd;\
+               if (wfd_sink->waiting_cmd)\
+               {\
+                       wfd_sink_debug ("send command signal to manager thread with %x command\n", &(wfd_sink->manager_thread_cmd));\
+                       g_cond_signal (&((wfd_sink)->manager_thread_cond));\
+               }\
+       }\
 } while(0);
 
-
 /**
  * This function is to initialize manager
  *
index ae70cb9..7962af7 100755 (executable)
@@ -101,14 +101,14 @@ enum WFDSinkVideoCodec
 typedef enum {
        MM_WFD_SINK_COMMAND_NONE,               /**< command for nothing */
        MM_WFD_SINK_COMMAND_CREATE,             /**< command for creating wifi-display sink */
-       MM_WFD_SINK_COMMAND_REALIZE,            /**< command for realizing wifi-display sink */
+       MM_WFD_SINK_COMMAND_PREPARE,            /**< command for preparing wifi-display sink */
        MM_WFD_SINK_COMMAND_CONNECT,    /**< command for connecting wifi-display sink  */
        MM_WFD_SINK_COMMAND_START,       /**< command for starting wifi-display sink  */
-       MM_WFD_SINK_COMMAND_STOP,       /**< command for stopping wifi-display sink  */
-       MM_WFD_SINK_COMMAND_UNREALIZE,          /**< command for unrealizing wifi-display sink  */
+       MM_WFD_SINK_COMMAND_DISCONNECT, /**< command for disconnecting wifi-display sink  */
+       MM_WFD_SINK_COMMAND_UNPREPARE,          /**< command for unpreparing wifi-display sink  */
        MM_WFD_SINK_COMMAND_DESTROY,            /**< command for destroting wifi-display sink  */
        MM_WFD_SINK_COMMAND_NUM,                /**< Number of wifi-display commands */
-} MMWfdSinkCommandType;
+} MMWFDSinkCommandType;
 
 /**
  *  * Enumerations of thread command.
@@ -160,9 +160,9 @@ typedef struct
 
 typedef struct
 {
-       MMWfdSinkStateType state;         // wfd current state
-       MMWfdSinkStateType prev_state;    // wfd  previous state
-       MMWfdSinkStateType pending_state; // wfd  state which is going to now
+       MMWFDSinkStateType state;         // wfd current state
+       MMWFDSinkStateType prev_state;    // wfd  previous state
+       MMWFDSinkStateType pending_state; // wfd  state which is going to now
 } MMWFDSinkState;
 
 #define MMWFDSINK_GET_ATTRS(x_wfd) ((x_wfd)? ((mm_wfd_sink_t*)x_wfd)->attrs : (MMHandleType)NULL)
@@ -170,19 +170,26 @@ typedef struct
 typedef struct {
        /* gstreamer pipeline */
        MMWFDSinkGstPipelineInfo *pipeline;
-       gboolean is_constructed;
        gint added_av_pad_num;
        gboolean audio_bin_is_linked;
        gboolean video_bin_is_linked;
-       gboolean audio_bin_is_prepared;
-       gboolean video_bin_is_prepared;
        GstPad * prev_audio_dec_src_pad;
        GstPad * next_audio_dec_sink_pad;
-       guint demux_video_pad_probe_id;
-       guint demux_audio_pad_probe_id;
+
+       /* timestamp compensation */
        gboolean need_to_reset_basetime;
+
+       GstClock *clock;
+       gint64 video_average_gap;
+       gint64 video_accumulated_gap;
+       gint64 video_buffer_count;
+       gint64 audio_average_gap;
+       gint64 audio_accumulated_gap;
+       gint64 audio_buffer_count;
+       GstClockTime last_buffer_timestamp;
+
        /* attributes */
-       MMHandleType attrs;
+       MMHandleType attrs;
 
        /* state */
        MMWFDSinkState state;
@@ -191,9 +198,9 @@ typedef struct {
        mm_wfd_sink_ini_t ini;
 
        /* command */
-       MMWfdSinkCommandType cmd;
-       GMutex* cmd_lock;
-
+       MMWFDSinkCommandType cmd;
+       GMutex cmd_lock;
+       gboolean waiting_cmd;
 
        /* stream information */
        MMWFDSinkStreamInfo stream_info;
@@ -206,19 +213,19 @@ typedef struct {
        GList *resource_list;
 
        GThread         *manager_thread;
-       GMutex *manager_thread_mutex;
-       GCond* manager_thread_cond;
+       GMutex manager_thread_mutex;
+       GCond manager_thread_cond;
        WFDSinkManagerCMDType manager_thread_cmd;
 } mm_wfd_sink_t;
 
 
 int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink);
-int _mm_wfd_sink_realize(mm_wfd_sink_t *wfd_sink);
+int _mm_wfd_sink_destroy(mm_wfd_sink_t *wfd_sink);
+int _mm_wfd_sink_prepare(mm_wfd_sink_t *wfd_sink);
+int _mm_wfd_sink_unprepare(mm_wfd_sink_t *wfd_sink);
 int _mm_wfd_sink_connect(mm_wfd_sink_t *wfd_sink, const char *uri);
+int _mm_wfd_sink_disconnect(mm_wfd_sink_t *wfd_sink);
 int _mm_wfd_sink_start(mm_wfd_sink_t *wfd_sink);
-int _mm_wfd_sink_stop(mm_wfd_sink_t *wfd_sink);
-int _mm_wfd_sink_unrealize(mm_wfd_sink_t *wfd_sink);
-int _mm_wfd_sink_destroy(mm_wfd_sink_t *wfd_sink);
 int _mm_wfd_set_message_callback(mm_wfd_sink_t *wfd_sink, MMWFDMessageCallback callback, void *user_data);
 int _mm_wfd_sink_get_resource(mm_wfd_sink_t* wfd_sink);
 
index a4e1ad7..c021363 100755 (executable)
 
 #include <glib.h>
 #include <gst/gst.h>
-#include <mm_debug.h>
 #include <mm_message.h>
 #include <mm_error.h>
 #include <mm_types.h>
-
+#include "mm_wfd_sink_dlog.h"
 
 #define MMWFDSINK_FREEIF(x) \
-if ( x ) \
-  g_free( (gpointer)x ); \
-x = NULL;
+do\
+{\
+       if ( (x) ) \
+               g_free( (gpointer)(x) ); \
+       (x) = NULL;\
+} while(0);
 
 /* lock for commnad */
 #define MMWFDSINK_CMD_LOCK(x_wfd) \
-if(x_wfd && ((mm_wfd_sink_t*)x_wfd)->cmd_lock) \
-  g_mutex_lock(((mm_wfd_sink_t*)x_wfd)->cmd_lock);
+if(x_wfd) \
+  g_mutex_lock(&(((mm_wfd_sink_t*)x_wfd)->cmd_lock));
 
 #define MMWFDSINK_CMD_UNLOCK(x_wfd) \
-if(x_wfd && ((mm_wfd_sink_t*)x_wfd)->cmd_lock) \
-  g_mutex_unlock(((mm_wfd_sink_t*)x_wfd)->cmd_lock);
+if(x_wfd) \
+  g_mutex_unlock(&(((mm_wfd_sink_t*)x_wfd)->cmd_lock));
 
 /* create element  */
 #define MMWFDSINK_CREATE_ELEMENT(x_bin, x_id, x_factory, x_name, x_add_bucket) \
@@ -56,24 +58,33 @@ do \
                x_bin[x_id].gst = gst_element_factory_make(x_factory, x_name);\
                if ( ! x_bin[x_id].gst )\
                {\
-                       debug_error("failed to create %s \n", x_factory);\
+                       wfd_sink_error("failed to create %s \n", x_factory);\
                        goto CREATE_ERROR;\
                }\
-               debug_log("%s is created \n", x_factory);\
+               wfd_sink_debug("%s is created \n", x_factory);\
                if ( x_add_bucket )\
                        element_bucket = g_list_append(element_bucket, &x_bin[x_id]);\
        }\
 } while(0);
 
 /* generating dot */
-#define MMWFD_GENERATE_DOT_IF_ENABLED( x_wfd_sink, x_name ) \
+#define MMWFDSINK_GENERATE_DOT_IF_ENABLED( x_wfd_sink, x_name ) \
 if ( x_wfd_sink->ini.generate_dot ) \
 { \
-       debug_log ("create dot file : %s.dot", x_name);\
+       wfd_sink_debug ("create dot file : %s.dot", x_name);\
        GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (x_wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst), \
-       GST_DEBUG_GRAPH_SHOW_ALL, x_name); \
+               GST_DEBUG_GRAPH_SHOW_ALL, x_name); \
+}
+
+/* postint message */
+#define MMWFDSINK_POST_MESSAGE( x_wfd_sink, x_error_type, x_state_type ) \
+if (x_wfd_sink->msg_cb) \
+{ \
+       wfd_sink_debug("Message (error : %d, state : %d) will be posted using user callback\n", x_error_type, x_state_type); \
+       x_wfd_sink->msg_cb(x_error_type, x_state_type, x_wfd_sink->msg_user_data); \
 }
 
+
 /* state */
 #define MMWFDSINK_CURRENT_STATE( x_wfd_sink) ((mm_wfd_sink_t *)x_wfd_sink)->state.state
 #define MMWFDSINK_PREVIOUS_STATE( x_wfd_sink) ((mm_wfd_sink_t *)x_wfd_sink)->state.prev_state
@@ -81,7 +92,7 @@ if ( x_wfd_sink->ini.generate_dot ) \
 #define MMWFDSINK_STATE_GET_NAME(x_state) __mm_wfds_sink_get_state_name(x_state)
 
 #define MMWFDSINK_PRINT_STATE(x_wfd_sink) \
-debug_log("-- prev %s, current %s, pending %s --\n", \
+wfd_sink_debug("-- prev %s, current %s, pending %s --\n", \
        MMWFDSINK_STATE_GET_NAME(MMWFDSINK_PREVIOUS_STATE(x_wfd_sink)), \
        MMWFDSINK_STATE_GET_NAME(MMWFDSINK_CURRENT_STATE(x_wfd_sink)), \
        MMWFDSINK_STATE_GET_NAME(MMWFDSINK_PENDING_STATE(x_wfd_sink)));
@@ -103,11 +114,20 @@ switch ( __mm_wfd_sink_check_state((mm_wfd_sink_t *)x_wfd_sink, x_cmd) ) \
 /* pad probe */
 void
 mm_wfd_sink_util_add_pad_probe(GstPad *pad, GstElement *element, const gchar *pad_name);
+void
+mm_wfd_sink_util_add_pad_probe_for_checking_first_buffer(GstPad *pad, GstElement *element, const gchar *pad_name);
 
 #define MMWFDSINK_PAD_PROBE( x_wfd_sink, x_pad, x_element, x_pad_name ) \
-if ( x_wfd_sink && x_wfd_sink->ini.enable_pad_probe ) \
-{ \
-       mm_wfd_sink_util_add_pad_probe (x_pad, x_element, (const gchar*)x_pad_name);\
+if ( x_wfd_sink ) \
+{  \
+       if (x_wfd_sink->ini.enable_pad_probe ) \
+       { \
+               mm_wfd_sink_util_add_pad_probe (x_pad, x_element, (const gchar*)x_pad_name); \
+       } \
+       else \
+       {\
+               mm_wfd_sink_util_add_pad_probe_for_checking_first_buffer (x_pad, x_element, (const gchar*)x_pad_name); \
+       }\
 }
 
 void
@@ -116,8 +136,7 @@ mm_wfd_sink_util_add_pad_probe_for_data_dump(GstElement *element, const gchar *p
 #define MMWFDSINK_TS_DATA_DUMP( x_wfd_sink, x_element, x_pad_name ) \
 if ( x_wfd_sink && x_wfd_sink->ini.enable_ts_data_dump ) \
 { \
-       mm_wfd_sink_util_add_pad_probe_for_data_dump (x_element, (const gchar*)x_pad_name);\
+       mm_wfd_sink_util_add_pad_probe_for_data_dump (x_element, (const gchar*)x_pad_name); \
 }
 
-
 #endif
index 03a5d1d..a01f35e 100755 (executable)
  */
 
 #include <gst/gst.h>
-#include <mm_debug.h>
 
 #include "mm_wfd_sink_util.h"
 #include "mm_wfd_sink.h"
 #include "mm_wfd_sink_priv.h"
-
+#include "mm_wfd_sink_dlog.h"
 
 int mm_wfd_sink_create(MMHandleType *wfd_sink)
 {
        mm_wfd_sink_t *new_wfd_sink = NULL;
        int result = MM_ERROR_NONE;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        result = _mm_wfd_sink_create(&new_wfd_sink);
        if (result != MM_ERROR_NONE)
        {
-               debug_error("fail to create wi-fi display sink handle. ret[%d]", result);
+               wfd_sink_error("fail to create wi-fi display sink handle. ret[%d]", result);
                *wfd_sink = (MMHandleType)NULL;
                return result;
        }
 
-       /* create wfd lock */
-       new_wfd_sink->cmd_lock = g_mutex_new();
-       if (!new_wfd_sink->cmd_lock)
-       {
-               debug_critical("failed to create wifi-display mutex");
-               _mm_wfd_sink_destroy (new_wfd_sink);
-               *wfd_sink = (MMHandleType)NULL;
-               return MM_ERROR_WFD_NO_FREE_SPACE;
-       }
+       /* init wfd lock */
+       g_mutex_init(&new_wfd_sink->cmd_lock);
 
        *wfd_sink = (MMHandleType)new_wfd_sink;
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return result;
 
 }
 
-int mm_wfd_sink_realize(MMHandleType wfd_sink)
+int mm_wfd_sink_prepare(MMHandleType wfd_sink)
 {
        int result = MM_ERROR_NONE;
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        MMWFDSINK_CMD_LOCK(wfd_sink);
-       result = _mm_wfd_sink_realize((mm_wfd_sink_t *)wfd_sink);
+       result = _mm_wfd_sink_prepare((mm_wfd_sink_t *)wfd_sink);
        MMWFDSINK_CMD_UNLOCK(wfd_sink);
 
        return result;
@@ -80,8 +72,8 @@ int mm_wfd_sink_connect(MMHandleType wfd_sink, const char *uri)
 {
        int result = MM_ERROR_NONE;
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-       return_val_if_fail (uri, MM_ERROR_WFD_INVALID_ARGUMENT);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (uri, MM_ERROR_WFD_INVALID_ARGUMENT);
 
        MMWFDSINK_CMD_LOCK(wfd_sink);
        result = _mm_wfd_sink_connect((mm_wfd_sink_t *)wfd_sink, uri);
@@ -94,7 +86,7 @@ int mm_wfd_sink_start(MMHandleType wfd_sink)
 {
        int result = MM_ERROR_NONE;
 
-       return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        MMWFDSINK_CMD_LOCK(wfd_sink);
        result = _mm_wfd_sink_start((mm_wfd_sink_t *)wfd_sink);
@@ -103,27 +95,27 @@ int mm_wfd_sink_start(MMHandleType wfd_sink)
        return result;
 }
 
-int mm_wfd_sink_stop(MMHandleType wfd_sink)
+int mm_wfd_sink_disconnect(MMHandleType wfd_sink)
 {
        int result = MM_ERROR_NONE;
 
-       return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        MMWFDSINK_CMD_LOCK(wfd_sink);
-       result = _mm_wfd_sink_stop((mm_wfd_sink_t *)wfd_sink);
+       result = _mm_wfd_sink_disconnect((mm_wfd_sink_t *)wfd_sink);
        MMWFDSINK_CMD_UNLOCK(wfd_sink);
 
        return result;
 }
 
-int mm_wfd_sink_unrealize(MMHandleType wfd_sink)
+int mm_wfd_sink_unprepare(MMHandleType wfd_sink)
 {
        int result = MM_ERROR_NONE;
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        MMWFDSINK_CMD_LOCK(wfd_sink);
-       result = _mm_wfd_sink_unrealize((mm_wfd_sink_t *)wfd_sink);
+       result = _mm_wfd_sink_unprepare((mm_wfd_sink_t *)wfd_sink);
        MMWFDSINK_CMD_UNLOCK(wfd_sink);
 
        return result;
@@ -133,17 +125,13 @@ int mm_wfd_sink_destroy(MMHandleType wfd_sink)
 {
        int result = MM_ERROR_NONE;
 
-       return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        MMWFDSINK_CMD_LOCK(wfd_sink);
        result = _mm_wfd_sink_destroy((mm_wfd_sink_t *)wfd_sink);
        MMWFDSINK_CMD_UNLOCK(wfd_sink);
 
-       if(((mm_wfd_sink_t *)wfd_sink)->cmd_lock)
-       {
-               g_mutex_free(((mm_wfd_sink_t *)wfd_sink)->cmd_lock);
-               ((mm_wfd_sink_t *)wfd_sink)->cmd_lock = NULL;
-       }
+       g_mutex_clear(&(((mm_wfd_sink_t *)wfd_sink)->cmd_lock));
 
        MMWFDSINK_FREEIF(wfd_sink);
 
@@ -154,7 +142,7 @@ int mm_wfd_sink_set_message_callback(MMHandleType wfd_sink, MMWFDMessageCallback
 {
        int result = MM_ERROR_NONE;
 
-       return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        MMWFDSINK_CMD_LOCK(wfd_sink);
        result = _mm_wfd_set_message_callback((mm_wfd_sink_t *)wfd_sink, callback, user_data);
@@ -168,8 +156,8 @@ int mm_wfd_sink_set_attribute(MMHandleType wfd_sink,  char **err_attr_name, cons
        int result = MM_ERROR_NONE;
        va_list var_args;
 
-       return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-       return_val_if_fail(first_attribute_name, MM_ERROR_WFD_INVALID_ARGUMENT);
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(first_attribute_name, MM_ERROR_WFD_INVALID_ARGUMENT);
 
        MMWFDSINK_CMD_LOCK(wfd_sink);
        va_start (var_args, first_attribute_name);
@@ -184,9 +172,9 @@ int mm_wfd_sink_get_video_resolution(MMHandleType wfd_sink, gint *width, gint *h
 {
        mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
 
-       return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
-       return_val_if_fail(width, MM_ERROR_WFD_INVALID_ARGUMENT);
-       return_val_if_fail(height, MM_ERROR_WFD_INVALID_ARGUMENT);
+       wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(width, MM_ERROR_WFD_INVALID_ARGUMENT);
+       wfd_sink_return_val_if_fail(height, MM_ERROR_WFD_INVALID_ARGUMENT);
 
        *width = wfd->stream_info.video_stream_info.width;
        *height =wfd->stream_info.video_stream_info.height;
@@ -198,8 +186,8 @@ int mm_wfd_sink_get_video_framerate(MMHandleType wfd_sink, gint *frame_rate)
 {
        mm_wfd_sink_t *wfd = (mm_wfd_sink_t *)wfd_sink;
 
-       return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
-       return_val_if_fail(frame_rate, MM_ERROR_WFD_INVALID_ARGUMENT);
+       wfd_sink_return_val_if_fail(wfd, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(frame_rate, MM_ERROR_WFD_INVALID_ARGUMENT);
 
        *frame_rate = wfd->stream_info.video_stream_info.frame_rate;
 
index 974b6a3..719778c 100755 (executable)
@@ -28,76 +28,59 @@ static gpointer __mm_wfd_sink_manager_thread(gpointer data);
 
 int _mm_wfd_sink_init_manager(mm_wfd_sink_t *wfd_sink)
 {
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        /* create capture mutex */
-       wfd_sink->manager_thread_mutex = g_mutex_new();
-       if (wfd_sink->manager_thread_mutex == NULL)
-       {
-               debug_error("failed to create manager thread mutex");
-               goto failed_to_init;
-       }
+       g_mutex_init(&(wfd_sink->manager_thread_mutex));
 
        /* create capture cond */
-       wfd_sink->manager_thread_cond = g_cond_new();
-       if (wfd_sink->manager_thread_cond == NULL)
-       {
-               debug_error("failed to create manger thread cond");
-               goto failed_to_init;
-       }
+       g_cond_init(&(wfd_sink->manager_thread_cond));
 
        wfd_sink->manager_thread_cmd = WFD_SINK_MANAGER_CMD_NONE;
 
        /* create video capture thread */
        wfd_sink->manager_thread =
-               g_thread_create (__mm_wfd_sink_manager_thread, (gpointer)wfd_sink, TRUE, NULL);
+               g_thread_new ("__mm_wfd_sink_manager_thread", __mm_wfd_sink_manager_thread, (gpointer)wfd_sink);
        if (wfd_sink->manager_thread == NULL)
        {
-               debug_error ("failed to create manager thread\n");
+               wfd_sink_error ("failed to create manager thread\n");
                goto failed_to_init;
        }
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 
 failed_to_init:
-       if (wfd_sink->manager_thread_mutex)
-               g_mutex_free (wfd_sink->manager_thread_mutex);
-       wfd_sink->manager_thread_mutex = NULL;
-
-       if (wfd_sink->manager_thread_cond)
-               g_cond_free (wfd_sink->manager_thread_cond);
-       wfd_sink->manager_thread_cond = NULL;
+       g_mutex_clear (&(wfd_sink->manager_thread_mutex));
+       g_cond_clear (&(wfd_sink->manager_thread_cond));
 
        return MM_ERROR_WFD_INTERNAL;
 }
 
 int _mm_wfd_sink_release_manager(mm_wfd_sink_t* wfd_sink)
 {
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        /* release capture thread */
-       if ( wfd_sink->manager_thread_cond &&
-                wfd_sink->manager_thread_mutex &&
-                wfd_sink->manager_thread )
+       if ( wfd_sink->manager_thread )
        {
                WFD_SINK_MANAGER_LOCK(wfd_sink);
                WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_EXIT);
                WFD_SINK_MANAGER_UNLOCK(wfd_sink);
 
-               debug_log("waitting for manager thread exit");
+               wfd_sink_debug("waitting for manager thread exit");
                g_thread_join (wfd_sink->manager_thread);
-               g_mutex_free (wfd_sink->manager_thread_mutex);
-               g_cond_free (wfd_sink->manager_thread_cond);
-               debug_log("manager thread released");
+               g_mutex_clear (&(wfd_sink->manager_thread_mutex));
+               g_cond_clear (&(wfd_sink->manager_thread_cond));
+               wfd_sink_debug("manager thread released");
        }
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 }
@@ -112,25 +95,28 @@ __mm_wfd_sink_manager_thread(gpointer data)
        gboolean set_ready_video_bin = FALSE;
 
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink, NULL);
+       wfd_sink_return_val_if_fail (wfd_sink, NULL);
 
        if (wfd_sink->manager_thread_cmd & WFD_SINK_MANAGER_CMD_EXIT)
-               goto EXIT;
+       {
+               wfd_sink->manager_thread_cmd = WFD_SINK_MANAGER_CMD_EXIT;
+               return NULL;
+       }
 
-       debug_log("manager thread started. waiting for signal");
+       wfd_sink_debug("manager thread started. waiting for signal");
 
        while (TRUE)
        {
                WFD_SINK_MANAGER_LOCK(wfd_sink);
                WFD_SINK_MANAGER_WAIT_CMD(wfd_sink);
 
-               debug_error("No-error:got command %x", wfd_sink->manager_thread_cmd);
+               wfd_sink_debug("got command %x", wfd_sink->manager_thread_cmd);
 
                if (wfd_sink->manager_thread_cmd & WFD_SINK_MANAGER_CMD_EXIT)
                {
-                       debug_log("exiting manager thread");
+                       wfd_sink_debug("exiting manager thread");
                        goto EXIT;
                }
 
@@ -140,14 +126,14 @@ __mm_wfd_sink_manager_thread(gpointer data)
                set_ready_audio_bin = wfd_sink->manager_thread_cmd & WFD_SINK_MANAGER_CMD_PREPARE_A_BIN;
                if (set_ready_audio_bin && !link_auido_bin && !wfd_sink->audio_bin_is_linked)
                {
-                       debug_error("audio bin is not linked... wait for command for linking audiobin");
+                       wfd_sink_error("audio bin is not linked... wait for command for linking audiobin");
                        WFD_SINK_MANAGER_UNLOCK(wfd_sink);
                        continue;
                }
                set_ready_video_bin = wfd_sink->manager_thread_cmd & WFD_SINK_MANAGER_CMD_PREPARE_V_BIN;
                if (set_ready_video_bin && !link_video_bin && !wfd_sink->video_bin_is_linked)
                {
-                       debug_error("video bin is not linked... wait for command for linking videobin.");
+                       wfd_sink_error("video bin is not linked... wait for command for linking videobin.");
                        WFD_SINK_MANAGER_UNLOCK(wfd_sink);
                        continue;
                }
@@ -155,10 +141,10 @@ __mm_wfd_sink_manager_thread(gpointer data)
                /* link audio bin*/
                if (link_auido_bin)
                {
-                       debug_error("No-error : try to link audiobin.");
+                       wfd_sink_debug("try to link audiobin.");
                        if (MM_ERROR_NONE !=__mm_wfd_sink_link_audiobin(wfd_sink))
                        {
-                               debug_error ("failed to link audiobin.....\n");
+                               wfd_sink_error ("failed to link audiobin.....\n");
                                goto EXIT;
                        }
                }
@@ -166,24 +152,25 @@ __mm_wfd_sink_manager_thread(gpointer data)
                /* link video bin*/
                if (link_video_bin)
                {
+                       wfd_sink_debug("try to link videobin.");
                }
 
                if (set_ready_audio_bin)
                {
-                       debug_error("No-error : try to prepare audiobin.");
+                       wfd_sink_debug("try to prepare audiobin.");
                        if (MM_ERROR_NONE !=__mm_wfd_sink_prepare_audiobin(wfd_sink))
                        {
-                               debug_error ("failed to prepare audiobin.....\n");
+                               wfd_sink_error ("failed to prepare audiobin.....\n");
                                goto EXIT;
                        }
                }
 
                if (set_ready_video_bin)
                {
-                       debug_error("No-error : try to prepare videobin.");
+                       wfd_sink_debug("try to prepare videobin.");
                        if (MM_ERROR_NONE !=__mm_wfd_sink_prepare_videobin(wfd_sink))
                        {
-                               debug_error ("failed to prepare videobin.....\n");
+                               wfd_sink_error ("failed to prepare videobin.....\n");
                                goto EXIT;
                        }
                }
@@ -193,7 +180,7 @@ __mm_wfd_sink_manager_thread(gpointer data)
                WFD_SINK_MANAGER_UNLOCK(wfd_sink);
        }
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return NULL;
 
index 5423229..a7e7013 100755 (executable)
 
 #include <gst/gst.h>
 #include <gst/video/videooverlay.h>
-#include <mm_debug.h>
 
 #include "mm_wfd_sink_util.h"
 #include "mm_wfd_sink_priv.h"
 #include "mm_wfd_sink_manager.h"
+#include "mm_wfd_sink_dlog.h"
 
 
 /* gstreamer */
@@ -38,20 +38,20 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink);
 static int __mm_wfd_sink_set_pipeline_state(mm_wfd_sink_t* wfd_sink, GstState state, gboolean async);
 
 /* state */
-static int __mm_wfd_sink_check_state(mm_wfd_sink_t* wfd_sink, MMWfdSinkCommandType cmd);
-static int __mm_wfd_sink_set_state(mm_wfd_sink_t* wfd_sink, MMWfdSinkStateType state);
+static int __mm_wfd_sink_check_state(mm_wfd_sink_t* wfd_sink, MMWFDSinkCommandType cmd);
+static int __mm_wfd_sink_set_state(mm_wfd_sink_t* wfd_sink, MMWFDSinkStateType state);
 
 /* util */
 static void __mm_wfd_sink_dump_pipeline_state(mm_wfd_sink_t *wfd_sink);
-const gchar * __mm_wfds_sink_get_state_name ( MMWfdSinkStateType state );
+const gchar * __mm_wfds_sink_get_state_name ( MMWFDSinkStateType state );
 
 int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink)
 {
        int result = MM_ERROR_NONE;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        mm_wfd_sink_t *new_wfd_sink = NULL;
 
@@ -59,7 +59,7 @@ int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink)
        new_wfd_sink = g_malloc0(sizeof(mm_wfd_sink_t));
        if (!new_wfd_sink)
        {
-               debug_error("failed to allocate memory for wi-fi display sink\n");
+               wfd_sink_error("failed to allocate memory for wi-fi display sink\n");
                return MM_ERROR_WFD_NO_FREE_SPACE;
        }
 
@@ -67,17 +67,23 @@ int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink)
        new_wfd_sink->attrs = 0;
 
        new_wfd_sink->pipeline = NULL;
-       new_wfd_sink->is_constructed = FALSE;
        new_wfd_sink->added_av_pad_num = 0;
        new_wfd_sink->audio_bin_is_linked = FALSE;
        new_wfd_sink->video_bin_is_linked = FALSE;
-       new_wfd_sink->audio_bin_is_prepared = FALSE;
-       new_wfd_sink->video_bin_is_prepared = FALSE;
        new_wfd_sink->prev_audio_dec_src_pad = NULL;
        new_wfd_sink->next_audio_dec_sink_pad = NULL;
+
+       /* Initialize timestamp compensation related */
        new_wfd_sink->need_to_reset_basetime = FALSE;
-       new_wfd_sink->demux_video_pad_probe_id = 0;
-       new_wfd_sink->demux_audio_pad_probe_id = 0;
+       new_wfd_sink->clock = NULL;
+       new_wfd_sink->video_buffer_count = 0LL;
+       new_wfd_sink->video_average_gap = 0LL;
+       new_wfd_sink->video_accumulated_gap = 0LL;
+       new_wfd_sink->audio_buffer_count = 0LL;
+       new_wfd_sink->audio_average_gap = 0LL;
+       new_wfd_sink->audio_accumulated_gap = 0LL;
+       new_wfd_sink->last_buffer_timestamp = GST_CLOCK_TIME_NONE;
+
        /* Initialize all states */
        MMWFDSINK_CURRENT_STATE (new_wfd_sink) = MM_WFD_SINK_STATE_NONE;
        MMWFDSINK_PREVIOUS_STATE (new_wfd_sink) =  MM_WFD_SINK_STATE_NONE;
@@ -95,15 +101,13 @@ int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink)
 
        /* Initialize command */
        new_wfd_sink->cmd = MM_WFD_SINK_COMMAND_CREATE;
-       new_wfd_sink->cmd_lock = NULL;
+       new_wfd_sink->waiting_cmd = FALSE;
 
        /* Initialize resource related */
        new_wfd_sink->resource_list = NULL;
 
        /* Initialize manager related */
        new_wfd_sink->manager_thread = NULL;
-       new_wfd_sink->manager_thread_mutex = NULL;
-       new_wfd_sink->manager_thread_cond = NULL;
        new_wfd_sink->manager_thread_cmd = WFD_SINK_MANAGER_CMD_NONE;
 
        /* construct attributes */
@@ -111,7 +115,7 @@ int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink)
        if (!new_wfd_sink->attrs)
        {
                MMWFDSINK_FREEIF (new_wfd_sink);
-               debug_error("failed to set attribute\n");
+               wfd_sink_error("failed to set attribute\n");
                return MM_ERROR_WFD_INTERNAL;
        }
 
@@ -119,7 +123,7 @@ int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink)
        result = mm_wfd_sink_ini_load(&new_wfd_sink->ini);
        if (result != MM_ERROR_NONE)
        {
-               debug_error("failed to load ini file\n");
+               wfd_sink_error("failed to load ini file\n");
                goto fail_to_load_ini;
        }
        new_wfd_sink->need_to_reset_basetime = new_wfd_sink->ini.enable_reset_basetime;
@@ -128,7 +132,7 @@ int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink)
        result = _mm_wfd_sink_init_manager(new_wfd_sink);
        if (result < MM_ERROR_NONE)
        {
-               debug_error("failed to init manager : %d\n", result);
+               wfd_sink_error("failed to init manager : %d\n", result);
                goto fail_to_init;
        }
 
@@ -136,7 +140,7 @@ int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink)
        result = __mm_wfd_sink_init_gstreamer(new_wfd_sink);
        if (result < MM_ERROR_NONE)
        {
-               debug_error("failed to init gstreamer : %d\n", result);
+               wfd_sink_error("failed to init gstreamer : %d\n", result);
                goto fail_to_init;
        }
 
@@ -146,7 +150,7 @@ int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink)
        /* now take handle */
        *wfd_sink = new_wfd_sink;
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return result;
 
@@ -162,23 +166,23 @@ fail_to_load_ini:
        return result;
 }
 
-int _mm_wfd_sink_realize (mm_wfd_sink_t *wfd_sink)
+int _mm_wfd_sink_prepare (mm_wfd_sink_t *wfd_sink)
 {
        int result = MM_ERROR_NONE;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        /* check current wi-fi display sink state */
-       MMWFDSINK_CHECK_STATE (wfd_sink, MM_WFD_SINK_COMMAND_REALIZE);
+       MMWFDSINK_CHECK_STATE (wfd_sink, MM_WFD_SINK_COMMAND_PREPARE);
 
        /* construct pipeline */
        /* create main pipeline */
        result = __mm_wfd_sink_create_pipeline(wfd_sink);
        if (result < MM_ERROR_NONE)
        {
-               debug_error("failed to create pipeline : %d\n", result);
+               wfd_sink_error("failed to create pipeline : %d\n", result);
                goto fail_to_create;
        }
 
@@ -186,7 +190,7 @@ int _mm_wfd_sink_realize (mm_wfd_sink_t *wfd_sink)
        result = __mm_wfd_sink_create_videobin(wfd_sink);
        if (result < MM_ERROR_NONE)
        {
-               debug_error("failed to create videobin : %d\n", result);
+               wfd_sink_error("failed to create videobin : %d\n", result);
                goto fail_to_create;
        }
 
@@ -194,7 +198,7 @@ int _mm_wfd_sink_realize (mm_wfd_sink_t *wfd_sink)
        result = __mm_wfd_sink_create_audiobin(wfd_sink);
        if (result < MM_ERROR_NONE)
        {
-               debug_error("fail to create audiobin : %d\n", result);
+               wfd_sink_error("fail to create audiobin : %d\n", result);
                goto fail_to_create;
        }
 
@@ -202,14 +206,14 @@ int _mm_wfd_sink_realize (mm_wfd_sink_t *wfd_sink)
        result = __mm_wfd_sink_set_pipeline_state(wfd_sink, GST_STATE_READY, TRUE);
        if (result < MM_ERROR_NONE)
        {
-               debug_error("failed to set state : %d\n", result);
+               wfd_sink_error("failed to set state : %d\n", result);
                goto fail_to_create;
        }
 
        /* set state */
-       __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_READY);
+       __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_PREPARED);
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return result;
 
@@ -224,11 +228,11 @@ int _mm_wfd_sink_connect (mm_wfd_sink_t *wfd_sink, const char *uri)
 {
        int result = MM_ERROR_NONE;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail(uri && strlen(uri) > strlen("rtsp://"),
+       wfd_sink_return_val_if_fail(uri && strlen(uri) > strlen("rtsp://"),
                MM_ERROR_WFD_INVALID_ARGUMENT);
-       return_val_if_fail (wfd_sink &&
+       wfd_sink_return_val_if_fail (wfd_sink &&
                wfd_sink->pipeline &&
                wfd_sink->pipeline->mainbin &&
                wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst &&
@@ -240,7 +244,7 @@ int _mm_wfd_sink_connect (mm_wfd_sink_t *wfd_sink, const char *uri)
        /* check current wi-fi display sink state */
        MMWFDSINK_CHECK_STATE (wfd_sink, MM_WFD_SINK_COMMAND_CONNECT);
 
-       debug_error ("No-error: try to connect to %s.....\n", GST_STR_NULL(uri));
+       wfd_sink_debug ("try to connect to %s.....\n", GST_STR_NULL(uri));
 
        /* set uri to wfdrtspsrc */
        g_object_set (G_OBJECT(wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst), "location", uri, NULL);
@@ -249,11 +253,11 @@ int _mm_wfd_sink_connect (mm_wfd_sink_t *wfd_sink, const char *uri)
        result = __mm_wfd_sink_set_pipeline_state(wfd_sink, GST_STATE_PAUSED, TRUE);
        if (result < MM_ERROR_NONE)
        {
-               debug_error("failed to set state : %d\n", result);
+               wfd_sink_error("failed to set state : %d\n", result);
                return result;
        }
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return result;
 }
@@ -262,78 +266,90 @@ int _mm_wfd_sink_start(mm_wfd_sink_t *wfd_sink)
 {
        int result = MM_ERROR_NONE;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        /* check current wi-fi display sink state */
-       /* MMWFDSINK_CHECK_STATE (wfd_sink, MM_WFD_SINK_COMMAND_START); */
+       MMWFDSINK_CHECK_STATE (wfd_sink, MM_WFD_SINK_COMMAND_START);
 
        WFD_SINK_MANAGER_LOCK(wfd_sink) ;
-       debug_error("No-error:need to check ready to play");
+       wfd_sink_debug("check pipeline is ready to start");
        WFD_SINK_MANAGER_UNLOCK(wfd_sink);
 
        result = __mm_wfd_sink_set_pipeline_state(wfd_sink, GST_STATE_PLAYING, TRUE);
        if (result < MM_ERROR_NONE)
        {
-               debug_error("failed to set state : %d\n", result);
+               wfd_sink_error("failed to set state : %d\n", result);
                return result;
        }
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return result;
 }
 
-int _mm_wfd_sink_stop(mm_wfd_sink_t *wfd_sink)
+int _mm_wfd_sink_disconnect(mm_wfd_sink_t *wfd_sink)
 {
        int result = MM_ERROR_NONE;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        /* check current wi-fi display sink state */
-       MMWFDSINK_CHECK_STATE (wfd_sink, MM_WFD_SINK_COMMAND_STOP);
+       MMWFDSINK_CHECK_STATE (wfd_sink, MM_WFD_SINK_COMMAND_DISCONNECT);
+
+       WFD_SINK_MANAGER_LOCK(wfd_sink) ;
+       WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_EXIT);
+       WFD_SINK_MANAGER_UNLOCK(wfd_sink);
 
        result = __mm_wfd_sink_set_pipeline_state (wfd_sink, GST_STATE_READY, FALSE);
        if (result < MM_ERROR_NONE)
        {
-               debug_error("fail to set state : %d\n", result);
+               wfd_sink_error("fail to set state : %d\n", result);
                return result;
        }
 
        /* set state */
-       __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_READY);
+       __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_DISCONNECTED);
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return result;
 }
 
-int _mm_wfd_sink_unrealize(mm_wfd_sink_t *wfd_sink)
+int _mm_wfd_sink_unprepare(mm_wfd_sink_t *wfd_sink)
 {
        int result = MM_ERROR_NONE;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        /* check current wi-fi display sink state */
-       MMWFDSINK_CHECK_STATE (wfd_sink, MM_WFD_SINK_COMMAND_UNREALIZE);
+       MMWFDSINK_CHECK_STATE (wfd_sink, MM_WFD_SINK_COMMAND_UNPREPARE);
+
+       WFD_SINK_MANAGER_LOCK(wfd_sink) ;
+       WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_EXIT);
+       WFD_SINK_MANAGER_UNLOCK(wfd_sink);
 
        /* release pipeline */
        result =  __mm_wfd_sink_destroy_pipeline (wfd_sink);
        if ( result != MM_ERROR_NONE)
        {
-               debug_error("failed to destory pipeline\n");
+               wfd_sink_error("failed to destory pipeline\n");
                return MM_ERROR_WFD_INTERNAL;
        }
+       else
+       {
+               wfd_sink_debug("success to destory pipeline\n");
+       }
 
        /* set state */
        __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_NULL);
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return result;
 }
@@ -342,9 +358,9 @@ int _mm_wfd_sink_destroy(mm_wfd_sink_t *wfd_sink)
 {
        int result = MM_ERROR_NONE;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        /* check current wi-fi display sink state */
        MMWFDSINK_CHECK_STATE (wfd_sink, MM_WFD_SINK_COMMAND_DESTROY);
@@ -357,7 +373,7 @@ int _mm_wfd_sink_destroy(mm_wfd_sink_t *wfd_sink)
 
        if (MM_ERROR_NONE != _mm_wfd_sink_release_manager(wfd_sink))
        {
-               debug_error("failed to release manager\n");
+               wfd_sink_error("failed to release manager\n");
                return MM_ERROR_WFD_INTERNAL;
        }
 
@@ -365,7 +381,7 @@ int _mm_wfd_sink_destroy(mm_wfd_sink_t *wfd_sink)
        /* set state */
        __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_NONE);
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return result;
 }
@@ -374,27 +390,18 @@ int _mm_wfd_set_message_callback(mm_wfd_sink_t *wfd_sink, MMWFDMessageCallback c
 {
        int result = MM_ERROR_NONE;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        wfd_sink->msg_cb = callback;
        wfd_sink->msg_user_data = user_data;
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return result;
 }
 
-void __mm_wfd_post_message(mm_wfd_sink_t* wfd_sink, MMWfdSinkStateType msgtype)
-{
-       if (wfd_sink->msg_cb)
-       {
-               debug_error("No-error: Message (type : %d) will be posted using user callback\n", msgtype);
-               wfd_sink->msg_cb(msgtype, wfd_sink->msg_user_data);
-       }
-}
-
 static int __mm_wfd_sink_init_gstreamer(mm_wfd_sink_t *wfd_sink)
 {
        int result = MM_ERROR_NONE;
@@ -404,14 +411,14 @@ static int __mm_wfd_sink_init_gstreamer(mm_wfd_sink_t *wfd_sink)
        GError *err = NULL;
        gint i = 0;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
        /* alloc */
        argc = calloc(1, sizeof(gint) );
        argv = calloc(max_argc, sizeof(gchar*));
        if (!argc || !argv)
        {
-               debug_error("Cannot allocate memory for wfdsink\n");
+               wfd_sink_error("failed to allocate memory for wfdsink\n");
 
                MMWFDSINK_FREEIF(argv);
                MMWFDSINK_FREEIF(argc);
@@ -436,24 +443,25 @@ static int __mm_wfd_sink_init_gstreamer(mm_wfd_sink_t *wfd_sink)
        {
                if (strlen( wfd_sink->ini.gst_param[i] ) > 2)
                {
-                       debug_log("set %s\n", wfd_sink->ini.gst_param[i]);
+                       wfd_sink_debug("set %s\n", wfd_sink->ini.gst_param[i]);
                        argv[*argc] = g_strdup(wfd_sink->ini.gst_param[i]);
                        (*argc)++;
                }
        }
 
-       debug_log("initializing gstreamer with following parameter\n");
-       debug_log("argc : %d\n", *argc);
+       wfd_sink_debug("initializing gstreamer with following parameter\n");
+       wfd_sink_debug("argc : %d\n", *argc);
 
        for ( i = 0; i < *argc; i++ )
        {
-               debug_log("argv[%d] : %s\n", i, argv[i]);
+               wfd_sink_debug("argv[%d] : %s\n", i, argv[i]);
        }
 
        /* initializing gstreamer */
        if ( ! gst_init_check (argc, &argv, &err))
        {
-               debug_error("Could not initialize GStreamer: %s\n", err ? err->message : "unknown error occurred");
+               wfd_sink_error("failed to initialize gstreamer: %s\n",
+                       err ? err->message : "unknown error occurred");
                if (err)
                        g_error_free (err);
 
@@ -468,7 +476,7 @@ static int __mm_wfd_sink_init_gstreamer(mm_wfd_sink_t *wfd_sink)
        MMWFDSINK_FREEIF(argv);
        MMWFDSINK_FREEIF(argc);
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return result;
 }
@@ -492,9 +500,13 @@ _mm_wfd_sink_correct_pipeline_latency (mm_wfd_sink_t *wfd_sink)
 static GstBusSyncReply
 _mm_wfd_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data)
 {
-       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *)data;
        GstBusSyncReply ret = GST_BUS_PASS;
 
+       wfd_sink_return_val_if_fail (message &&
+               GST_IS_MESSAGE(message) &&
+               GST_MESSAGE_SRC(message),
+               GST_BUS_DROP);
+
        switch (GST_MESSAGE_TYPE (message))
        {
                case GST_MESSAGE_TAG:
@@ -503,14 +515,14 @@ _mm_wfd_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data)
                break;
                case GST_MESSAGE_STATE_CHANGED:
                {
-                       /* we only handle messages from pipeline */
-                       if (message->src != GST_OBJECT_CAST(wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst))
+                       /* we only handle state change messages from pipeline */
+                       if (!GST_IS_PIPELINE(GST_MESSAGE_SRC(message)))
                                ret = GST_BUS_DROP;
                }
                break;
                case GST_MESSAGE_ASYNC_DONE:
                {
-                       if( message->src != GST_OBJECT_CAST(wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst) )
+                       if (!GST_IS_PIPELINE(GST_MESSAGE_SRC(message)))
                                ret = GST_BUS_DROP;
                }
                break;
@@ -525,13 +537,15 @@ static gboolean
 _mm_wfd_sink_msg_callback (GstBus *bus, GstMessage *msg, gpointer data)
 {
        mm_wfd_sink_t* wfd_sink = (mm_wfd_sink_t*) data;
-       gboolean ret = TRUE;
-       gchar** splited_message;
-       const gchar* message_structure_name;
        const GstStructure* message_structure = gst_message_get_structure(msg);
+       gboolean ret = TRUE;
+
+       wfd_sink_return_val_if_fail (wfd_sink, FALSE);
+       wfd_sink_return_val_if_fail (msg && GST_IS_MESSAGE(msg), FALSE);
 
-       return_val_if_fail (wfd_sink, FALSE);
-       return_val_if_fail (msg && GST_IS_MESSAGE(msg), FALSE);
+       wfd_sink_debug("got %s from %s \n",
+               GST_STR_NULL(GST_MESSAGE_TYPE_NAME(msg)),
+               GST_STR_NULL(GST_OBJECT_NAME(GST_MESSAGE_SRC(msg))));
 
        switch (GST_MESSAGE_TYPE (msg))
        {
@@ -543,8 +557,8 @@ _mm_wfd_sink_msg_callback (GstBus *bus, GstMessage *msg, gpointer data)
                        /* get error code */
                        gst_message_parse_error( msg, &error, &debug );
 
-                       debug_error("error : %s\n", error->message);
-                       debug_error("debug : %s\n", debug);
+                       wfd_sink_error("error : %s\n", error->message);
+                       wfd_sink_error("debug : %s\n", debug);
 
                        MMWFDSINK_FREEIF( debug );
                        g_error_free( error );
@@ -558,8 +572,8 @@ _mm_wfd_sink_msg_callback (GstBus *bus, GstMessage *msg, gpointer data)
 
                        gst_message_parse_warning(msg, &error, &debug);
 
-                       debug_error("warning : %s\n", error->message);
-                       debug_error("debug : %s\n", debug);
+                       wfd_sink_error("warning : %s\n", error->message);
+                       wfd_sink_error("debug : %s\n", debug);
 
                        MMWFDSINK_FREEIF (debug);
                        g_error_free (error);
@@ -586,15 +600,15 @@ _mm_wfd_sink_msg_callback (GstBus *bus, GstMessage *msg, gpointer data)
                        newstate = (GstState)vnewstate->data[0].v_int;
                        pending = (GstState)vpending->data[0].v_int;
 
-                       debug_error("No-error: 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 ) );
+                       wfd_sink_debug("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_error("pipeline reports state transition to old state\n");
+                               wfd_sink_error("pipeline reports state transition to old state\n");
                                break;
                        }
 
@@ -604,17 +618,7 @@ _mm_wfd_sink_msg_callback (GstBus *bus, GstMessage *msg, gpointer data)
                                case GST_STATE_NULL:
                                case GST_STATE_READY:
                                case GST_STATE_PAUSED:
-                               break;
-
                                case GST_STATE_PLAYING:
-                                       if (wfd_sink->is_constructed) {
-                                               __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_PLAYING);
-                                               _mm_wfd_sink_correct_pipeline_latency (wfd_sink);
-                                       }
-                                       else
-                                               debug_error ("No-error: pipleline is not constructed yet, intermediate state changing\n");
-                               break;
-
                                default:
                                break;
                        }
@@ -625,7 +629,8 @@ _mm_wfd_sink_msg_callback (GstBus *bus, GstMessage *msg, gpointer data)
                {
                        GstClock *clock = NULL;
                        gst_message_parse_clock_lost (msg, &clock);
-                       debug_error("No-error: GST_MESSAGE_CLOCK_LOST : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
+                       wfd_sink_debug("The current clock[%s] as selected by the pipeline became unusable.",
+                               (clock ? GST_OBJECT_NAME (clock) : "NULL"));
                }
                break;
 
@@ -633,35 +638,59 @@ _mm_wfd_sink_msg_callback (GstBus *bus, GstMessage *msg, gpointer data)
                {
                        GstClock *clock = NULL;
                        gst_message_parse_new_clock (msg, &clock);
-                       debug_error("No-error: GST_MESSAGE_NEW_CLOCK : %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
+                       if (!clock)
+                               break;
+
+                       if (wfd_sink->clock)
+                       {
+                               if (wfd_sink->clock != clock)
+                                       wfd_sink_debug("clock is changed! [%s] --> [%s]\n",
+                                               GST_STR_NULL(GST_OBJECT_NAME (wfd_sink->clock)),
+                                               GST_STR_NULL(GST_OBJECT_NAME (clock)));
+                               else
+                                       wfd_sink_debug("same clock is selected again! [%s] \n",
+                                               GST_STR_NULL(GST_OBJECT_NAME (clock)));
+                       }
+                       else
+                       {
+                               wfd_sink_debug("new clock [%s] was selected in the pipeline\n",
+                                       (GST_STR_NULL(GST_OBJECT_NAME (clock))));
+                       }
+
+                       wfd_sink->clock = clock;
                }
                break;
 
                case GST_MESSAGE_APPLICATION:
                {
+                       const gchar* message_structure_name;
+
                        message_structure_name = gst_structure_get_name(message_structure);
-                       debug_error ("No-error: message name : %s", message_structure_name);
-                       splited_message = g_strsplit((gchar*)message_structure_name, "_", 2);
-                       if(g_strrstr(message_structure_name, "TEARDOWN"))
-                       {
-                               debug_error ("Got TEARDOWN.. Closing..\n");
-                               //_mm_wfd_sink_stop (wfd_sink);
-                               __mm_wfd_post_message(wfd_sink, MM_WFD_SINK_STATE_TEARDOWN);
-                       }
-                       g_strfreev(splited_message);
+                       if (!message_structure_name)
+                               break;
+
+                       wfd_sink_debug ("message name : %s", GST_STR_NULL(message_structure_name));
                }
                break;
 
                case GST_MESSAGE_ELEMENT:
                {
                        const gchar *structure_name = NULL;
-                       const GstStructure *structure;
-                       structure = gst_message_get_structure(msg);
-                       if (structure == NULL)
-                               break;
-                       structure_name = gst_structure_get_name(structure);
+                       const GstStructure* message_structure = NULL;
+
+                       message_structure = gst_message_get_structure(msg);
+                       structure_name = gst_structure_get_name(message_structure);
                        if (structure_name)
-                               debug_error("No-error: GST_MESSAGE_ELEMENT : %s\n", structure_name);
+                       {
+                               wfd_sink_debug("got element specific message[%s]\n", GST_STR_NULL(structure_name));
+                               if(g_strrstr(structure_name, "GstUDPSrcTimeout"))
+                               {
+                                       wfd_sink_error("Got %s, post error message\n", GST_STR_NULL(structure_name));
+                                       MMWFDSINK_POST_MESSAGE(wfd_sink,
+                                               MM_ERROR_WFD_INTERNAL,
+                                               MMWFDSINK_CURRENT_STATE(wfd_sink));
+                               }
+                       }
                }
                break;
 
@@ -670,9 +699,8 @@ _mm_wfd_sink_msg_callback (GstBus *bus, GstMessage *msg, gpointer data)
                        GstProgressType type = GST_PROGRESS_TYPE_ERROR;
                        gchar *category=NULL, *text=NULL;
 
-                       debug_error("No-error: GST_MESSAGE_PROGRESS\n");
-
                        gst_message_parse_progress (msg, &type, &category, &text);
+                       wfd_sink_debug("%s : %s \n", GST_STR_NULL(category), GST_STR_NULL(text));
 
                        switch (type)
                        {
@@ -680,101 +708,101 @@ _mm_wfd_sink_msg_callback (GstBus *bus, GstMessage *msg, gpointer data)
                                        break;
                                case GST_PROGRESS_TYPE_COMPLETE:
                                        if (category && !strcmp (category, "open"))
+                                               __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_CONNECTED);
+                                       else if (category && !strcmp (category, "play"))
                                        {
-                                               debug_error("No-error: %s\n", GST_STR_NULL(text));
-                                               __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_PAUSED);
+                                               __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_PLAYING);
+                                               //_mm_wfd_sink_correct_pipeline_latency (wfd_sink);
                                        }
+                                       else if (category && !strcmp (category, "pause"))
+                                               __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_PAUSED);
+                                       else if (category && !strcmp (category, "close"))
+                                               __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_DISCONNECTED);
+
+
                                        break;
                                case GST_PROGRESS_TYPE_CANCELED:
                                        break;
                                case GST_PROGRESS_TYPE_ERROR:
                                        if (category && !strcmp (category, "open"))
                                        {
-                                               debug_error("got error : %s\n", GST_STR_NULL(text));
-                                               //_mm_wfd_sink_stop (wfd_sink);
-                                               __mm_wfd_post_message(wfd_sink, MM_WFD_SINK_STATE_TEARDOWN);
+                                               wfd_sink_error("got error : %s\n", GST_STR_NULL(text));
+                                               //_mm_wfd_sink_disconnect (wfd_sink);
+                                               MMWFDSINK_POST_MESSAGE(wfd_sink,
+                                                       MM_ERROR_WFD_INTERNAL,
+                                                       MMWFDSINK_CURRENT_STATE(wfd_sink));
                                        }
                                        else if (category && !strcmp (category, "play"))
                                        {
-                                               debug_error("got error : %s\n", GST_STR_NULL(text));
-                                               //_mm_wfd_sink_stop (wfd_sink);
-                                               __mm_wfd_post_message(wfd_sink, MM_WFD_SINK_STATE_TEARDOWN);
+                                               wfd_sink_error("got error : %s\n", GST_STR_NULL(text));
+                                               //_mm_wfd_sink_disconnect (wfd_sink);
+                                               MMWFDSINK_POST_MESSAGE(wfd_sink,
+                                                       MM_ERROR_WFD_INTERNAL,
+                                                       MMWFDSINK_CURRENT_STATE(wfd_sink));
+                                       }
+                                       else if (category && !strcmp (category, "pause"))
+                                       {
+                                               wfd_sink_error("got error : %s\n", GST_STR_NULL(text));
+                                               //_mm_wfd_sink_disconnect (wfd_sink);
+                                               MMWFDSINK_POST_MESSAGE(wfd_sink,
+                                                       MM_ERROR_WFD_INTERNAL,
+                                                       MMWFDSINK_CURRENT_STATE(wfd_sink));
+                                       }
+                                       else if (category && !strcmp (category, "close"))
+                                       {
+                                               wfd_sink_error("got error : %s\n", GST_STR_NULL(text));
+                                               //_mm_wfd_sink_disconnect (wfd_sink);
+                                               MMWFDSINK_POST_MESSAGE(wfd_sink,
+                                                       MM_ERROR_WFD_INTERNAL,
+                                                       MMWFDSINK_CURRENT_STATE(wfd_sink));
                                        }
                                        else
                                        {
-                                               debug_error("got error : %s\n", GST_STR_NULL(text));
+                                               wfd_sink_error("got error : %s\n", GST_STR_NULL(text));
                                        }
                                        break;
                                default :
-                                       debug_error("progress message has no type\n");
+                                       wfd_sink_error("progress message has no type\n");
                                        return ret;
                        }
 
-                       debug_error("No-error: %s : %s \n", GST_STR_NULL(category), GST_STR_NULL(text));
                        MMWFDSINK_FREEIF (category);
                        MMWFDSINK_FREEIF (text);
                }
                break;
-
-               case GST_MESSAGE_UNKNOWN:       debug_log("GST_MESSAGE_UNKNOWN\n"); break;
-               case GST_MESSAGE_INFO:  debug_log("GST_MESSAGE_STATE_DIRTY\n"); break;
-               case GST_MESSAGE_TAG: /*debug_log("GST_MESSAGE_TAG\n");*/  break;
-               case GST_MESSAGE_BUFFERING: debug_log("GST_MESSAGE_BUFFERING\n");break;
-               case GST_MESSAGE_EOS:   debug_log("GST_MESSAGE_EOS received\n");                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_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_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");break;
-               case GST_MESSAGE_LATENCY:       debug_log("GST_MESSAGE_LATENCY\n"); break;
-               case GST_MESSAGE_ASYNC_START:   debug_log("GST_MESSAGE_ASYNC_START : %s\n", gst_element_get_name(GST_MESSAGE_SRC(msg))); break;
-               case GST_MESSAGE_ASYNC_DONE:  debug_log("GST_MESSAGE_ASYNC_DONE");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_ANY:                           debug_log("GST_MESSAGE_ANY\n"); break;
+               case GST_MESSAGE_ASYNC_START:
+                       wfd_sink_debug("GST_MESSAGE_ASYNC_START : %s\n", gst_element_get_name(GST_MESSAGE_SRC(msg)));
+                       break;
+               case GST_MESSAGE_ASYNC_DONE:
+                       wfd_sink_debug("GST_MESSAGE_ASYNC_DONE : %s\n", gst_element_get_name(GST_MESSAGE_SRC(msg)));
+                       break;
+               case GST_MESSAGE_UNKNOWN:
+               case GST_MESSAGE_INFO:
+               case GST_MESSAGE_TAG:
+               case GST_MESSAGE_BUFFERING:
+               case GST_MESSAGE_EOS:
+               case GST_MESSAGE_STATE_DIRTY:
+               case GST_MESSAGE_STEP_DONE:
+               case GST_MESSAGE_CLOCK_PROVIDE:
+               case GST_MESSAGE_STRUCTURE_CHANGE:
+               case GST_MESSAGE_STREAM_STATUS:
+               case GST_MESSAGE_SEGMENT_START:
+               case GST_MESSAGE_SEGMENT_DONE:
+               case GST_MESSAGE_DURATION:
+               case GST_MESSAGE_LATENCY:
+               case GST_MESSAGE_REQUEST_STATE:
+               case GST_MESSAGE_STEP_START:
+               case GST_MESSAGE_QOS:
+               case GST_MESSAGE_ANY:
+                       break;
                default:
-                       debug_log("unhandled message\n");
+                       wfd_sink_debug("unhandled message\n");
                break;
        }
 
        return ret;
 }
 
-
-static gboolean
-__mm_wfd_sink_gst_sync_state_bucket (GList* element_bucket)
-{
-       GList* bucket = element_bucket;
-       MMWFDSinkGstElement* element = NULL;
-
-       debug_fenter();
-
-       return_val_if_fail (element_bucket, FALSE);
-
-       for (; bucket; bucket = bucket->next)
-       {
-               element = (MMWFDSinkGstElement*)bucket->data;
-
-               if (element && element->gst)
-               {
-                       if (!gst_element_sync_state_with_parent (GST_ELEMENT(element->gst)))
-                       {
-                               debug_error ("fail to sync %s state with parent\n", GST_ELEMENT_NAME(element->gst));
-                               return FALSE;
-                       }
-               }
-       }
-
-       debug_fleave();
-
-       return TRUE;
-}
-
-
 static int
 __mm_wfd_sink_gst_element_add_bucket_to_bin (GstBin* bin, GList* element_bucket, gboolean need_prepare)
 {
@@ -782,10 +810,10 @@ __mm_wfd_sink_gst_element_add_bucket_to_bin (GstBin* bin, GList* element_bucket,
        MMWFDSinkGstElement* element = NULL;
        int successful_add_count = 0;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (element_bucket, 0);
-       return_val_if_fail (bin, 0);
+       wfd_sink_return_val_if_fail (element_bucket, 0);
+       wfd_sink_return_val_if_fail (bin, 0);
 
        for (; bucket; bucket = bucket->next)
        {
@@ -798,16 +826,21 @@ __mm_wfd_sink_gst_element_add_bucket_to_bin (GstBin* bin, GList* element_bucket,
 
                        if (!gst_bin_add (bin, GST_ELEMENT(element->gst)))
                        {
-                               debug_error("No-error: Adding element [%s]to bin [%s] failed\n",
-                                       GST_ELEMENT_NAME(GST_ELEMENT(element->gst)),
-                                       GST_ELEMENT_NAME(GST_ELEMENT(bin) ) );
+                               wfd_sink_error("failed to add element [%s] to bin [%s]\n",
+                                       GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT(element->gst))),
+                                       GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT_CAST(bin) )));
                                return 0;
                        }
+
+                       wfd_sink_debug("add element [%s] to bin [%s]\n",
+                               GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT(element->gst))),
+                               GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT_CAST(bin) )));
+
                        successful_add_count ++;
                }
        }
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return successful_add_count;
 }
@@ -820,9 +853,9 @@ __mm_wfd_sink_gst_element_link_bucket (GList* element_bucket)
        MMWFDSinkGstElement* prv_element = NULL;
        gint successful_link_count = 0;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (element_bucket, -1);
+       wfd_sink_return_val_if_fail (element_bucket, -1);
 
        prv_element = (MMWFDSinkGstElement*)bucket->data;
        bucket = bucket->next;
@@ -835,16 +868,16 @@ __mm_wfd_sink_gst_element_link_bucket (GList* element_bucket)
                {
                        if ( gst_element_link (GST_ELEMENT(prv_element->gst), GST_ELEMENT(element->gst)) )
                        {
-                               debug_error("No-error: linking [%s] to [%s] success\n",
-                                       GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
-                                       GST_ELEMENT_NAME(GST_ELEMENT(element->gst)) );
+                               wfd_sink_debug("linking [%s] to [%s] success\n",
+                                       GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst))),
+                                       GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT(element->gst))));
                                successful_link_count ++;
                        }
                        else
                        {
-                               debug_error("linking [%s] to [%s] failed\n",
-                                       GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst)),
-                                       GST_ELEMENT_NAME(GST_ELEMENT(element->gst)) );
+                               wfd_sink_error("linking [%s] to [%s] failed\n",
+                                       GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT(prv_element->gst))),
+                                       GST_STR_NULL(GST_ELEMENT_NAME(GST_ELEMENT(element->gst))));
                                return -1;
                        }
                }
@@ -852,19 +885,19 @@ __mm_wfd_sink_gst_element_link_bucket (GList* element_bucket)
                prv_element = element;
        }
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return successful_link_count;
 }
 
 static int
-__mm_wfd_sink_check_state(mm_wfd_sink_t* wfd_sink, MMWfdSinkCommandType cmd)
+__mm_wfd_sink_check_state(mm_wfd_sink_t* wfd_sink, MMWFDSinkCommandType cmd)
 {
-       MMWfdSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
+       MMWFDSinkStateType cur_state = MM_WFD_SINK_STATE_NONE;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        MMWFDSINK_PRINT_STATE(wfd_sink);
 
@@ -881,25 +914,25 @@ __mm_wfd_sink_check_state(mm_wfd_sink_t* wfd_sink, MMWfdSinkCommandType cmd)
                }
                break;
 
-               case MM_WFD_SINK_COMMAND_REALIZE:
+               case MM_WFD_SINK_COMMAND_PREPARE:
                {
-                       if (cur_state == MM_WFD_SINK_STATE_READY)
+                       if (cur_state == MM_WFD_SINK_STATE_PREPARED)
                                goto no_operation;
                        else if (cur_state != MM_WFD_SINK_STATE_NULL)
                                goto invalid_state;
 
-                       MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_READY;
+                       MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_PREPARED;
                }
                break;
 
                case MM_WFD_SINK_COMMAND_CONNECT:
                {
-                       if (cur_state == MM_WFD_SINK_STATE_PAUSED)
+                       if (cur_state == MM_WFD_SINK_STATE_CONNECTED)
                                goto no_operation;
-                       else if (cur_state != MM_WFD_SINK_STATE_READY)
+                       else if (cur_state != MM_WFD_SINK_STATE_PREPARED)
                                goto invalid_state;
 
-                       MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_PAUSED;
+                       MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_CONNECTED;
                }
                break;
 
@@ -907,25 +940,33 @@ __mm_wfd_sink_check_state(mm_wfd_sink_t* wfd_sink, MMWfdSinkCommandType cmd)
                {
                        if (cur_state == MM_WFD_SINK_STATE_PLAYING)
                                goto no_operation;
-                       else if (cur_state != MM_WFD_SINK_STATE_PAUSED)
+                       else if (cur_state != MM_WFD_SINK_STATE_CONNECTED)
                                goto invalid_state;
 
                        MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_PLAYING;
                }
                break;
 
-               case MM_WFD_SINK_COMMAND_STOP:
+               case MM_WFD_SINK_COMMAND_DISCONNECT:
                {
-                       if (cur_state == MM_WFD_SINK_STATE_READY || cur_state == MM_WFD_SINK_STATE_NULL || cur_state == MM_WFD_SINK_STATE_NONE)
+                       if (cur_state == MM_WFD_SINK_STATE_NONE ||
+                               cur_state == MM_WFD_SINK_STATE_NULL ||
+                               cur_state == MM_WFD_SINK_STATE_PREPARED ||
+                               cur_state == MM_WFD_SINK_STATE_DISCONNECTED)
                                goto no_operation;
+                       else if (cur_state != MM_WFD_SINK_STATE_PLAYING &&
+                               cur_state != MM_WFD_SINK_STATE_CONNECTED &&
+                               cur_state != MM_WFD_SINK_STATE_PAUSED)
+                               goto invalid_state;
 
-                       MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_READY;
+                       MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_DISCONNECTED;
                }
                break;
 
-               case MM_WFD_SINK_COMMAND_UNREALIZE:
+               case MM_WFD_SINK_COMMAND_UNPREPARE:
                {
-                       if (cur_state == MM_WFD_SINK_STATE_NULL || cur_state == MM_WFD_SINK_STATE_NONE)
+                       if (cur_state == MM_WFD_SINK_STATE_NONE ||
+                               cur_state == MM_WFD_SINK_STATE_NULL)
                                goto no_operation;
 
                        MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_NULL;
@@ -947,29 +988,29 @@ __mm_wfd_sink_check_state(mm_wfd_sink_t* wfd_sink, MMWfdSinkCommandType cmd)
 
        wfd_sink->cmd = cmd;
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 
 no_operation:
-       debug_error ("No-error: already %s state, nothing to do.\n", MMWFDSINK_STATE_GET_NAME(cur_state));
+       wfd_sink_debug ("already %s state, nothing to do.\n", MMWFDSINK_STATE_GET_NAME(cur_state));
        return MM_ERROR_WFD_NO_OP;
 
 /* ERRORS */
 invalid_state:
-       debug_error ("current state is invalid.\n", MMWFDSINK_STATE_GET_NAME(cur_state));
+       wfd_sink_error ("current state is invalid.\n", MMWFDSINK_STATE_GET_NAME(cur_state));
        return MM_ERROR_WFD_INVALID_STATE;
 }
 
-static int __mm_wfd_sink_set_state(mm_wfd_sink_t* wfd_sink, MMWfdSinkStateType state)
+static int __mm_wfd_sink_set_state(mm_wfd_sink_t* wfd_sink, MMWFDSinkStateType state)
 {
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
 
        if (MMWFDSINK_CURRENT_STATE(wfd_sink) == state )
        {
-               debug_error("already state(%s)\n", MMWFDSINK_STATE_GET_NAME(state));
+               wfd_sink_error("already state(%s)\n", MMWFDSINK_STATE_GET_NAME(state));
                MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_NONE;
                return MM_ERROR_NONE;
        }
@@ -982,12 +1023,14 @@ static int __mm_wfd_sink_set_state(mm_wfd_sink_t* wfd_sink, MMWfdSinkStateType s
                MMWFDSINK_PENDING_STATE(wfd_sink) = MM_WFD_SINK_STATE_NONE;
 
        /* poset state message to application */
-       __mm_wfd_post_message(wfd_sink, state);
+       MMWFDSINK_POST_MESSAGE(wfd_sink,
+               MM_ERROR_NONE,
+               MMWFDSINK_CURRENT_STATE(wfd_sink));
 
        /* print state */
        MMWFDSINK_PRINT_STATE(wfd_sink);
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 }
@@ -999,35 +1042,35 @@ __mm_wfd_sink_set_pipeline_state(mm_wfd_sink_t* wfd_sink, GstState state, gboole
        GstState cur_state = GST_STATE_VOID_PENDING;
        GstState pending_state = GST_STATE_VOID_PENDING;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink &&
+       wfd_sink_return_val_if_fail (wfd_sink &&
                wfd_sink->pipeline &&
                wfd_sink->pipeline->mainbin &&
                wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst,
                MM_ERROR_WFD_NOT_INITIALIZED);
 
-       return_val_if_fail (state > GST_STATE_VOID_PENDING,
+       wfd_sink_return_val_if_fail (state > GST_STATE_VOID_PENDING,
                MM_ERROR_WFD_INVALID_ARGUMENT);
 
-       debug_error ("No-error: try to set %s state \n", gst_element_state_get_name(state));
+       wfd_sink_debug ("try to set %s state \n", gst_element_state_get_name(state));
 
        result = gst_element_set_state (wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst, state);
        if (result == GST_STATE_CHANGE_FAILURE)
        {
-               debug_error ("fail to set %s state....\n", gst_element_state_get_name(state));
+               wfd_sink_error ("fail to set %s state....\n", gst_element_state_get_name(state));
                return MM_ERROR_WFD_INTERNAL;
        }
 
        if (!async)
        {
-               debug_error ("No-error: wait for changing state is completed \n");
+               wfd_sink_debug ("wait for changing state is completed \n");
 
                result = gst_element_get_state (wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst,
                                &cur_state, &pending_state, wfd_sink->ini.state_change_timeout * GST_SECOND);
                if (result == GST_STATE_CHANGE_FAILURE)
                {
-                       debug_error ("fail to get state within %d seconds....\n", wfd_sink->ini.state_change_timeout);
+                       wfd_sink_error ("fail to get state within %d seconds....\n", wfd_sink->ini.state_change_timeout);
 
                        __mm_wfd_sink_dump_pipeline_state(wfd_sink);
 
@@ -1035,75 +1078,82 @@ __mm_wfd_sink_set_pipeline_state(mm_wfd_sink_t* wfd_sink, GstState state, gboole
                }
                else if (result == GST_STATE_CHANGE_NO_PREROLL)
                {
-                       debug_error ("No-error: successfully changed state but is not able to provide data yet\n");
+                       wfd_sink_debug ("successfully changed state but is not able to provide data yet\n");
                }
 
-               debug_error ("No-error: cur state is %s, pending state is %s\n",
+               wfd_sink_debug("cur state is %s, pending state is %s\n",
                        gst_element_state_get_name(cur_state),
                        gst_element_state_get_name(pending_state));
        }
 
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 }
 
-static GstPadProbeReturn
-_mm_wfd_sink_reset_basetime(GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
+static void
+_mm_wfd_sink_reset_basetime(mm_wfd_sink_t *wfd_sink)
 {
-       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *)u_data;
+       GstClockTime base_time = GST_CLOCK_TIME_NONE;
+       int i;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       if (wfd_sink->need_to_reset_basetime)
+       wfd_sink_return_if_fail (wfd_sink &&
+               wfd_sink->pipeline &&
+               wfd_sink->pipeline->mainbin &&
+               wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst);
+       wfd_sink_return_if_fail (wfd_sink->need_to_reset_basetime);
+
+
+       if (wfd_sink->clock)
+               base_time = gst_clock_get_time (wfd_sink->clock);
+
+       if (GST_CLOCK_TIME_IS_VALID(base_time))
        {
-               GstClock * clock = NULL;
-               GstClockTime base_time = GST_CLOCK_TIME_NONE;
 
-               clock = gst_element_get_clock (GST_ELEMENT_CAST (wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst));
-               if (clock)
-               {
-                       base_time = gst_clock_get_time (clock);
-                       gst_object_unref (clock);
-               }
+               wfd_sink_debug ("set pipeline base_time as now [%"GST_TIME_FORMAT"]\n",GST_TIME_ARGS(base_time));
 
-               if (base_time != GST_CLOCK_TIME_NONE)
+               for (i=0; i<WFD_SINK_M_NUM; i++)
                {
-                       debug_error ("No-error: set pipeline basetime as now \n");
-                       gst_element_set_base_time(GST_ELEMENT_CAST (wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst), base_time);
-
-                       wfd_sink->need_to_reset_basetime = FALSE;
+                       if (wfd_sink->pipeline->mainbin[i].gst)
+                               gst_element_set_base_time(GST_ELEMENT_CAST (wfd_sink->pipeline->mainbin[i].gst), base_time);
                }
-       }
-       else
-       {
-               if (wfd_sink->demux_audio_pad_probe_id)
+
+               if (wfd_sink->pipeline->videobin)
                {
-                       debug_log ("remove pad probe(%d) for demux audio pad \n", wfd_sink->demux_audio_pad_probe_id);
-                       gst_pad_remove_probe (pad, wfd_sink->demux_audio_pad_probe_id);
+                       for (i=0; i<WFD_SINK_V_NUM; i++)
+                       {
+                               if (wfd_sink->pipeline->videobin[i].gst)
+                                       gst_element_set_base_time(GST_ELEMENT_CAST (wfd_sink->pipeline->videobin[i].gst), base_time);
+                       }
                }
-               if (wfd_sink->demux_video_pad_probe_id)
+
+               if (wfd_sink->pipeline->audiobin)
                {
-                       debug_log ("remove pad probe(%d) for demux video pad \n", wfd_sink->demux_video_pad_probe_id);
-                       gst_pad_remove_probe (pad, wfd_sink->demux_video_pad_probe_id);
+                       for (i=0; i<WFD_SINK_A_NUM; i++)
+                       {
+                               if (wfd_sink->pipeline->audiobin[i].gst)
+                                       gst_element_set_base_time(GST_ELEMENT_CAST (wfd_sink->pipeline->audiobin[i].gst), base_time);
+                       }
                }
+               wfd_sink->need_to_reset_basetime = FALSE;
        }
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
-       return TRUE;
+       return;
 }
 
-
 int
 __mm_wfd_sink_prepare_videobin (mm_wfd_sink_t *wfd_sink)
 {
        GstElement* videobin = NULL;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink &&
+       wfd_sink_return_val_if_fail (wfd_sink &&
                wfd_sink->pipeline,
                MM_ERROR_WFD_NOT_INITIALIZED);
 
@@ -1111,35 +1161,36 @@ __mm_wfd_sink_prepare_videobin (mm_wfd_sink_t *wfd_sink)
        {
                if (MM_ERROR_NONE !=__mm_wfd_sink_create_videobin (wfd_sink))
                {
-                       debug_error ("failed to create videobin....\n");
+                       wfd_sink_error ("failed to create videobin....\n");
                        goto ERROR;
                }
        }
        else
        {
-               debug_error ("No-error: videobin is already created.\n");
+               wfd_sink_debug ("videobin is already created.\n");
        }
 
        videobin = wfd_sink->pipeline->videobin[WFD_SINK_V_BIN].gst;
 
-       if (!wfd_sink->video_bin_is_prepared)
+       if (GST_STATE(videobin) <= GST_STATE_NULL)
        {
                if (GST_STATE_CHANGE_FAILURE == gst_element_set_state (videobin, GST_STATE_READY))
                {
-                       debug_error("failed to set state(READY) to %s\n", GST_STR_NULL(GST_ELEMENT_NAME(videobin)));
+                       wfd_sink_error("failed to set state(READY) to %s\n", GST_STR_NULL(GST_ELEMENT_NAME(videobin)));
                        goto ERROR;
                }
-               wfd_sink->video_bin_is_prepared = TRUE;
        }
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 
 /* ERRORS */
 ERROR:
        /* need to notify to app */
-       __mm_wfd_post_message(wfd_sink, MM_WFD_SINK_STATE_TEARDOWN);
+       MMWFDSINK_POST_MESSAGE(wfd_sink,
+               MM_ERROR_WFD_INTERNAL,
+               MMWFDSINK_CURRENT_STATE(wfd_sink));
 
        return MM_ERROR_WFD_INTERNAL;
 }
@@ -1149,9 +1200,9 @@ __mm_wfd_sink_prepare_audiobin (mm_wfd_sink_t *wfd_sink)
 {
        MMWFDSinkGstElement* audiobin = NULL;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink &&
+       wfd_sink_return_val_if_fail (wfd_sink &&
                wfd_sink->pipeline,
                MM_ERROR_WFD_NOT_INITIALIZED);
 
@@ -1159,7 +1210,7 @@ __mm_wfd_sink_prepare_audiobin (mm_wfd_sink_t *wfd_sink)
        {
                if (MM_ERROR_NONE !=__mm_wfd_sink_create_audiobin (wfd_sink))
                {
-                       debug_error ("failed to create audiobin....\n");
+                       wfd_sink_error ("failed to create audiobin....\n");
                        goto ERROR;
                }
        }
@@ -1168,36 +1219,321 @@ __mm_wfd_sink_prepare_audiobin (mm_wfd_sink_t *wfd_sink)
        {
                if (MM_ERROR_NONE !=__mm_wfd_sink_link_audiobin(wfd_sink))
                {
-                       debug_error ("failed to link audio decoder.....\n");
+                       wfd_sink_error ("failed to link audio decoder.....\n");
                        goto ERROR;
                }
        }
 
        audiobin = wfd_sink->pipeline->audiobin;
 
-       if (!wfd_sink->audio_bin_is_prepared)
+       if (GST_STATE(audiobin) <= GST_STATE_NULL)
        {
-               if (GST_STATE_CHANGE_FAILURE == gst_element_set_state (audiobin[WFD_SINK_A_BIN].gst, GST_STATE_READY))
+               if (GST_STATE_CHANGE_FAILURE ==gst_element_set_state (audiobin[WFD_SINK_A_BIN].gst, GST_STATE_READY))
                {
-                       debug_error("failed to set state(READY) to %s\n", GST_STR_NULL(GST_ELEMENT_NAME(audiobin)));
+                       wfd_sink_error("failed to set state(READY) to %s\n",
+                               GST_STR_NULL(GST_ELEMENT_NAME(audiobin)));
                        goto ERROR;
                }
-
-               wfd_sink->audio_bin_is_prepared = TRUE;
        }
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 
 /* ERRORS */
 ERROR:
        /* need to notify to app */
-       __mm_wfd_post_message(wfd_sink, MM_WFD_SINK_STATE_TEARDOWN);
+       MMWFDSINK_POST_MESSAGE(wfd_sink,
+               MM_ERROR_WFD_INTERNAL,
+               MMWFDSINK_CURRENT_STATE(wfd_sink));
 
        return MM_ERROR_WFD_INTERNAL;
 }
 
+#define COMPENSATION_CRETERIA_VALUE 1000000 // 1 msec
+#define COMPENSATION_CHECK_PERIOD 30*GST_SECOND  // 30 sec
+
+static GstPadProbeReturn
+_mm_wfd_sink_check_running_time(GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
+{
+       mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *)u_data;
+       GstClockTime current_time = GST_CLOCK_TIME_NONE;
+       GstClockTime start_time = GST_CLOCK_TIME_NONE;
+       GstClockTime running_time = GST_CLOCK_TIME_NONE;
+       GstClockTime base_time = GST_CLOCK_TIME_NONE;
+       GstClockTime render_time = GST_CLOCK_TIME_NONE;
+       GstClockTimeDiff diff = GST_CLOCK_TIME_NONE;
+       GstBuffer * buffer = NULL;
+       gint64 ts_offset = 0LL;
+       GstPadProbeReturn ret = GST_PAD_PROBE_OK;
+
+       wfd_sink_return_val_if_fail (info, FALSE);
+       wfd_sink_return_val_if_fail (wfd_sink &&
+               wfd_sink->pipeline &&
+               wfd_sink->pipeline->mainbin &&
+               wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst,
+               GST_PAD_PROBE_DROP);
+
+       if (!wfd_sink->clock)
+       {
+               wfd_sink_warning ("pipeline did not select clock, yet\n");
+               return GST_PAD_PROBE_OK;
+       }
+
+       if (wfd_sink->need_to_reset_basetime)
+               _mm_wfd_sink_reset_basetime(wfd_sink);
+
+       /* calculate current runninig time */
+       current_time = gst_clock_get_time(wfd_sink->clock);
+       if (g_strrstr(GST_OBJECT_NAME(pad), "video"))
+               base_time = gst_element_get_base_time(wfd_sink->pipeline->videobin[WFD_SINK_V_BIN].gst);
+       else if (g_strrstr(GST_OBJECT_NAME(pad), "audio"))
+               base_time = gst_element_get_base_time(wfd_sink->pipeline->audiobin[WFD_SINK_A_BIN].gst);
+       start_time = gst_element_get_start_time(wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst);
+       if (GST_CLOCK_TIME_IS_VALID(current_time) &&
+               GST_CLOCK_TIME_IS_VALID(start_time) &&
+               GST_CLOCK_TIME_IS_VALID(base_time))
+       {
+               running_time = current_time - (start_time + base_time);
+       }
+       else
+       {
+               wfd_sink_debug ("current time %"GST_TIME_FORMAT", start time %"GST_TIME_FORMAT
+                       "  base time %"GST_TIME_FORMAT"\n", GST_TIME_ARGS(current_time),
+                       GST_TIME_ARGS(start_time), GST_TIME_ARGS(base_time));
+               return GST_PAD_PROBE_OK;
+       }
+
+       /* calculate this buffer rendering time */
+       buffer = gst_pad_probe_info_get_buffer (info);
+       if (!GST_BUFFER_TIMESTAMP_IS_VALID(buffer))
+       {
+               wfd_sink_error ("buffer timestamp is invalid.\n");
+               return GST_PAD_PROBE_OK;
+       }
+
+       if (g_strrstr(GST_OBJECT_NAME(pad), "audio"))
+       {
+               if (wfd_sink->pipeline && wfd_sink->pipeline->audiobin && wfd_sink->pipeline->audiobin[WFD_SINK_A_SINK].gst)
+                       g_object_get(G_OBJECT(wfd_sink->pipeline->audiobin[WFD_SINK_A_SINK].gst), "ts-offset", &ts_offset, NULL);
+       }
+       else if (g_strrstr(GST_OBJECT_NAME(pad), "video"))
+       {
+               if (wfd_sink->pipeline && wfd_sink->pipeline->videobin && wfd_sink->pipeline->videobin[WFD_SINK_V_SINK].gst)
+                       g_object_get(G_OBJECT(wfd_sink->pipeline->videobin[WFD_SINK_V_SINK].gst), "ts-offset", &ts_offset, NULL);
+       }
+
+       render_time = GST_BUFFER_TIMESTAMP(buffer);
+       render_time += ts_offset;
+
+       /* chekc this buffer could be rendered or not */
+       if (GST_CLOCK_TIME_IS_VALID(running_time) && GST_CLOCK_TIME_IS_VALID(render_time))
+       {
+               diff=GST_CLOCK_DIFF(running_time, render_time);
+               if (diff < 0)
+               {
+                       /* this buffer could be NOT rendered */
+                       wfd_sink_debug ("%s : diff time : -%" GST_TIME_FORMAT "\n",
+                               GST_STR_NULL((GST_OBJECT_NAME(pad))),
+                               GST_TIME_ARGS(GST_CLOCK_DIFF(render_time, running_time)));
+               }
+               else
+               {
+                       /* this buffer could be rendered */
+                       //wfd_sink_debug ("%s :diff time : %" GST_TIME_FORMAT "\n",
+                       //      GST_STR_NULL((GST_OBJECT_NAME(pad))),
+                       //      GST_TIME_ARGS(diff));
+               }
+       }
+
+       /* update buffer count and gap */
+       if (g_strrstr(GST_OBJECT_NAME(pad), "video"))
+       {
+               wfd_sink->video_buffer_count ++;
+               wfd_sink->video_accumulated_gap += diff;
+       }
+       else if (g_strrstr(GST_OBJECT_NAME(pad), "audio"))
+       {
+               wfd_sink->audio_buffer_count ++;
+               wfd_sink->audio_accumulated_gap += diff;
+       }
+       else
+       {
+               wfd_sink_warning("invalid buffer type.. \n");
+               return GST_PAD_PROBE_DROP;
+       }
+
+       if (GST_CLOCK_TIME_IS_VALID(wfd_sink->last_buffer_timestamp))
+       {
+               /* fisrt 60sec, just calculate the gap between source device and sink device */
+               if (GST_BUFFER_TIMESTAMP(buffer) < 60*GST_SECOND)
+                       return GST_PAD_PROBE_OK;
+
+               /* every 10sec, calculate the gap between source device and sink device */
+               if (GST_CLOCK_DIFF(wfd_sink->last_buffer_timestamp, GST_BUFFER_TIMESTAMP(buffer))
+                       > COMPENSATION_CHECK_PERIOD)
+               {
+                       gint64 audio_avgrage_gap = 0LL;
+                       gint64 video_avgrage_gap = 0LL;
+                       gint64 audio_avgrage_gap_diff = 0LL;
+                       gint64 video_avgrage_gap_diff = 0LL;
+                       gboolean video_minus_compensation = FALSE;
+                       gboolean audio_minus_compensation = FALSE;
+                       gint64 avgrage_gap_diff = 0LL;
+                       gboolean minus_compensation = FALSE;
+
+                       /* check video */
+                       if (wfd_sink->video_buffer_count > 0)
+                       {
+                               video_avgrage_gap = wfd_sink->video_accumulated_gap /wfd_sink->video_buffer_count;
+
+                               if (wfd_sink->video_average_gap !=0)
+                               {
+                                       if (video_avgrage_gap > wfd_sink->video_average_gap)
+                                       {
+                                               video_avgrage_gap_diff = video_avgrage_gap - wfd_sink->video_average_gap;
+                                               video_minus_compensation = TRUE;
+                                       }
+                                       else
+                                       {
+                                               video_avgrage_gap_diff = wfd_sink->video_average_gap - video_avgrage_gap;
+                                               video_minus_compensation = FALSE;
+                                       }
+                               }
+                               else
+                               {
+                                       wfd_sink_debug ("first update video average gap (%lld) \n", video_avgrage_gap);
+                                       wfd_sink->video_average_gap = video_avgrage_gap;
+                               }
+                       }
+                       else
+                       {
+                               wfd_sink_debug ("there is no video buffer flow during %"GST_TIME_FORMAT
+                                       " ~ %" GST_TIME_FORMAT"\n",
+                                       GST_TIME_ARGS(wfd_sink->last_buffer_timestamp),
+                                       GST_TIME_ARGS( GST_BUFFER_TIMESTAMP(buffer)));
+                       }
+
+                       /* check audio */
+                       if (wfd_sink->audio_buffer_count > 0)
+                       {
+                               audio_avgrage_gap = wfd_sink->audio_accumulated_gap /wfd_sink->audio_buffer_count;
+
+                               if (wfd_sink->audio_average_gap !=0)
+                               {
+                                       if (audio_avgrage_gap > wfd_sink->audio_average_gap)
+                                       {
+                                               audio_avgrage_gap_diff = audio_avgrage_gap - wfd_sink->audio_average_gap;
+                                               audio_minus_compensation = TRUE;
+                                       }
+                                       else
+                                       {
+                                               audio_avgrage_gap_diff = wfd_sink->audio_average_gap - audio_avgrage_gap;
+                                               audio_minus_compensation = FALSE;
+                                       }
+                               }
+                               else
+                               {
+                                       wfd_sink_debug ("first update audio average gap (%lld) \n", audio_avgrage_gap);
+                                       wfd_sink->audio_average_gap = audio_avgrage_gap;
+                               }
+                       }
+                       else
+                       {
+                               wfd_sink_debug ("there is no audio buffer flow during %"GST_TIME_FORMAT
+                                       " ~ %" GST_TIME_FORMAT"\n",
+                                       GST_TIME_ARGS(wfd_sink->last_buffer_timestamp),
+                                       GST_TIME_ARGS( GST_BUFFER_TIMESTAMP(buffer)));
+                       }
+
+                       /* selecet average_gap_diff between video and audio */
+                       /*  which makes no buffer drop in the sink elements */
+                       if (video_avgrage_gap_diff && audio_avgrage_gap_diff)
+                       {
+                               if (!video_minus_compensation && !audio_minus_compensation)
+                               {
+                                       minus_compensation = FALSE;
+                                       if (video_avgrage_gap_diff > audio_avgrage_gap_diff)
+                                               avgrage_gap_diff = video_avgrage_gap_diff;
+                                       else
+                                               avgrage_gap_diff = audio_avgrage_gap_diff;
+                               }
+                               else if (video_minus_compensation && audio_minus_compensation)
+                               {
+                                       minus_compensation = TRUE;
+                                       if (video_avgrage_gap_diff > audio_avgrage_gap_diff)
+                                               avgrage_gap_diff = audio_avgrage_gap_diff;
+                                       else
+                                               avgrage_gap_diff = video_avgrage_gap_diff;
+                               }
+                               else
+                               {
+                                       minus_compensation = FALSE;
+                                       if (!video_minus_compensation)
+                                               avgrage_gap_diff = video_avgrage_gap_diff;
+                                       else
+                                               avgrage_gap_diff = audio_avgrage_gap_diff;
+                               }
+                       }
+                       else if (video_avgrage_gap_diff)
+                       {
+                               minus_compensation = video_minus_compensation;
+                               avgrage_gap_diff = video_avgrage_gap_diff;
+                       }
+                       else if (audio_avgrage_gap_diff)
+                       {
+                               minus_compensation = audio_minus_compensation;
+                               avgrage_gap_diff = audio_avgrage_gap_diff;
+                       }
+
+                       wfd_sink_debug ("average diff gap difference beween audio:%s%lld and video:%s%lld \n",
+                               audio_minus_compensation ? "-" : "", audio_avgrage_gap_diff,
+                               video_minus_compensation ? "-" : "", video_avgrage_gap_diff);
+
+
+                       /* if calculated gap diff is larger than 1ms. need to compensate buffer timestamp */
+                       if (avgrage_gap_diff >= COMPENSATION_CRETERIA_VALUE)
+                       {
+                               if (minus_compensation)
+                                       ts_offset -= avgrage_gap_diff;
+                               else
+                                       ts_offset += avgrage_gap_diff;
+
+                               wfd_sink_debug ("do timestamp compensation : %s%lld (ts-offset : %"
+                                       GST_TIME_FORMAT") at (%" GST_TIME_FORMAT")\n",
+                                       minus_compensation? "-" : "", avgrage_gap_diff,
+                                       GST_TIME_ARGS(ts_offset), GST_TIME_ARGS(running_time));
+
+                               if (wfd_sink->pipeline && wfd_sink->pipeline->audiobin && wfd_sink->pipeline->audiobin[WFD_SINK_A_SINK].gst)
+                                       g_object_set(G_OBJECT(wfd_sink->pipeline->audiobin[WFD_SINK_A_SINK].gst), "ts-offset", (gint64)ts_offset, NULL);
+                               if (wfd_sink->pipeline && wfd_sink->pipeline->videobin && wfd_sink->pipeline->videobin[WFD_SINK_V_SINK].gst)
+                                       g_object_set(G_OBJECT(wfd_sink->pipeline->videobin[WFD_SINK_V_SINK].gst), "ts-offset", (gint64)ts_offset, NULL);
+                       }
+                       else
+                       {
+                               wfd_sink_debug ("don't need to do timestamp compensation : %s%lld (ts-offset : %"GST_TIME_FORMAT ")\n",
+                                       minus_compensation? "-" : "", avgrage_gap_diff, GST_TIME_ARGS(ts_offset));
+                       }
+
+                       /* reset values*/
+                       wfd_sink->video_buffer_count = 0;
+                       wfd_sink->video_accumulated_gap = 0LL;
+                       wfd_sink->audio_buffer_count = 0;
+                       wfd_sink->audio_accumulated_gap = 0LL;
+                       wfd_sink->last_buffer_timestamp = GST_BUFFER_TIMESTAMP(buffer);
+               }
+       }
+       else
+       {
+               wfd_sink_debug ("first update last buffer timestamp :%" GST_TIME_FORMAT" \n",
+                        GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)));
+               wfd_sink->last_buffer_timestamp = GST_BUFFER_TIMESTAMP(buffer);
+       }
+
+       return GST_PAD_PROBE_OK;
+}
+
+
 static void
 __mm_wfd_sink_demux_pad_added (GstElement* ele, GstPad* pad, gpointer data)
 {
@@ -1206,29 +1542,28 @@ __mm_wfd_sink_demux_pad_added (GstElement* ele, GstPad* pad, gpointer data)
        GstElement* sinkbin = NULL;
        GstPad* sinkpad = NULL;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_if_fail (wfd_sink && wfd_sink->pipeline);
+       wfd_sink_return_if_fail (wfd_sink && wfd_sink->pipeline);
 
        if (name[0] == 'v')
        {
-               debug_error("No-error:  =========== >>>>>>>>>> Received VIDEO pad...:%s\n", name);
+               wfd_sink_debug("=========== >>>>>>>>>> Received VIDEO pad...\n");
 
                MMWFDSINK_PAD_PROBE( wfd_sink, pad, NULL,  NULL );
 
-               if (wfd_sink->need_to_reset_basetime)
-               {
-                       debug_error("No-error: need to reset basetime... set pad probe for video pad of demux\n");
-                       wfd_sink->demux_video_pad_probe_id = gst_pad_add_probe(pad,
-                                       GST_PAD_PROBE_TYPE_BUFFER, _mm_wfd_sink_reset_basetime, wfd_sink, NULL);
-               }
+               gst_pad_add_probe(pad,
+                       GST_PAD_PROBE_TYPE_BUFFER,
+                       _mm_wfd_sink_check_running_time,
+                       (gpointer)wfd_sink,
+                       NULL);
 
-               if (!wfd_sink->video_bin_is_prepared)
+               if (GST_STATE(wfd_sink->pipeline->videobin[WFD_SINK_V_BIN].gst) <= GST_STATE_NULL)
                {
-                       debug_error ("need to prepare videobin" );
+                       wfd_sink_debug ("need to prepare videobin" );
                        if (MM_ERROR_NONE !=__mm_wfd_sink_prepare_videobin (wfd_sink))
                        {
-                               debug_error ("failed to prepare videobin....\n");
+                               wfd_sink_error ("failed to prepare videobin....\n");
                                goto ERROR;
                        }
                }
@@ -1239,23 +1574,22 @@ __mm_wfd_sink_demux_pad_added (GstElement* ele, GstPad* pad, gpointer data)
        }
        else if (name[0] == 'a')
        {
-               debug_error("No-error:  =========== >>>>>>>>>> Received AUDIO pad...:%s\n", name);
+               wfd_sink_debug("=========== >>>>>>>>>> Received AUDIO pad...\n");
 
                MMWFDSINK_PAD_PROBE( wfd_sink, pad, NULL,  NULL );
 
-               if (wfd_sink->need_to_reset_basetime)
-               {
-                       debug_error("No-error: need to reset basetime... set pad probe for audio pad of demux\n");
-                       wfd_sink->demux_audio_pad_probe_id = gst_pad_add_probe(pad,
-                                       GST_PAD_PROBE_TYPE_BUFFER, _mm_wfd_sink_reset_basetime, wfd_sink, NULL);
-               }
+               gst_pad_add_probe(pad,
+                       GST_PAD_PROBE_TYPE_BUFFER,
+                       _mm_wfd_sink_check_running_time,
+                       (gpointer)wfd_sink,
+                       NULL);
 
-               if (!wfd_sink->audio_bin_is_prepared)
+               if (GST_STATE(wfd_sink->pipeline->audiobin[WFD_SINK_A_BIN].gst) <= GST_STATE_NULL)
                {
-                       debug_error ("need to prepare audiobin" );
+                       wfd_sink_debug ("need to prepare audiobin" );
                        if (MM_ERROR_NONE !=__mm_wfd_sink_prepare_audiobin (wfd_sink))
                        {
-                               debug_error ("failed to prepare audiobin....\n");
+                               wfd_sink_error ("failed to prepare audiobin....\n");
                                goto ERROR;
                        }
                }
@@ -1266,43 +1600,45 @@ __mm_wfd_sink_demux_pad_added (GstElement* ele, GstPad* pad, gpointer data)
        }
        else
        {
-               debug_error("not handling.....\n\n\n");
+               wfd_sink_error("not handling.....\n\n\n");
        }
 
 
        if (sinkbin)
        {
-               debug_error("No-error:  add %s to pipeline.\n", GST_STR_NULL(GST_ELEMENT_NAME(sinkbin)));
+               wfd_sink_debug("add %s to pipeline.\n",
+                       GST_STR_NULL(GST_ELEMENT_NAME(sinkbin)));
 
                /* add */
                if(!gst_bin_add (GST_BIN(wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst), sinkbin))
                {
-                       debug_error("failed to add sinkbin to pipeline\n");
+                       wfd_sink_error("failed to add sinkbin to pipeline\n");
                        goto ERROR;
                }
 
-               debug_error("No-error:  link %s .\n", GST_STR_NULL(GST_ELEMENT_NAME(sinkbin)));
+               wfd_sink_debug("link %s .\n", GST_STR_NULL(GST_ELEMENT_NAME(sinkbin)));
 
                /* link */
                sinkpad = gst_element_get_static_pad (GST_ELEMENT_CAST(sinkbin), "sink");
                if (!sinkpad)
                {
-                       debug_error("failed to get pad from sinkbin\n");
+                       wfd_sink_error("failed to get pad from sinkbin\n");
                        goto ERROR;
                }
 
                if (GST_PAD_LINK_OK != gst_pad_link_full (pad, sinkpad, GST_PAD_LINK_CHECK_NOTHING))
                {
-                       debug_error("failed to link sinkbin\n");
+                       wfd_sink_error("failed to link sinkbin\n");
                        goto ERROR;
                }
 
-               debug_error("No-error:  sync state %s with pipeline .\n", GST_STR_NULL(GST_ELEMENT_NAME(sinkbin)));
+               wfd_sink_debug("sync state %s with pipeline .\n",
+                       GST_STR_NULL(GST_ELEMENT_NAME(sinkbin)));
 
                /* run */
                if (!gst_element_sync_state_with_parent (GST_ELEMENT_CAST(sinkbin)))
                {
-                       debug_error ("failed to sync sinkbin state with parent \n");
+                       wfd_sink_error ("failed to sync sinkbin state with parent \n");
                        goto ERROR;
                }
 
@@ -1313,17 +1649,15 @@ __mm_wfd_sink_demux_pad_added (GstElement* ele, GstPad* pad, gpointer data)
 
        if (wfd_sink->added_av_pad_num == 2)
        {
-               debug_error ("No-error: whole pipeline is constructed. \n");
+               wfd_sink_debug("whole pipeline is constructed. \n");
 
                /* generate dot file of the constructed pipeline of wifi display sink */
-               MMWFD_GENERATE_DOT_IF_ENABLED( wfd_sink, "constructed-pipeline" );
-
-               wfd_sink->is_constructed = TRUE;
+               MMWFDSINK_GENERATE_DOT_IF_ENABLED( wfd_sink, "constructed-pipeline" );
        }
 
        MMWFDSINK_FREEIF(name);
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return;
 
@@ -1336,7 +1670,9 @@ ERROR:
        sinkpad = NULL;
 
        /* need to notify to app */
-       __mm_wfd_post_message(wfd_sink, MM_WFD_SINK_STATE_TEARDOWN);
+       MMWFDSINK_POST_MESSAGE (wfd_sink,
+               MM_ERROR_WFD_INTERNAL,
+               MMWFDSINK_CURRENT_STATE(wfd_sink));
 
        return;
 }
@@ -1346,26 +1682,27 @@ __mm_wfd_sink_change_av_format (GstElement* wfdrtspsrc, gpointer* need_to_flush,
 {
        mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *)data;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_if_fail (wfd_sink);
-       return_if_fail (need_to_flush);
+       wfd_sink_return_if_fail (wfd_sink);
+       wfd_sink_return_if_fail (need_to_flush);
 
        if (MMWFDSINK_CURRENT_STATE(wfd_sink)==MM_WFD_SINK_STATE_PLAYING)
        {
-               debug_error("No-error: need to flush pipeline");
+               wfd_sink_debug("need to flush pipeline");
                *need_to_flush = (gpointer) TRUE;
        }
        else
        {
-               debug_error("No-error: don't need to flush pipeline");
+               wfd_sink_debug("don't need to flush pipeline");
                *need_to_flush = (gpointer) FALSE;
        }
 
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 }
 
+
 static void
 __mm_wfd_sink_update_stream_info (GstElement* wfdrtspsrc, GstStructure* str, gpointer data)
 {
@@ -1377,10 +1714,10 @@ __mm_wfd_sink_update_stream_info (GstElement* wfdrtspsrc, GstStructure* str, gpo
        gchar * audio_format;
        gchar * video_format;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_if_fail (str && GST_IS_STRUCTURE(str));
-       return_if_fail (wfd_sink);
+       wfd_sink_return_if_fail (str && GST_IS_STRUCTURE(str));
+       wfd_sink_return_if_fail (wfd_sink);
 
        stream_info = &wfd_sink->stream_info;
 
@@ -1396,7 +1733,7 @@ __mm_wfd_sink_update_stream_info (GstElement* wfdrtspsrc, GstStructure* str, gpo
                        stream_info->audio_stream_info.codec = WFD_SINK_AUDIO_CODEC_LPCM;
                else
                {
-                       debug_error ("invalid audio format(%s)...\n", audio_format);
+                       wfd_sink_error ("invalid audio format(%s)...\n", audio_format);
                        is_valid_audio_format = FALSE;
                }
 
@@ -1411,9 +1748,11 @@ __mm_wfd_sink_update_stream_info (GstElement* wfdrtspsrc, GstStructure* str, gpo
 
                        cmd = cmd | WFD_SINK_MANAGER_CMD_LINK_A_BIN;
 
-                       debug_error ("No-error: audio_format : %s \n \t rate :  %d \n \t channels :  %d \n \t bitwidth :  %d \n \t      \n",
-                               audio_format, stream_info->audio_stream_info.sample_rate,
-                               stream_info->audio_stream_info.channels, stream_info->audio_stream_info.bitwidth);
+                       wfd_sink_debug ("audio_format : %s \n \t rate : %d \n \t channels :  %d \n \t bitwidth :  %d \n \t      \n",
+                               audio_format,
+                               stream_info->audio_stream_info.sample_rate,
+                               stream_info->audio_stream_info.channels,
+                               stream_info->audio_stream_info.bitwidth);
                }
        }
 
@@ -1423,7 +1762,7 @@ __mm_wfd_sink_update_stream_info (GstElement* wfdrtspsrc, GstStructure* str, gpo
                video_format = g_strdup(gst_structure_get_string(str, "video_format"));
                if (!g_strrstr(video_format,"H264"))
                {
-                       debug_error ("invalid video format(%s)...\n", video_format);
+                       wfd_sink_error ("invalid video format(%s)...\n", video_format);
                        is_valid_video_format = FALSE;
                }
 
@@ -1438,10 +1777,11 @@ __mm_wfd_sink_update_stream_info (GstElement* wfdrtspsrc, GstStructure* str, gpo
                        if (gst_structure_has_field (str, "video_framerate"))
                                gst_structure_get_int (str, "video_framerate", &stream_info->video_stream_info.frame_rate);
 
-                       cmd = cmd | WFD_SINK_MANAGER_CMD_LINK_V_BIN ;
+                       cmd = cmd | WFD_SINK_MANAGER_CMD_LINK_V_BIN;
 
-                       debug_error ("No-error: video_format : %s \n \t width :  %d \n \t height :  %d \n \t frame_rate :  %d \n \t  \n",
-                               video_format, stream_info->video_stream_info.width,
+                       wfd_sink_debug("video_format : %s \n \t width :  %d \n \t height :  %d \n \t frame_rate :  %d \n \t  \n",
+                               video_format,
+                               stream_info->video_stream_info.width,
                                stream_info->video_stream_info.height,
                                stream_info->video_stream_info.frame_rate);
                }
@@ -1454,7 +1794,7 @@ __mm_wfd_sink_update_stream_info (GstElement* wfdrtspsrc, GstStructure* str, gpo
                WFD_SINK_MANAGER_UNLOCK(wfd_sink);
        }
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 }
 
 static int __mm_wfd_sink_prepare_wfdrtspsrc(mm_wfd_sink_t *wfd_sink, GstElement *wfdrtspsrc)
@@ -1466,15 +1806,17 @@ static int __mm_wfd_sink_prepare_wfdrtspsrc(mm_wfd_sink_t *wfd_sink, GstElement
        gint hdcp_version = 0;
        gint hdcp_port = 0;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-       return_val_if_fail (wfd_sink->attrs, MM_ERROR_WFD_NOT_INITIALIZED);
-       return_val_if_fail (wfdrtspsrc, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink->attrs, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfdrtspsrc, MM_ERROR_WFD_NOT_INITIALIZED);
 
        g_object_set (G_OBJECT(wfdrtspsrc), "debug", wfd_sink->ini.set_debug_property, NULL);
        g_object_set (G_OBJECT(wfdrtspsrc), "latency", wfd_sink->ini.jitter_buffer_latency, NULL);
+#if 0
        g_object_set (G_OBJECT(wfdrtspsrc), "do-request", wfd_sink->ini.enable_retransmission, NULL);
+#endif
        g_object_set (G_OBJECT(wfdrtspsrc), "udp-buffer-size", 2097152, NULL);
        g_object_set (G_OBJECT(wfdrtspsrc), "enable-pad-probe", wfd_sink->ini.enable_wfdrtspsrc_pad_probe, NULL);
 
@@ -1504,7 +1846,7 @@ static int __mm_wfd_sink_prepare_wfdrtspsrc(mm_wfd_sink_t *wfd_sink, GstElement
        mm_attrs_get_data_by_name(wfd_sink->attrs, "hdcp_handle", &hdcp_handle);
        mm_attrs_get_int_by_name(wfd_sink->attrs, "hdcp_version", &hdcp_version);
        mm_attrs_get_int_by_name(wfd_sink->attrs, "hdcp_port", &hdcp_port);
-       debug_log("set hdcp version %d with %d port\n", hdcp_version, hdcp_port);
+       wfd_sink_debug("set hdcp version %d with %d port\n", hdcp_version, hdcp_port);
 
        hdcp_param = gst_structure_new ("hdcp_param",
                        "hdcp_version", G_TYPE_INT, hdcp_version,
@@ -1515,27 +1857,28 @@ static int __mm_wfd_sink_prepare_wfdrtspsrc(mm_wfd_sink_t *wfd_sink, GstElement
        g_object_set (G_OBJECT(wfdrtspsrc), "video-param", video_param, NULL);
        g_object_set (G_OBJECT(wfdrtspsrc), "hdcp-param", hdcp_param, NULL);
 
-       g_signal_connect (wfdrtspsrc, "receive-M4-request",
+       g_signal_connect (wfdrtspsrc, "update-media-info",
                G_CALLBACK(__mm_wfd_sink_update_stream_info), wfd_sink);
 
        g_signal_connect (wfdrtspsrc, "change-av-format",
                G_CALLBACK(__mm_wfd_sink_change_av_format), wfd_sink);
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 }
 
 static int __mm_wfd_sink_prepare_demux(mm_wfd_sink_t *wfd_sink, GstElement *demux)
 {
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-       return_val_if_fail (demux, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (demux, MM_ERROR_WFD_NOT_INITIALIZED);
 
-       g_signal_connect (demux, "pad-added", G_CALLBACK(__mm_wfd_sink_demux_pad_added), wfd_sink);
+       g_signal_connect (demux, "pad-added",
+               G_CALLBACK(__mm_wfd_sink_demux_pad_added),      wfd_sink);
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 }
@@ -1547,10 +1890,10 @@ static int __mm_wfd_sink_create_pipeline(mm_wfd_sink_t *wfd_sink)
        GstBus  *bus = NULL;
        int i;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-       return_val_if_fail (wfd_sink->attrs, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+       wfd_sink_return_val_if_fail (wfd_sink->attrs, MM_ERROR_WFD_NOT_INITIALIZED);
 
        /* Create pipeline */
        wfd_sink->pipeline = (MMWFDSinkGstPipelineInfo*) g_malloc0 (sizeof(MMWFDSinkGstPipelineInfo));
@@ -1571,17 +1914,20 @@ static int __mm_wfd_sink_create_pipeline(mm_wfd_sink_t *wfd_sink)
        mainbin[WFD_SINK_M_PIPE].gst = gst_pipeline_new ("wfdsink");
        if (!mainbin[WFD_SINK_M_PIPE].gst)
        {
-               debug_error ("failed to create pipeline\n");
+               wfd_sink_error ("failed to create pipeline\n");
                goto CREATE_ERROR;
        }
 
        /* create wfdrtspsrc */
        MMWFDSINK_CREATE_ELEMENT(mainbin, WFD_SINK_M_SRC, "wfdrtspsrc", "wfdsink_source", TRUE);
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, mainbin[WFD_SINK_M_SRC].gst,  "src" );
-       if (MM_ERROR_NONE != __mm_wfd_sink_prepare_wfdrtspsrc (wfd_sink, mainbin[WFD_SINK_M_SRC].gst))
+       if (mainbin[WFD_SINK_M_SRC].gst)
        {
-               debug_error ("failed to prepare wfdrtspsrc...\n");
-               goto CREATE_ERROR;
+               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_wfdrtspsrc (wfd_sink, mainbin[WFD_SINK_M_SRC].gst))
+               {
+                       wfd_sink_error ("failed to prepare wfdrtspsrc...\n");
+                       goto CREATE_ERROR;
+               }
        }
 
        /* create rtpmp2tdepay */
@@ -1594,25 +1940,26 @@ static int __mm_wfd_sink_create_pipeline(mm_wfd_sink_t *wfd_sink)
        /* create tsdemuxer*/
        MMWFDSINK_CREATE_ELEMENT (mainbin, WFD_SINK_M_DEMUX, wfd_sink->ini.name_of_tsdemux, "wfdsink_demux", TRUE);
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, mainbin[WFD_SINK_M_DEMUX].gst, "sink" );
-       if (MM_ERROR_NONE != __mm_wfd_sink_prepare_demux (wfd_sink, mainbin[WFD_SINK_M_DEMUX].gst))
+       if (mainbin[WFD_SINK_M_DEMUX].gst)
        {
-               debug_error ("failed to prepare demux...\n");
-               goto CREATE_ERROR;
+               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_demux (wfd_sink, mainbin[WFD_SINK_M_DEMUX].gst))
+               {
+                       wfd_sink_error ("failed to prepare demux...\n");
+                       goto CREATE_ERROR;
+               }
        }
 
        /* adding created elements to pipeline */
-       debug_error("No-error: try to add created elements to pipeline\n");
        if( !__mm_wfd_sink_gst_element_add_bucket_to_bin (GST_BIN_CAST(mainbin[WFD_SINK_M_PIPE].gst), element_bucket, FALSE))
        {
-               debug_error ("failed to add elements\n");
+               wfd_sink_error ("failed to add elements\n");
                goto CREATE_ERROR;
        }
 
        /* linking elements in the bucket by added order. */
-       debug_error("No-error: try to link elements in the bucket by added order.\n");
        if ( __mm_wfd_sink_gst_element_link_bucket (element_bucket) == -1 )
        {
-               debug_error("failed to link elements\n");
+               wfd_sink_error("failed to link elements\n");
                goto CREATE_ERROR;
        }
 
@@ -1620,7 +1967,7 @@ static int __mm_wfd_sink_create_pipeline(mm_wfd_sink_t *wfd_sink)
        bus = gst_pipeline_get_bus (GST_PIPELINE(mainbin[WFD_SINK_M_PIPE].gst));
        if (!bus)
        {
-               debug_error ("cannot get bus from pipeline.\n");
+               wfd_sink_error ("cannot get bus from pipeline.\n");
                goto CREATE_ERROR;
        }
 
@@ -1636,13 +1983,13 @@ static int __mm_wfd_sink_create_pipeline(mm_wfd_sink_t *wfd_sink)
        /* now we have completed mainbin. take it */
        wfd_sink->pipeline->mainbin = mainbin;
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 
 /* ERRORS */
 CREATE_ERROR:
-       debug_error("ERROR : releasing pipeline\n");
+       wfd_sink_error("ERROR : releasing pipeline\n");
 
        if (element_bucket)
                g_list_free (element_bucket);
@@ -1696,20 +2043,20 @@ int __mm_wfd_sink_link_audiobin(mm_wfd_sink_t *wfd_sink)
        GstPad *sinkpad = NULL;
        GstPad *srcpad = NULL;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink &&
+       wfd_sink_return_val_if_fail (wfd_sink &&
                wfd_sink->pipeline &&
                wfd_sink->pipeline->audiobin &&
                wfd_sink->pipeline->audiobin[WFD_SINK_A_BIN].gst,
                MM_ERROR_WFD_NOT_INITIALIZED );
-       return_val_if_fail (wfd_sink->prev_audio_dec_src_pad &&
+       wfd_sink_return_val_if_fail (wfd_sink->prev_audio_dec_src_pad &&
                wfd_sink->next_audio_dec_sink_pad,
                MM_ERROR_WFD_INTERNAL);
 
        if (wfd_sink->audio_bin_is_linked)
        {
-               debug_error ("No-error : audiobin is already linked... nothing to do\n");
+               wfd_sink_debug ("audiobin is already linked... nothing to do\n");
                return MM_ERROR_NONE;
        }
 
@@ -1742,35 +2089,33 @@ int __mm_wfd_sink_link_audiobin(mm_wfd_sink_t *wfd_sink)
                        break;
 
                default:
-                       debug_error("audio type is not decied yet. cannot link audio decoder...\n");
+                       wfd_sink_error("audio type is not decied yet. cannot link audio decoder...\n");
                        return MM_ERROR_WFD_INTERNAL;
                        break;
        }
 
        if (!element_bucket)
        {
-               debug_error ("No-error: there is no additional elements to be linked... just link audiobin.\n");
+               wfd_sink_debug ("there is no additional elements to be linked... just link audiobin.\n");
                if (GST_PAD_LINK_OK != gst_pad_link_full(wfd_sink->prev_audio_dec_src_pad, wfd_sink->next_audio_dec_sink_pad, GST_PAD_LINK_CHECK_NOTHING))
                {
-                       debug_error("failed to link audiobin....\n");
+                       wfd_sink_error("failed to link audiobin....\n");
                        goto fail_to_link;
                }
                goto done;
        }
 
        /* adding elements to audiobin */
-       debug_error("No-error: try to add elements to audiobin\n");
        if( !__mm_wfd_sink_gst_element_add_bucket_to_bin (GST_BIN_CAST(audiobin[WFD_SINK_A_BIN].gst), element_bucket, FALSE))
        {
-               debug_error ("failed to add elements to audiobin\n");
+               wfd_sink_error ("failed to add elements to audiobin\n");
                goto fail_to_link;
        }
 
        /* linking elements in the bucket by added order. */
-       debug_error("No-error: try to link elements in the bucket by added order.\n");
        if ( __mm_wfd_sink_gst_element_link_bucket (element_bucket) == -1 )
        {
-               debug_error("failed to link elements\n");
+               wfd_sink_error("failed to link elements\n");
                goto fail_to_link;
        }
 
@@ -1778,20 +2123,20 @@ int __mm_wfd_sink_link_audiobin(mm_wfd_sink_t *wfd_sink)
        first_element = (MMWFDSinkGstElement *)g_list_nth_data(element_bucket, 0);
        if (!first_element)
        {
-               debug_error("failed to get first element to be linked....\n");
+               wfd_sink_error("failed to get first element to be linked....\n");
                goto fail_to_link;
        }
 
        sinkpad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
        if (!sinkpad)
        {
-               debug_error("failed to get sink pad from element(%s)\n", GST_ELEMENT_NAME(first_element->gst));
+               wfd_sink_error("failed to get sink pad from element(%s)\n", GST_ELEMENT_NAME(first_element->gst));
                goto fail_to_link;
        }
 
        if (GST_PAD_LINK_OK != gst_pad_link_full(wfd_sink->prev_audio_dec_src_pad, sinkpad, GST_PAD_LINK_CHECK_NOTHING))
        {
-               debug_error("failed to link audiobin....\n");
+               wfd_sink_error("failed to link audiobin....\n");
                goto fail_to_link;
        }
 
@@ -1803,20 +2148,20 @@ int __mm_wfd_sink_link_audiobin(mm_wfd_sink_t *wfd_sink)
        last_element = (MMWFDSinkGstElement *)g_list_nth_data(element_bucket, g_list_length(element_bucket)-1);
        if (!last_element)
        {
-               debug_error("failed to get last element to be linked....\n");
+               wfd_sink_error("failed to get last element to be linked....\n");
                goto fail_to_link;
        }
 
        srcpad = gst_element_get_static_pad(GST_ELEMENT(last_element->gst), "src");
        if (!srcpad)
        {
-               debug_error("failed to get src pad from element(%s)\n", GST_ELEMENT_NAME(last_element->gst));
+               wfd_sink_error("failed to get src pad from element(%s)\n", GST_ELEMENT_NAME(last_element->gst));
                goto fail_to_link;
        }
 
        if (GST_PAD_LINK_OK != gst_pad_link_full(srcpad, wfd_sink->next_audio_dec_sink_pad, GST_PAD_LINK_CHECK_NOTHING))
        {
-               debug_error("failed to link audiobin....\n");
+               wfd_sink_error("failed to link audiobin....\n");
                goto fail_to_link;
        }
 
@@ -1828,7 +2173,7 @@ int __mm_wfd_sink_link_audiobin(mm_wfd_sink_t *wfd_sink)
 done:
        wfd_sink->audio_bin_is_linked = TRUE;
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 
@@ -1847,6 +2192,125 @@ fail_to_link:
        return MM_ERROR_WFD_INTERNAL;
 }
 
+static int __mm_wfd_sink_prepare_audiosink(mm_wfd_sink_t *wfd_sink, GstElement *audio_sink)
+{
+       wfd_sink_debug_fenter();
+
+       /* check audiosink is created */
+       wfd_sink_return_val_if_fail (audio_sink, MM_ERROR_WFD_INVALID_ARGUMENT);
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
+
+       g_object_set (G_OBJECT(audio_sink), "provide-clock", FALSE,  NULL);
+       g_object_set (G_OBJECT(audio_sink), "buffer-time", 100000LL, NULL);
+       g_object_set (G_OBJECT(audio_sink), "query-position-support", FALSE,  NULL);
+       g_object_set (G_OBJECT(audio_sink), "slave-method", 2,  NULL);
+       g_object_set (G_OBJECT(audio_sink), "async", wfd_sink->ini.audio_sink_async,  NULL);
+       g_object_set (G_OBJECT(audio_sink), "ts-offset", (gint64)wfd_sink->ini.sink_ts_offset, NULL );
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static void
+__mm_wfd_sink_queue_overrun (GstElement* element, gpointer u_data)
+{
+        debug_fenter();
+
+        return_if_fail(element);
+
+        wfd_sink_warning ("%s is overrun\n",
+                       GST_STR_NULL(GST_ELEMENT_NAME(element)));
+
+        debug_fleave();
+
+        return;
+}
+
+static int  __mm_wfd_sink_destroy_audiobin(mm_wfd_sink_t* wfd_sink)
+{
+       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+       MMWFDSinkGstElement* audiobin = NULL;
+       GstObject* parent = NULL;
+       int i;
+
+       wfd_sink_debug_fenter ();
+
+       wfd_sink_return_val_if_fail (wfd_sink,
+               MM_ERROR_WFD_NOT_INITIALIZED);
+
+       if (wfd_sink->pipeline &&
+               wfd_sink->pipeline->audiobin &&
+               wfd_sink->pipeline->audiobin[WFD_SINK_A_BIN].gst)
+       {
+               audiobin = wfd_sink->pipeline->audiobin;
+       }
+       else
+       {
+               wfd_sink_debug("audiobin is not created, nothing to destroy\n");
+               return MM_ERROR_NONE;
+       }
+
+
+       parent = gst_element_get_parent (audiobin[WFD_SINK_A_BIN].gst);
+       if (!parent)
+       {
+               wfd_sink_debug("audiobin has no parent.. need to relase by itself\n");
+
+               if (GST_STATE(audiobin[WFD_SINK_A_BIN].gst)>=GST_STATE_READY)
+               {
+                       wfd_sink_debug("try to change state of audiobin to NULL\n");
+                       ret = gst_element_set_state (audiobin[WFD_SINK_A_BIN].gst, GST_STATE_NULL);
+                       if ( ret != GST_STATE_CHANGE_SUCCESS )
+                       {
+                               wfd_sink_error("failed to change state of audiobin to NULL\n");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+               }
+
+               /* release element which are not added to bin */
+               for (i = 1; i < WFD_SINK_A_NUM; i++)    /* NOTE : skip bin */
+               {
+                       if (audiobin[i].gst)
+                       {
+                               parent = gst_element_get_parent (audiobin[i].gst);
+                               if (!parent)
+                               {
+                                       wfd_sink_debug("unref %s(current ref %d)\n",
+                                               GST_STR_NULL(GST_ELEMENT_NAME(audiobin[i].gst)),
+                                               ((GObject *) audiobin[i].gst)->ref_count);
+                                       gst_object_unref(GST_OBJECT(audiobin[i].gst));
+                                       audiobin[i].gst = NULL;
+                               }
+                               else
+                               {
+                                       wfd_sink_debug("unref %s(current ref %d)\n",
+                                               GST_STR_NULL(GST_ELEMENT_NAME(audiobin[i].gst)),
+                                               ((GObject *) audiobin[i].gst)->ref_count);
+                                       gst_object_unref(GST_OBJECT(parent));
+                               }
+                       }
+               }
+
+               /* release audiobin with it's childs */
+               if (audiobin[WFD_SINK_A_BIN].gst )
+               {
+                       gst_object_unref (GST_OBJECT(audiobin[WFD_SINK_A_BIN].gst));
+               }
+       }
+       else
+       {
+               wfd_sink_debug("audiobin has parent (%s), unref it \n",
+                       GST_STR_NULL(GST_OBJECT_NAME(GST_OBJECT(parent))));
+
+               gst_object_unref (GST_OBJECT(parent));
+       }
+
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
 static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
 {
        MMWFDSinkGstElement* audiobin = NULL;
@@ -1858,9 +2322,9 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
        GstCaps *caps = NULL;
        gint i;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink &&
+       wfd_sink_return_val_if_fail (wfd_sink &&
                wfd_sink->pipeline &&
                wfd_sink->pipeline->mainbin,
                MM_ERROR_WFD_NOT_INITIALIZED );
@@ -1869,7 +2333,7 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
        audiobin = (MMWFDSinkGstElement*)g_malloc0(sizeof(MMWFDSinkGstElement) * WFD_SINK_A_NUM);
        if (!audiobin)
        {
-               debug_error ("failed to allocate memory for audiobin\n");
+               wfd_sink_error ("failed to allocate memory for audiobin\n");
                return MM_ERROR_WFD_NO_FREE_SPACE;
        }
 
@@ -1878,7 +2342,7 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
        audiobin[WFD_SINK_A_BIN].gst = gst_bin_new("audiobin");
        if ( !audiobin[WFD_SINK_A_BIN].gst )
        {
-               debug_error ("failed to create audiobin\n");
+               wfd_sink_error ("failed to create audiobin\n");
                goto CREATE_ERROR;
        }
 
@@ -1896,7 +2360,7 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
                        break;
                case WFD_SINK_AUDIO_CODEC_NONE:
                default:
-                       debug_error ("No-error: audio decoder could NOT be linked now, just prepare.\n");
+                       wfd_sink_debug ("audio decoder could NOT be linked now, just prepare.\n");
                        audio_codec = wfd_sink->ini.audio_codec;
                        link_audio_dec = FALSE;
                        break;
@@ -1910,13 +2374,20 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
        MMWFDSINK_CREATE_ELEMENT (audiobin, WFD_SINK_A_QUEUE, "queue", "audio_queue", link_audio_dec);
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, audiobin[WFD_SINK_A_QUEUE].gst,  "sink" );
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, audiobin[WFD_SINK_A_QUEUE].gst,  "src" );
-       g_object_set (G_OBJECT(wfd_sink->pipeline->mainbin[WFD_SINK_M_SRC].gst), "audio-queue-handle", audiobin[WFD_SINK_A_QUEUE].gst, NULL);
-
+       if (audiobin[WFD_SINK_A_QUEUE].gst)
+       {
+               g_object_set(G_OBJECT (audiobin[WFD_SINK_A_QUEUE].gst), "max-size-bytes", 0, NULL);
+               g_object_set(G_OBJECT (audiobin[WFD_SINK_A_QUEUE].gst), "max-size-buffers", 0, NULL);
+               g_object_set(G_OBJECT (audiobin[WFD_SINK_A_QUEUE].gst), "max-size-time", (guint64)3000000000ULL, NULL);
+               g_signal_connect (audiobin[WFD_SINK_A_QUEUE].gst, "overrun",
+                       G_CALLBACK(__mm_wfd_sink_queue_overrun), wfd_sink);
+       }
        if (!link_audio_dec)
        {
                if (!gst_bin_add (GST_BIN_CAST(audiobin[WFD_SINK_A_BIN].gst), audiobin[WFD_SINK_A_QUEUE].gst))
                {
-                       debug_error("failed to add %s to audiobin\n", GST_ELEMENT_NAME(audiobin[WFD_SINK_A_QUEUE].gst));
+                       wfd_sink_error("failed to add %s to audiobin\n",
+                               GST_STR_NULL(GST_ELEMENT_NAME(audiobin[WFD_SINK_A_QUEUE].gst)));
                        goto CREATE_ERROR;
                }
 
@@ -1924,15 +2395,16 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
                {
                        if (!gst_bin_add (GST_BIN_CAST(audiobin[WFD_SINK_A_BIN].gst), audiobin[WFD_SINK_A_HDCP].gst))
                        {
-                               debug_error("failed to add %s to audiobin\n", GST_ELEMENT_NAME(audiobin[WFD_SINK_A_HDCP].gst));
+                               wfd_sink_error("failed to add %s to audiobin\n",
+                                       GST_STR_NULL(GST_ELEMENT_NAME(audiobin[WFD_SINK_A_HDCP].gst)));
                                goto CREATE_ERROR;
                        }
 
                        if (!gst_element_link (audiobin[WFD_SINK_A_QUEUE].gst, audiobin[WFD_SINK_A_HDCP].gst) )
                        {
-                               debug_error("failed to link [%s] to [%s] success\n",
-                                       GST_ELEMENT_NAME(audiobin[WFD_SINK_A_QUEUE].gst),
-                                       GST_ELEMENT_NAME(audiobin[WFD_SINK_A_HDCP].gst) );
+                               wfd_sink_error("failed to link [%s] to [%s] success\n",
+                                       GST_STR_NULL(GST_ELEMENT_NAME(audiobin[WFD_SINK_A_QUEUE].gst)),
+                                       GST_STR_NULL(GST_ELEMENT_NAME(audiobin[WFD_SINK_A_HDCP].gst)));
                                goto CREATE_ERROR;
                        }
 
@@ -1945,11 +2417,11 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
 
                if (!wfd_sink->prev_audio_dec_src_pad)
                {
-                       debug_error ("failed to get src pad from previous element of audio decoder\n");
+                       wfd_sink_error ("failed to get src pad from previous element of audio decoder\n");
                        goto CREATE_ERROR;
                }
 
-               debug_error ("No-error: take src pad from previous element of audio decoder for linking\n");
+               wfd_sink_debug ("take src pad from previous element of audio decoder for linking\n");
        }
 
        if (audio_codec & WFD_AUDIO_LPCM)
@@ -1963,15 +2435,16 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
                MMWFDSINK_CREATE_ELEMENT (audiobin, WFD_SINK_A_LPCM_FILTER, wfd_sink->ini.name_of_lpcm_filter, "audio_lpcm_filter", link_audio_dec);
                MMWFDSINK_PAD_PROBE( wfd_sink, NULL, audiobin[WFD_SINK_A_LPCM_FILTER].gst,  "sink" );
                MMWFDSINK_PAD_PROBE( wfd_sink, NULL, audiobin[WFD_SINK_A_LPCM_FILTER].gst,  "src" );
-               caps = gst_caps_new_simple("audio/x-raw-int",
-                               "rate", G_TYPE_INT, 48000,
-                               "channels", G_TYPE_INT, 2,
-                               "depth", G_TYPE_INT, 16,
-                               "width", G_TYPE_INT, 16,
-                               "signed", G_TYPE_BOOLEAN, TRUE,
-                               "endianness", G_TYPE_INT, 1234, NULL);
-               g_object_set (G_OBJECT(audiobin[WFD_SINK_A_LPCM_FILTER].gst), "caps", caps, NULL);
-               gst_object_unref (GST_OBJECT(caps));
+               if (audiobin[WFD_SINK_A_LPCM_FILTER].gst)
+               {
+                       caps = gst_caps_new_simple("audio/x-raw",
+                                       "rate", G_TYPE_INT, 48000,
+                                       "channels", G_TYPE_INT, 2,
+                                       "format", G_TYPE_STRING, "S16LE", NULL);
+
+                       g_object_set (G_OBJECT(audiobin[WFD_SINK_A_LPCM_FILTER].gst), "caps", caps, NULL);
+                       gst_object_unref (GST_OBJECT(caps));
+               }
        }
 
        if (audio_codec & WFD_AUDIO_AAC )
@@ -2010,26 +2483,25 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, audiobin[WFD_SINK_A_VOLUME].gst,  "sink" );
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, audiobin[WFD_SINK_A_VOLUME].gst,  "src" );
 
-  //TODO gstreamer-1.0 alsasink does not want process not S16LE format.
+       //TODO gstreamer-1.0 alsasink does not want process not S16LE format.
        MMWFDSINK_CREATE_ELEMENT (audiobin, WFD_SINK_A_CAPSFILTER, "capsfilter", "audio_capsfilter", TRUE);
-       caps = gst_caps_from_string("audio/x-raw, format=(string)S16LE");
-       g_object_set (G_OBJECT(audiobin[WFD_SINK_A_CAPSFILTER].gst), "caps", caps, NULL);
-       gst_caps_unref (caps);
+       if (audiobin[WFD_SINK_A_CAPSFILTER].gst)
+       {
+               caps = gst_caps_from_string("audio/x-raw, format=(string)S16LE");
+               g_object_set (G_OBJECT(audiobin[WFD_SINK_A_CAPSFILTER].gst), "caps", caps, NULL);
+               gst_caps_unref (caps);
+       }
 
        /* create sink */
        MMWFDSINK_CREATE_ELEMENT (audiobin, WFD_SINK_A_SINK, wfd_sink->ini.name_of_audio_sink, "audio_sink", TRUE);
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, audiobin[WFD_SINK_A_SINK].gst,  "sink" );
-
-       g_object_set (G_OBJECT(audiobin[WFD_SINK_A_SINK].gst), "provide-clock", FALSE,  NULL);
-       g_object_set (G_OBJECT(audiobin[WFD_SINK_A_SINK].gst), "buffer-time", 100000LL, NULL);
-       //g_object_set (G_OBJECT(audiobin[WFD_SINK_A_SINK].gst), "async", FALSE,  NULL);
-       g_object_set (G_OBJECT(audiobin[WFD_SINK_A_SINK].gst), "query-position-support", FALSE,  NULL);
-
-       if (g_str_equal(wfd_sink->ini.name_of_audio_sink, "alsasink"))
+       if (audiobin[WFD_SINK_A_SINK].gst)
        {
-               g_object_set (G_OBJECT (audiobin[WFD_SINK_A_SINK].gst), "device", "hw:0,0", NULL);
-
-               debug_error("No-error: set device hw0:0 for alsasink");
+               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_audiosink(wfd_sink, audiobin[WFD_SINK_A_SINK].gst))
+               {
+                       wfd_sink_error ("failed to set audio sink property....\n");
+                       goto CREATE_ERROR;
+               }
        }
 
        if (!link_audio_dec)
@@ -2039,33 +2511,31 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
                first_element = (MMWFDSinkGstElement *)g_list_nth_data(element_bucket, 0);
                if (!first_element)
                {
-                       debug_error("failed to get first element\n");
+                       wfd_sink_error("failed to get first element\n");
                        goto CREATE_ERROR;
                }
 
                wfd_sink->next_audio_dec_sink_pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
                if (!wfd_sink->next_audio_dec_sink_pad)
                {
-                       debug_error("failed to get sink pad from next element of audio decoder\n");
+                       wfd_sink_error("failed to get sink pad from next element of audio decoder\n");
                        goto CREATE_ERROR;
                }
 
-               debug_error ("No-error: take sink pad from next element of audio decoder for linking\n");
+               wfd_sink_debug ("take sink pad from next element of audio decoder for linking\n");
        }
 
        /* adding created elements to audiobin */
-       debug_error("No-error: adding created elements to audiobin\n");
        if( !__mm_wfd_sink_gst_element_add_bucket_to_bin (GST_BIN_CAST(audiobin[WFD_SINK_A_BIN].gst), element_bucket, FALSE))
        {
-               debug_error ("failed to add elements\n");
+               wfd_sink_error ("failed to add elements\n");
                goto CREATE_ERROR;
        }
 
        /* linking elements in the bucket by added order. */
-       debug_error("No-error: Linking elements in the bucket by added order.\n");
        if ( __mm_wfd_sink_gst_element_link_bucket (element_bucket) == -1 )
        {
-               debug_error("failed to link elements\n");
+               wfd_sink_error("failed to link elements\n");
                goto CREATE_ERROR;
        }
 
@@ -2073,20 +2543,20 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
        pad = gst_element_get_static_pad(audiobin[WFD_SINK_A_QUEUE].gst, "sink");
        if (!pad)
        {
-               debug_error("failed to get pad from queue of audiobin\n");
+               wfd_sink_error("failed to get pad from queue of audiobin\n");
                goto CREATE_ERROR;
        }
 
        ghostpad = gst_ghost_pad_new ("sink", pad);
        if (!ghostpad)
        {
-               debug_error("failed to create ghostpad\n");
+               wfd_sink_error("failed to create ghostpad\n");
                goto CREATE_ERROR;
        }
 
        if (FALSE == gst_element_add_pad (audiobin[WFD_SINK_A_BIN].gst, ghostpad) )
        {
-               debug_error("failed to add ghostpad to audiobin\n");
+               wfd_sink_error("failed to add ghostpad to audiobin\n");
                goto CREATE_ERROR;
        }
 
@@ -2097,12 +2567,12 @@ static int __mm_wfd_sink_create_audiobin(mm_wfd_sink_t *wfd_sink)
        /* take it */
        wfd_sink->pipeline->audiobin = audiobin;
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 
 CREATE_ERROR:
-       debug_error("ERROR : releasing audiobin\n");
+       wfd_sink_error("failed to create audiobin, releasing all\n");
 
        if (wfd_sink->next_audio_dec_sink_pad)
                gst_object_unref (GST_OBJECT(wfd_sink->next_audio_dec_sink_pad));
@@ -2125,30 +2595,7 @@ CREATE_ERROR:
        element_bucket = NULL;
 
        /* release element which are not added to bin */
-       for (i = 1; i < WFD_SINK_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[WFD_SINK_A_BIN].gst )
-       {
-               gst_object_unref (GST_OBJECT(audiobin[WFD_SINK_A_BIN].gst));
-       }
+       __mm_wfd_sink_destroy_audiobin(wfd_sink);
 
        MMWFDSINK_FREEIF (audiobin);
 
@@ -2157,16 +2604,15 @@ CREATE_ERROR:
 
 static int __mm_wfd_sink_prepare_videodec(mm_wfd_sink_t *wfd_sink, GstElement *video_dec)
 {
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
        /* check video decoder is created */
-       return_val_if_fail ( video_dec, MM_ERROR_WFD_INVALID_ARGUMENT );
-       return_val_if_fail ( wfd_sink && wfd_sink->attrs, MM_ERROR_WFD_NOT_INITIALIZED );
+       wfd_sink_return_val_if_fail ( video_dec, MM_ERROR_WFD_INVALID_ARGUMENT );
+       wfd_sink_return_val_if_fail ( wfd_sink && wfd_sink->attrs, MM_ERROR_WFD_NOT_INITIALIZED );
 
-       g_object_set (G_OBJECT(video_dec), "decoding-type", 1, NULL );
        g_object_set (G_OBJECT(video_dec), "error-concealment", TRUE, NULL );
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 }
@@ -2177,17 +2623,17 @@ static int __mm_wfd_sink_prepare_videosink(mm_wfd_sink_t *wfd_sink, GstElement *
        gint surface_type = MM_DISPLAY_SURFACE_X;
        gulong xid = 0;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
        /* check videosink is created */
-       return_val_if_fail ( video_sink, MM_ERROR_WFD_INVALID_ARGUMENT );
-       return_val_if_fail ( wfd_sink && wfd_sink->attrs, MM_ERROR_WFD_NOT_INITIALIZED );
+       wfd_sink_return_val_if_fail ( video_sink, MM_ERROR_WFD_INVALID_ARGUMENT );
+       wfd_sink_return_val_if_fail ( wfd_sink && wfd_sink->attrs, MM_ERROR_WFD_NOT_INITIALIZED );
 
        /* update display surface */
 //     mm_attrs_get_int_by_name(wfd_sink->attrs, "display_surface_type", &surface_type);
-       debug_error("No-error: check display surface type attribute: %d", surface_type);
+       wfd_sink_debug("check display surface type attribute: %d", surface_type);
        mm_attrs_get_int_by_name(wfd_sink->attrs, "display_visible", &visible);
-       debug_error("No-error: check display visible attribute: %d", visible);
+       wfd_sink_debug("check display visible attribute: %d", visible);
 
        /* configuring display */
        switch ( surface_type )
@@ -2202,12 +2648,12 @@ static int __mm_wfd_sink_prepare_videosink(mm_wfd_sink_t *wfd_sink, GstElement *
                        mm_attrs_get_int_by_name(wfd_sink->attrs, "display_evas_do_scaling", &scaling);
                        if (object)
                        {
-                               debug_error("No-error: set video param : evas-object %x", object);
+                               wfd_sink_debug("set video param : evas-object %x", object);
                                g_object_set(G_OBJECT(video_sink), "evas-object", object, NULL);
                        }
                        else
                        {
-                               debug_error("no evas object");
+                               wfd_sink_error("no evas object");
                                return MM_ERROR_WFD_INTERNAL;
                        }
                }
@@ -2222,12 +2668,12 @@ static int __mm_wfd_sink_prepare_videosink(mm_wfd_sink_t *wfd_sink, GstElement *
                        if (object)
                        {
                                xid = *object;
-                               debug_error("No-error: xid = %lu )", xid);
+                               wfd_sink_debug("xid = %lu", xid);
                                gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(video_sink), xid);
                        }
                        else
                        {
-                               debug_error("Handle is NULL. Set xid as 0.. but, it's not recommended.");
+                               wfd_sink_warning("Handle is NULL. Set xid as 0.. but, it's not recommended.");
                                gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(video_sink), 0);
                        }
                }
@@ -2236,19 +2682,100 @@ static int __mm_wfd_sink_prepare_videosink(mm_wfd_sink_t *wfd_sink, GstElement *
                case MM_DISPLAY_SURFACE_NULL:
                {
                        /* do nothing */
-                       debug_error("Not Supported Surface.");
+                       wfd_sink_error("Not Supported Surface.");
                        return MM_ERROR_WFD_INTERNAL;
                }
                break;
        }
 
        g_object_set (G_OBJECT(video_sink), "qos", FALSE, NULL );
-       //g_object_set (G_OBJECT(video_sink), "async", FALSE, NULL);
+       g_object_set (G_OBJECT(video_sink), "async", wfd_sink->ini.video_sink_async, NULL);
        g_object_set (G_OBJECT(video_sink), "max-lateness", (gint64)wfd_sink->ini.video_sink_max_lateness, NULL );
-       g_object_set(G_OBJECT(video_sink), "visible", visible, NULL);
-       debug_error("No-error: set video param : visible %d", visible);
+       g_object_set (G_OBJECT(video_sink), "visible", visible, NULL);
+       g_object_set (G_OBJECT(video_sink), "ts-offset", (gint64)(wfd_sink->ini.sink_ts_offset), NULL );
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+static int __mm_wfd_sink_destroy_videobin(mm_wfd_sink_t* wfd_sink)
+{
+       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+       MMWFDSinkGstElement* videobin = NULL;
+       GstObject* parent = NULL;
+       int i;
+
+       wfd_sink_debug_fenter ();
+
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED );
+
+       if (wfd_sink->pipeline &&
+               wfd_sink->pipeline->videobin &&
+               wfd_sink->pipeline->videobin[WFD_SINK_V_BIN].gst)
+       {
+               videobin = wfd_sink->pipeline->videobin;
+       }
+       else
+       {
+               wfd_sink_debug("videobin is not created, nothing to destroy\n");
+               return MM_ERROR_NONE;
+       }
+
+
+       parent = gst_element_get_parent (videobin[WFD_SINK_V_BIN].gst);
+       if (!parent)
+       {
+               wfd_sink_debug("videobin has no parent.. need to relase by itself\n");
+
+               if (GST_STATE(videobin[WFD_SINK_V_BIN].gst) >= GST_STATE_READY)
+               {
+                       wfd_sink_debug("try to change state of videobin to NULL\n");
+                       ret = gst_element_set_state (videobin[WFD_SINK_V_BIN].gst, GST_STATE_NULL);
+                       if ( ret != GST_STATE_CHANGE_SUCCESS )
+                       {
+                               wfd_sink_error("failed to change state of videobin to NULL\n");
+                               return MM_ERROR_WFD_INTERNAL;
+                       }
+               }
+               /* release element which are not added to bin */
+               for (i = 1; i < WFD_SINK_V_NUM; i++)    /* NOTE : skip bin */
+               {
+                       if (videobin[i].gst)
+                       {
+                               parent = gst_element_get_parent (videobin[i].gst);
+                               if (!parent)
+                               {
+                                       wfd_sink_debug("unref %s(current ref %d)\n",
+                                               GST_STR_NULL(GST_ELEMENT_NAME(videobin[i].gst)),
+                                               ((GObject *) videobin[i].gst)->ref_count);
+                                       gst_object_unref(GST_OBJECT(videobin[i].gst));
+                                       videobin[i].gst = NULL;
+                               }
+                               else
+                               {
+                                       wfd_sink_debug("unref %s(current ref %d)\n",
+                                               GST_STR_NULL(GST_ELEMENT_NAME(videobin[i].gst)),
+                                               ((GObject *) videobin[i].gst)->ref_count);
+                                       gst_object_unref(GST_OBJECT(parent));
+                               }
+                       }
+               }
+               /* release audiobin with it's childs */
+               if (videobin[WFD_SINK_V_BIN].gst )
+               {
+                       gst_object_unref (GST_OBJECT(videobin[WFD_SINK_V_BIN].gst));
+               }
+       }
+       else
+       {
+               wfd_sink_debug("videobin has parent (%s), unref it \n",
+                       GST_STR_NULL(GST_OBJECT_NAME(GST_OBJECT(parent))));
+
+               gst_object_unref (GST_OBJECT(parent));
+       }
+
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 }
@@ -2263,9 +2790,9 @@ static int __mm_wfd_sink_create_videobin(mm_wfd_sink_t *wfd_sink)
        GstPad *ghostpad = NULL;
        gint i = 0;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_val_if_fail (wfd_sink &&
+       wfd_sink_return_val_if_fail (wfd_sink &&
                wfd_sink->pipeline &&
                wfd_sink->pipeline->mainbin,
                MM_ERROR_WFD_NOT_INITIALIZED );
@@ -2274,7 +2801,7 @@ static int __mm_wfd_sink_create_videobin(mm_wfd_sink_t *wfd_sink)
        videobin = (MMWFDSinkGstElement*)g_malloc0(sizeof(MMWFDSinkGstElement) * WFD_SINK_V_NUM);
        if (!videobin )
        {
-               debug_error ("failed to allocate memory for videobin\n");
+               wfd_sink_error ("failed to allocate memory for videobin\n");
                return MM_ERROR_WFD_NO_FREE_SPACE;
        }
 
@@ -2283,7 +2810,7 @@ static int __mm_wfd_sink_create_videobin(mm_wfd_sink_t *wfd_sink)
        videobin[WFD_SINK_V_BIN].gst = gst_bin_new("videobin");
        if ( !videobin[WFD_SINK_V_BIN].gst )
        {
-               debug_error ("failed to create videobin\n");
+               wfd_sink_error ("failed to create videobin\n");
                goto CREATE_ERROR;
        }
 
@@ -2292,45 +2819,58 @@ static int __mm_wfd_sink_create_videobin(mm_wfd_sink_t *wfd_sink)
        MMWFDSINK_CREATE_ELEMENT (videobin, WFD_SINK_V_QUEUE, "queue", "video_queue", TRUE);
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, videobin[WFD_SINK_V_QUEUE].gst,  "sink" );
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, videobin[WFD_SINK_V_QUEUE].gst,  "src" );
+       if (videobin[WFD_SINK_V_QUEUE].gst)
+       {
+               g_object_set(G_OBJECT (videobin[WFD_SINK_V_QUEUE].gst), "max-size-bytes", 0, NULL);
+               g_object_set(G_OBJECT (videobin[WFD_SINK_V_QUEUE].gst), "max-size-buffers", 0, NULL);
+               g_object_set(G_OBJECT (videobin[WFD_SINK_V_QUEUE].gst), "max-size-time", (guint64)3000000000ULL, NULL);
+               g_signal_connect (videobin[WFD_SINK_V_QUEUE].gst, "overrun",
+                       G_CALLBACK(__mm_wfd_sink_queue_overrun), wfd_sink);
+       }
 
        /* create parser */
        MMWFDSINK_CREATE_ELEMENT (videobin, WFD_SINK_V_PARSE, wfd_sink->ini.name_of_video_parser, "video_parser", TRUE);
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, videobin[WFD_SINK_V_PARSE].gst,  "sink" );
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, videobin[WFD_SINK_V_PARSE].gst,  "src" );
-       g_object_set (G_OBJECT(videobin[WFD_SINK_V_PARSE].gst), "wfd-mode", TRUE, NULL );
+       if (videobin[WFD_SINK_V_PARSE].gst)
+               g_object_set (G_OBJECT(videobin[WFD_SINK_V_PARSE].gst), "wfd-mode", TRUE, NULL );
 
        /* create dec */
        MMWFDSINK_CREATE_ELEMENT (videobin, WFD_SINK_V_DEC, wfd_sink->ini.name_of_video_decoder, "video_dec", TRUE);
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, videobin[WFD_SINK_V_DEC].gst,  "sink" );
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, videobin[WFD_SINK_V_DEC].gst,  "src" );
-       if (MM_ERROR_NONE != __mm_wfd_sink_prepare_videodec(wfd_sink, videobin[WFD_SINK_V_DEC].gst))
+       if (videobin[WFD_SINK_V_DEC].gst)
        {
-               debug_error ("failed to set video sink property....\n");
-               goto CREATE_ERROR;
+               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_videodec(wfd_sink, videobin[WFD_SINK_V_DEC].gst))
+               {
+                       wfd_sink_error ("failed to set video sink property....\n");
+                       goto CREATE_ERROR;
+               }
        }
 
        /* create sink */
        MMWFDSINK_CREATE_ELEMENT (videobin, WFD_SINK_V_SINK, wfd_sink->ini.name_of_video_sink, "video_sink", TRUE);
        MMWFDSINK_PAD_PROBE( wfd_sink, NULL, videobin[WFD_SINK_V_SINK].gst,  "sink" );
-       if (MM_ERROR_NONE != __mm_wfd_sink_prepare_videosink(wfd_sink, videobin[WFD_SINK_V_SINK].gst))
+       if (videobin[WFD_SINK_V_SINK].gst)
        {
-               debug_error ("failed to set video sink property....\n");
-               goto CREATE_ERROR;
+               if (MM_ERROR_NONE != __mm_wfd_sink_prepare_videosink(wfd_sink, videobin[WFD_SINK_V_SINK].gst))
+               {
+                       wfd_sink_error ("failed to set video sink property....\n");
+                       goto CREATE_ERROR;
+               }
        }
 
        /* adding created elements to videobin */
-       debug_error("No-error: adding created elements to videobin\n");
-       if( !__mm_wfd_sink_gst_element_add_bucket_to_bin (GST_BIN_CAST(videobin[WFD_SINK_V_BIN].gst), element_bucket, FALSE))
+       if( !__mm_wfd_sink_gst_element_add_bucket_to_bin(GST_BIN_CAST(videobin[WFD_SINK_V_BIN].gst), element_bucket, FALSE))
        {
-               debug_error ("failed to add elements\n");
+               wfd_sink_error ("failed to add elements\n");
                goto CREATE_ERROR;
        }
 
        /* linking elements in the bucket by added order. */
-       debug_error("No-error: Linking elements in the bucket by added order.\n");
        if ( __mm_wfd_sink_gst_element_link_bucket (element_bucket) == -1 )
        {
-               debug_error("failed to link elements\n");
+               wfd_sink_error("failed to link elements\n");
                goto CREATE_ERROR;
        }
 
@@ -2338,27 +2878,27 @@ static int __mm_wfd_sink_create_videobin(mm_wfd_sink_t *wfd_sink)
        first_element =  (MMWFDSinkGstElement *)g_list_nth_data(element_bucket, 0);
        if (!first_element)
        {
-               debug_error("failed to get first element of videobin\n");
+               wfd_sink_error("failed to get first element of videobin\n");
                goto CREATE_ERROR;
        }
 
        pad = gst_element_get_static_pad(GST_ELEMENT(first_element->gst), "sink");
        if (!pad)
        {
-               debug_error("failed to get pad from first element(%s) of videobin\n", GST_ELEMENT_NAME(first_element->gst));
+               wfd_sink_error("failed to get pad from first element(%s) of videobin\n", GST_ELEMENT_NAME(first_element->gst));
                goto CREATE_ERROR;
        }
 
        ghostpad = gst_ghost_pad_new ("sink", pad);
        if (!ghostpad)
        {
-               debug_error("failed to create ghostpad\n");
+               wfd_sink_error("failed to create ghostpad\n");
                goto CREATE_ERROR;
        }
 
        if (FALSE == gst_element_add_pad (videobin[WFD_SINK_V_BIN].gst, ghostpad) )
        {
-               debug_error("failed to add ghostpad to videobin\n");
+               wfd_sink_error("failed to add ghostpad to videobin\n");
                goto CREATE_ERROR;
        }
 
@@ -2371,13 +2911,22 @@ static int __mm_wfd_sink_create_videobin(mm_wfd_sink_t *wfd_sink)
        /* take it */
        wfd_sink->pipeline->videobin = videobin;
 
-       debug_fleave();
+       if (wfd_sink->ini.video_sink_async)
+       {
+               GstBus *bus = NULL;
+               bus = gst_element_get_bus(videobin[WFD_SINK_V_BIN].gst );
+               if (bus)
+                       gst_bus_set_sync_handler(bus, _mm_wfd_bus_sync_callback, wfd_sink, NULL);
+               gst_object_unref(bus);
+       }
+
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 
 /* ERRORS */
 CREATE_ERROR:
-       debug_error("ERROR : releasing videobin\n");
+       wfd_sink_error("failed to create videobin, releasing all\n");
 
        if (pad)
                gst_object_unref (GST_OBJECT(pad));
@@ -2389,191 +2938,20 @@ CREATE_ERROR:
 
        g_list_free (element_bucket);
 
-       /* release element which are not added to bin */
-       for (i = 1; i < WFD_SINK_V_NUM; i++)    /* NOTE : skip bin */
-       {
-               if (videobin[i].gst)
-               {
-                       GstObject* parent = NULL;
-                       parent = gst_element_get_parent (videobin[i].gst);
-
-                       if (!parent)
-                       {
-                               gst_object_unref(GST_OBJECT(videobin[i].gst));
-                               videobin[i].gst = NULL;
-                       }
-                       else
-                       {
-                               gst_object_unref(GST_OBJECT(parent));
-                       }
-               }
-       }
-
-       /* release videobin with it's childs */
-       if (videobin[WFD_SINK_V_BIN].gst )
-       {
-               gst_object_unref (GST_OBJECT(videobin[WFD_SINK_V_BIN].gst));
-       }
+       __mm_wfd_sink_destroy_videobin(wfd_sink);
 
        MMWFDSINK_FREEIF (videobin);
 
        return MM_ERROR_WFD_INTERNAL;
 }
 
-static int __mm_wfd_sink_destroy_videobin(mm_wfd_sink_t* wfd_sink)
-{
-       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-       MMWFDSinkGstElement* videobin = NULL;
-       GstObject* parent = NULL;
-       int i;
-
-       debug_fenter ();
-
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED );
-
-       if (wfd_sink->pipeline && wfd_sink->pipeline->videobin && wfd_sink->pipeline->videobin[WFD_SINK_V_BIN].gst)
-       {
-               videobin = wfd_sink->pipeline->videobin;
-       }
-       else
-       {
-               debug_error("No-error : videobin is not created, nothing to destroy\n");
-               return MM_ERROR_NONE;
-       }
-
-
-       parent = gst_element_get_parent (videobin[WFD_SINK_V_BIN].gst);
-       if (!parent)
-       {
-               debug_error("No-error : videobin has no parent.. need to relaset by itself\n");
-
-               if (wfd_sink->video_bin_is_prepared)
-               {
-                       debug_error("No-error : try to change state of videobin to NULL\n");
-                       ret = gst_element_set_state (videobin[WFD_SINK_V_BIN].gst, GST_STATE_NULL);
-                       if ( ret != GST_STATE_CHANGE_SUCCESS )
-                       {
-                               debug_error("failed to change state of videobin to NULL\n");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-               }
-
-               /* release element which are not added to bin */
-               for (i = 1; i < WFD_SINK_V_NUM; i++)    /* NOTE : skip bin */
-               {
-                       if (videobin[i].gst)
-                       {
-                               parent = gst_element_get_parent (videobin[i].gst);
-                               if (!parent)
-                               {
-                                       gst_object_unref(GST_OBJECT(videobin[i].gst));
-                                       videobin[i].gst = NULL;
-                               }
-                               else
-                               {
-                                       gst_object_unref(GST_OBJECT(parent));
-                               }
-                       }
-               }
-               /* release audiobin with it's childs */
-               if (videobin[WFD_SINK_V_BIN].gst )
-               {
-                       gst_object_unref (GST_OBJECT(videobin[WFD_SINK_V_BIN].gst));
-               }
-       }
-       else
-       {
-               debug_error("No-error : videobin has parent\n");
-
-               gst_object_unref (GST_OBJECT(parent));
-       }
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
-static int  __mm_wfd_sink_destroy_audiobin(mm_wfd_sink_t* wfd_sink)
-{
-       GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-       MMWFDSinkGstElement* audiobin = NULL;
-       GstObject* parent = NULL;
-       int i;
-
-       debug_fenter ();
-
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
-
-       if (wfd_sink->pipeline && wfd_sink->pipeline->audiobin && wfd_sink->pipeline->audiobin[WFD_SINK_A_BIN].gst)
-       {
-               audiobin = wfd_sink->pipeline->audiobin;
-       }
-       else
-       {
-               debug_error("No-error : audiobin is not created, nothing to destroy\n");
-               return MM_ERROR_NONE;
-       }
-
-
-       parent = gst_element_get_parent (audiobin[WFD_SINK_A_BIN].gst);
-       if (!parent)
-       {
-               debug_error("No-error : audiobin has no parent.. need to relaset by itself\n");
-
-               if (wfd_sink->audio_bin_is_prepared)
-               {
-                       debug_error("No-error : try to change state of audiobin to NULL\n");
-                       ret = gst_element_set_state (audiobin[WFD_SINK_A_BIN].gst, GST_STATE_NULL);
-                       if ( ret != GST_STATE_CHANGE_SUCCESS )
-                       {
-                               debug_error("failed to change state of audiobin to NULL\n");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-               }
-
-               /* release element which are not added to bin */
-               for (i = 1; i < WFD_SINK_A_NUM; i++)    /* NOTE : skip bin */
-               {
-                       if (audiobin[i].gst)
-                       {
-                               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[WFD_SINK_A_BIN].gst )
-               {
-                       gst_object_unref (GST_OBJECT(audiobin[WFD_SINK_A_BIN].gst));
-               }
-       }
-       else
-       {
-               debug_error("No-error : audiobin has parent\n");
-
-               gst_object_unref (GST_OBJECT(parent));
-       }
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-}
-
 static int __mm_wfd_sink_destroy_pipeline(mm_wfd_sink_t* wfd_sink)
 {
        GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
 
-       debug_fenter ();
+       wfd_sink_debug_fenter ();
 
-       return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED );
+       wfd_sink_return_val_if_fail (wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED );
 
        if (wfd_sink->prev_audio_dec_src_pad)
                gst_object_unref(GST_OBJECT(wfd_sink->prev_audio_dec_src_pad));
@@ -2595,20 +2973,20 @@ static int __mm_wfd_sink_destroy_pipeline(mm_wfd_sink_t* wfd_sink)
 
                        if (MM_ERROR_NONE != __mm_wfd_sink_destroy_videobin(wfd_sink))
                        {
-                               debug_error("failed to destroy videobin\n");
+                               wfd_sink_error("failed to destroy videobin\n");
                                return MM_ERROR_WFD_INTERNAL;
                        }
 
                        if (MM_ERROR_NONE != __mm_wfd_sink_destroy_audiobin(wfd_sink))
                        {
-                               debug_error("failed to destroy audiobin\n");
+                               wfd_sink_error("failed to destroy audiobin\n");
                                return MM_ERROR_WFD_INTERNAL;
                        }
 
                        ret = gst_element_set_state (mainbin[WFD_SINK_M_PIPE].gst, GST_STATE_NULL);
                        if ( ret != GST_STATE_CHANGE_SUCCESS )
                        {
-                               debug_error("failed to change state of mainbin to NULL\n");
+                               wfd_sink_error("failed to change state of mainbin to NULL\n");
                                return MM_ERROR_WFD_INTERNAL;
                        }
 
@@ -2622,17 +3000,12 @@ static int __mm_wfd_sink_destroy_pipeline(mm_wfd_sink_t* wfd_sink)
                MMWFDSINK_FREEIF( wfd_sink->pipeline );
        }
 
-       wfd_sink->is_constructed = FALSE;
        wfd_sink->added_av_pad_num = 0;
-       wfd_sink->need_to_reset_basetime = FALSE;
-       wfd_sink->demux_video_pad_probe_id = 0;
-       wfd_sink->demux_audio_pad_probe_id = 0;
        wfd_sink->audio_bin_is_linked = FALSE;
        wfd_sink->video_bin_is_linked = FALSE;
-       wfd_sink->audio_bin_is_prepared = FALSE;
-       wfd_sink->video_bin_is_prepared = FALSE;
+       wfd_sink->need_to_reset_basetime = FALSE;
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return MM_ERROR_NONE;
 }
@@ -2650,9 +3023,9 @@ __mm_wfd_sink_dump_pipeline_state(mm_wfd_sink_t *wfd_sink)
        GstState pending = GST_STATE_VOID_PENDING;
        GstClockTime time = 200*GST_MSECOND;
 
-       debug_fenter();
+       wfd_sink_debug_fenter();
 
-       return_if_fail ( wfd_sink &&
+       wfd_sink_return_if_fail ( wfd_sink &&
                wfd_sink->pipeline &&
                wfd_sink->pipeline->mainbin &&
                wfd_sink->pipeline->mainbin[WFD_SINK_M_PIPE].gst);
@@ -2671,8 +3044,12 @@ __mm_wfd_sink_dump_pipeline_state(mm_wfd_sink_t *wfd_sink)
                                        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));
+                                                wfd_sink_error("%s:%s : From:%s To:%s refcount : %d\n",
+                                                       GST_STR_NULL(GST_OBJECT_NAME(factory)),
+                                                       GST_STR_NULL(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;
@@ -2694,10 +3071,9 @@ __mm_wfd_sink_dump_pipeline_state(mm_wfd_sink_t *wfd_sink)
        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:%srefcount : %d\n",
+               wfd_sink_error("%s:%s : From:%s To:%s refcount : %d\n",
                        GST_OBJECT_NAME(factory),
                        GST_ELEMENT_NAME(item),
                        gst_element_state_get_name(state),
@@ -2708,28 +3084,30 @@ __mm_wfd_sink_dump_pipeline_state(mm_wfd_sink_t *wfd_sink)
        if ( iter )
                gst_iterator_free (iter);
 
-       debug_fleave();
+       wfd_sink_debug_fleave();
 
        return;
 }
 
 const gchar *
-__mm_wfds_sink_get_state_name ( MMWfdSinkStateType state )
+__mm_wfds_sink_get_state_name ( MMWFDSinkStateType state )
 {
        switch ( state )
        {
+               case MM_WFD_SINK_STATE_NONE:
+                       return "NONE";
                case MM_WFD_SINK_STATE_NULL:
                        return "NULL";
-               case MM_WFD_SINK_STATE_READY:
-                       return "READY";
-               case MM_WFD_SINK_STATE_PAUSED:
-                       return "PAUSED";
+               case MM_WFD_SINK_STATE_PREPARED:
+                       return "PREPARED";
+               case MM_WFD_SINK_STATE_CONNECTED:
+                       return "CONNECTED";
                case MM_WFD_SINK_STATE_PLAYING:
                        return "PLAYING";
-               case MM_WFD_SINK_STATE_NONE:
-                       return "NONE";
-               case MM_WFD_SINK_STATE_TEARDOWN:
-                       return "TEARDOWN";
+               case MM_WFD_SINK_STATE_PAUSED:
+                       return "PAUSED";
+               case MM_WFD_SINK_STATE_DISCONNECTED:
+                       return "DISCONNECTED";
                default:
                        return "INVAID";
        }
index 81384da..fedb81e 100755 (executable)
@@ -25,7 +25,8 @@
 
 #define DUMP_TS_DATA_PATH "/var/tmp/"
 
-static GstPadProbeReturn _mm_wfd_sink_util_dump (GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
+static GstPadProbeReturn
+_mm_wfd_sink_util_dump (GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
 {
        gint8 *data = NULL;
        gint size = 0;
@@ -36,92 +37,80 @@ static GstPadProbeReturn _mm_wfd_sink_util_dump (GstPad * pad, GstPadProbeInfo *
        snprintf(path , sizeof(path), "%s%s_%s.ts", DUMP_TS_DATA_PATH,
                gst_element_get_name(gst_pad_get_parent_element(pad)), gst_pad_get_name(pad));
 
-       if (info->type & GST_PAD_PROBE_TYPE_BUFFER) {
-               GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
+       if (info && info->type & GST_PAD_PROBE_TYPE_BUFFER) {
                GstMapInfo buf_info;
+               GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
 
                gst_buffer_map(buffer, &buf_info, GST_MAP_READ);
 
-               debug_log ("got buffer %p with size %d", buffer, buf_info.size);
+               wfd_sink_debug ("got buffer %p with size %d", buffer, buf_info.size);
                data = (gint8 *)(buf_info.data);
                size = buf_info.size;
                f = fopen(path, "a");
                if(f == NULL)
                {
                        strerror_r(errno, buf, sizeof(buf));
-                       debug_error("failed to fopen! : %s", buf);
-                       return TRUE;
+                       wfd_sink_error("failed to fopen! : %s", buf);
+                       return GST_PAD_PROBE_OK;
                }
                fwrite(data, size, 1, f);
                fclose(f);
                gst_buffer_unmap(buffer, &buf_info);
        }
 
-       return TRUE;
+       return GST_PAD_PROBE_OK;
 }
 
 static GstPadProbeReturn
 _mm_wfd_sink_util_pad_probe_cb(GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
 {
        GstElement* parent = NULL;
-       const GstSegment* segment = NULL;
 
-       parent = (GstElement*)gst_object_get_parent(GST_OBJECT(pad));
+       wfd_sink_return_val_if_fail(info &&
+               info->type != GST_PAD_PROBE_TYPE_INVALID,
+               GST_PAD_PROBE_DROP);
+       wfd_sink_return_val_if_fail(pad, GST_PAD_PROBE_DROP);
 
-#if 0
-       if (GST_IS_EVENT (object))
+       parent = (GstElement*)gst_object_get_parent(GST_OBJECT(pad));
+       if(!parent)
        {
-               GstEvent *event = GST_EVENT_CAST(object);
-
-               /* show name and event type */
-               debug_log("EVENT PROBE : %s:%s :  %s\n",
-                       GST_STR_NULL(GST_ELEMENT_NAME(parent)), GST_STR_NULL(GST_PAD_NAME(pad)),
-                       GST_EVENT_TYPE_NAME(event));
-
-               if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT)
-               {
-                       const GstSegment *seg;
-                       gst_event_parse_segment (event, &seg);
-
-                       debug_log ("NEWSEGMENT : %" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %" G_GINT64_FORMAT " \n",
-                               seg->start, seg->stop, seg->time);
-               }
+               wfd_sink_error("failed to get parent of pad");
+               return GST_PAD_PROBE_DROP;
        }
-       else if  (GST_IS_BUFFER(object))
-       {
-               GstBuffer *buffer = GST_BUFFER_CAST(object);
 
-               /* show name and timestamp */
-               debug_log("BUFFER PROBE : %s:%s :  %u:%02u:%02u.%09u (%d bytes)\n",
-                       GST_STR_NULL(GST_ELEMENT_NAME(parent)), GST_STR_NULL(GST_PAD_NAME(pad)),
-                       GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)), gst_buffer_get_size(buffer));
-       }
-#else
-       if (info->type & GST_PAD_PROBE_TYPE_BUFFER) {
+       if (info->type == GST_PAD_PROBE_TYPE_BUFFER)
+       {
                GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
-
                /* show name and timestamp */
-               GST_ERROR_OBJECT(parent, "BUFFER PROBE : %s:%s :  %u:%02u:%02u.%09u  (%"G_GSSIZE_FORMAT" bytes)\n",
-               GST_STR_NULL(GST_ELEMENT_NAME(parent)), GST_STR_NULL(GST_PAD_NAME(pad)),
-               GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)), gst_buffer_get_size(buffer));
-       } else if (info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM ||
-               info->type & GST_PAD_PROBE_TYPE_EVENT_UPSTREAM ||
-               info->type & GST_PAD_PROBE_TYPE_EVENT_FLUSH ||
-               info->type & GST_PAD_PROBE_TYPE_EVENT_BOTH) {
+               wfd_sink_debug("BUFFER PROBE : %s:%s :  %u:%02u:%02u.%09u  (%"G_GSSIZE_FORMAT" bytes)\n",
+                       GST_STR_NULL(GST_ELEMENT_NAME(parent)),
+                       GST_STR_NULL(GST_PAD_NAME(pad)),
+                       GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)),
+                       gst_buffer_get_size(buffer));
+       }
+       else if (info->type == GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM ||
+               info->type == GST_PAD_PROBE_TYPE_EVENT_UPSTREAM ||
+               info->type == GST_PAD_PROBE_TYPE_EVENT_FLUSH ||
+               info->type == GST_PAD_PROBE_TYPE_EVENT_BOTH)
+       {
                GstEvent *event = gst_pad_probe_info_get_event (info);
+
                /* show name and event type */
-               GST_ERROR_OBJECT(parent, "EVENT PROBE : %s:%s :  %s\n",
-               GST_STR_NULL(GST_ELEMENT_NAME(parent)), GST_STR_NULL(GST_PAD_NAME(pad)),
-               GST_EVENT_TYPE_NAME(event));
+               wfd_sink_debug("EVENT PROBE : %s:%s :  %s\n",
+                       GST_STR_NULL(GST_ELEMENT_NAME(parent)),
+                       GST_STR_NULL(GST_PAD_NAME(pad)),
+                       GST_EVENT_TYPE_NAME(event));
 
-               if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
+               if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT)
+               {
+                       const GstSegment* segment = NULL;
                        gst_event_parse_segment (event, &segment);
-
-                       GST_ERROR_OBJECT (parent, "NEWSEGMENT : %" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %" G_GINT64_FORMAT " \n",
-                       segment->start, segment->stop, segment->time);
+                       if (segment)
+                               wfd_sink_debug ("NEWSEGMENT : %" G_GINT64_FORMAT
+                                       " -- %"  G_GINT64_FORMAT ", time %" G_GINT64_FORMAT " \n",
+                                       segment->start, segment->stop, segment->time);
                }
        }
-#endif
 
        if ( parent )
                gst_object_unref(parent);
@@ -147,8 +136,9 @@ mm_wfd_sink_util_add_pad_probe(GstPad *pad, GstElement *element, const gchar *pa
 
        if (probe_pad)
        {
-               debug_log ("add pad(%s) probe", GST_STR_NULL(GST_PAD_NAME(probe_pad)));
-               gst_pad_add_probe(probe_pad, GST_PAD_PROBE_TYPE_DATA_BOTH, _mm_wfd_sink_util_pad_probe_cb, (gpointer)NULL, NULL);
+               wfd_sink_debug ("add pad(%s) probe", GST_STR_NULL(GST_PAD_NAME(probe_pad)));
+               gst_pad_add_probe(probe_pad, GST_PAD_PROBE_TYPE_DATA_BOTH,
+                       _mm_wfd_sink_util_pad_probe_cb, (gpointer)NULL, NULL);
                gst_object_unref(probe_pad);
        }
 }
@@ -158,15 +148,88 @@ mm_wfd_sink_util_add_pad_probe_for_data_dump(GstElement *element, const gchar *p
 {
        GstPad * probe_pad = NULL;
 
-
        if(element && pad_name)
                probe_pad = gst_element_get_static_pad(element, pad_name);
 
        if (probe_pad)
        {
-               debug_log ("add pad(%s) probe", GST_STR_NULL(GST_PAD_NAME(probe_pad)));
+               wfd_sink_debug ("add pad(%s) probe", GST_STR_NULL(GST_PAD_NAME(probe_pad)));
                gst_pad_add_probe(probe_pad, GST_PAD_PROBE_TYPE_BUFFER, _mm_wfd_sink_util_dump, (gpointer)NULL, NULL);
                gst_object_unref(probe_pad);
        }
 }
 
+static GstPadProbeReturn
+_mm_wfd_sink_util_check_first_buffer_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
+{
+       GstElement* parent = NULL;
+       GstBuffer *buffer = NULL;
+       guint *probe_id = (guint*)user_data;
+
+       wfd_sink_return_val_if_fail(pad, GST_PAD_PROBE_DROP);
+       wfd_sink_return_val_if_fail(info, GST_PAD_PROBE_DROP);
+
+       parent = GST_ELEMENT_CAST(gst_object_get_parent(GST_OBJECT(pad)));
+       if( parent == NULL)
+       {
+               wfd_sink_error("The parent of pad is NULL.");
+               return GST_PAD_PROBE_DROP;
+       }
+
+       buffer = gst_pad_probe_info_get_buffer (info);
+
+       wfd_sink_debug("FIRST BUFFER PROBE : %s:%s :  %u:%02u:%02u.%09u (%"G_GSSIZE_FORMAT" bytes)\n",
+               GST_STR_NULL(GST_ELEMENT_NAME(parent)), GST_STR_NULL(GST_PAD_NAME(pad)),
+               GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)), gst_buffer_get_size(buffer));
+
+       if (probe_id && *probe_id >0)
+       {
+               wfd_sink_debug("remove buffer probe[%d]\n", *probe_id);
+               gst_pad_remove_probe(pad, *probe_id);
+
+               MMWFDSINK_FREEIF(probe_id);
+       }
+
+       if ( parent )
+               gst_object_unref(parent);
+
+       return GST_PAD_PROBE_REMOVE;
+}
+
+void
+mm_wfd_sink_util_add_pad_probe_for_checking_first_buffer(GstPad *pad, GstElement *element, const gchar *pad_name)
+{
+       GstPad * probe_pad = NULL;
+       guint *probe_id = NULL;
+
+       if (!pad)
+       {
+               if(element && pad_name)
+                       probe_pad = gst_element_get_static_pad(element, pad_name);
+       }
+       else
+       {
+               probe_pad = pad;
+               gst_object_ref(probe_pad);
+       }
+
+       if (probe_pad)
+       {
+               probe_id  = g_malloc0(sizeof(guint));
+               if (!probe_id)
+               {
+                       wfd_sink_error("failed to allocate memory for probe id\n");
+                       gst_object_unref(probe_pad);
+                       return;
+               }
+
+               *probe_id = gst_pad_add_probe(probe_pad, GST_PAD_PROBE_TYPE_BUFFER, _mm_wfd_sink_util_check_first_buffer_cb, (gpointer)probe_id, NULL);
+               wfd_sink_debug ("add pad(%s) probe, %d",
+                       GST_STR_NULL(GST_PAD_NAME(probe_pad)), *probe_id);
+
+               gst_object_unref(probe_pad);
+       }
+
+       return;
+}
+